diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/CIndex/CIndex.cpp | 2589 | ||||
-rw-r--r-- | tools/CIndex/CIndex.darwin.exports | 81 | ||||
-rw-r--r-- | tools/CIndex/CIndex.exports | 81 | ||||
-rw-r--r-- | tools/CIndex/CIndexCodeCompletion.cpp | 512 | ||||
-rw-r--r-- | tools/CIndex/CIndexDiagnostic.cpp | 285 | ||||
-rw-r--r-- | tools/CIndex/CIndexDiagnostic.h | 53 | ||||
-rw-r--r-- | tools/CIndex/CIndexInclusionStack.cpp | 67 | ||||
-rw-r--r-- | tools/CIndex/CIndexUSRs.cpp | 469 | ||||
-rw-r--r-- | tools/CIndex/CIndexer.cpp | 154 | ||||
-rw-r--r-- | tools/CIndex/CIndexer.h | 78 | ||||
-rw-r--r-- | tools/CIndex/CMakeLists.txt | 56 | ||||
-rw-r--r-- | tools/CIndex/CXCursor.cpp | 369 | ||||
-rw-r--r-- | tools/CIndex/CXCursor.h | 112 | ||||
-rw-r--r-- | tools/CIndex/CXSourceLocation.h | 75 | ||||
-rw-r--r-- | tools/CIndex/Makefile | 55 | ||||
-rw-r--r-- | tools/index-test/CMakeLists.txt | 23 | ||||
-rw-r--r-- | tools/index-test/Makefile | 25 | ||||
-rw-r--r-- | tools/index-test/index-test.cpp | 334 |
18 files changed, 0 insertions, 5418 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp deleted file mode 100644 index 9cdb965..0000000 --- a/tools/CIndex/CIndex.cpp +++ /dev/null @@ -1,2589 +0,0 @@ -//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the main API hooks in the Clang-C Source Indexing -// library. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXCursor.h" -#include "CXSourceLocation.h" -#include "CIndexDiagnostic.h" - -#include "clang/Basic/Version.h" - -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/AST/TypeLocVisitor.h" -#include "clang/Basic/Diagnostic.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Lex/Lexer.h" -#include "clang/Lex/PreprocessingRecord.h" -#include "clang/Lex/Preprocessor.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/Program.h" -#include "llvm/System/Signals.h" - -// Needed to define L_TMPNAM on some systems. -#include <cstdio> - -using namespace clang; -using namespace clang::cxcursor; -using namespace clang::cxstring; - -//===----------------------------------------------------------------------===// -// Crash Reporting. -//===----------------------------------------------------------------------===// - -#ifdef __APPLE__ -#define USE_CRASHTRACER -#include "clang/Analysis/Support/SaveAndRestore.h" -// Integrate with crash reporter. -extern "C" const char *__crashreporter_info__; -#define NUM_CRASH_STRINGS 32 -static unsigned crashtracer_counter = 0; -static unsigned crashtracer_counter_id[NUM_CRASH_STRINGS] = { 0 }; -static const char *crashtracer_strings[NUM_CRASH_STRINGS] = { 0 }; -static const char *agg_crashtracer_strings[NUM_CRASH_STRINGS] = { 0 }; - -static unsigned SetCrashTracerInfo(const char *str, - llvm::SmallString<1024> &AggStr) { - - unsigned slot = 0; - while (crashtracer_strings[slot]) { - if (++slot == NUM_CRASH_STRINGS) - slot = 0; - } - crashtracer_strings[slot] = str; - crashtracer_counter_id[slot] = ++crashtracer_counter; - - // We need to create an aggregate string because multiple threads - // may be in this method at one time. The crash reporter string - // will attempt to overapproximate the set of in-flight invocations - // of this function. Race conditions can still cause this goal - // to not be achieved. - { - llvm::raw_svector_ostream Out(AggStr); - for (unsigned i = 0; i < NUM_CRASH_STRINGS; ++i) - if (crashtracer_strings[i]) Out << crashtracer_strings[i] << '\n'; - } - __crashreporter_info__ = agg_crashtracer_strings[slot] = AggStr.c_str(); - return slot; -} - -static void ResetCrashTracerInfo(unsigned slot) { - unsigned max_slot = 0; - unsigned max_value = 0; - - crashtracer_strings[slot] = agg_crashtracer_strings[slot] = 0; - - for (unsigned i = 0 ; i < NUM_CRASH_STRINGS; ++i) - if (agg_crashtracer_strings[i] && - crashtracer_counter_id[i] > max_value) { - max_slot = i; - max_value = crashtracer_counter_id[i]; - } - - __crashreporter_info__ = agg_crashtracer_strings[max_slot]; -} - -namespace { -class ArgsCrashTracerInfo { - llvm::SmallString<1024> CrashString; - llvm::SmallString<1024> AggregateString; - unsigned crashtracerSlot; -public: - ArgsCrashTracerInfo(llvm::SmallVectorImpl<const char*> &Args) - : crashtracerSlot(0) - { - { - llvm::raw_svector_ostream Out(CrashString); - Out << "ClangCIndex [" << getClangFullVersion() << "]" - << "[createTranslationUnitFromSourceFile]: clang"; - for (llvm::SmallVectorImpl<const char*>::iterator I=Args.begin(), - E=Args.end(); I!=E; ++I) - Out << ' ' << *I; - } - crashtracerSlot = SetCrashTracerInfo(CrashString.c_str(), - AggregateString); - } - - ~ArgsCrashTracerInfo() { - ResetCrashTracerInfo(crashtracerSlot); - } -}; -} -#endif - -/// \brief The result of comparing two source ranges. -enum RangeComparisonResult { - /// \brief Either the ranges overlap or one of the ranges is invalid. - RangeOverlap, - - /// \brief The first range ends before the second range starts. - RangeBefore, - - /// \brief The first range starts after the second range ends. - RangeAfter -}; - -/// \brief Compare two source ranges to determine their relative position in -/// the translation unit. -static RangeComparisonResult RangeCompare(SourceManager &SM, - SourceRange R1, - SourceRange R2) { - assert(R1.isValid() && "First range is invalid?"); - assert(R2.isValid() && "Second range is invalid?"); - if (R1.getEnd() == R2.getBegin() || - SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin())) - return RangeBefore; - if (R2.getEnd() == R1.getBegin() || - SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin())) - return RangeAfter; - return RangeOverlap; -} - -/// \brief Translate a Clang source range into a CIndex source range. -/// -/// Clang internally represents ranges where the end location points to the -/// start of the token at the end. However, for external clients it is more -/// useful to have a CXSourceRange be a proper half-open interval. This routine -/// does the appropriate translation. -CXSourceRange cxloc::translateSourceRange(const SourceManager &SM, - const LangOptions &LangOpts, - SourceRange R) { - // We want the last character in this location, so we will adjust the - // location accordingly. - // FIXME: How do do this with a macro instantiation location? - SourceLocation EndLoc = R.getEnd(); - if (!EndLoc.isInvalid() && EndLoc.isFileID()) { - unsigned Length = Lexer::MeasureTokenLength(EndLoc, SM, LangOpts); - EndLoc = EndLoc.getFileLocWithOffset(Length); - } - - CXSourceRange Result = { { (void *)&SM, (void *)&LangOpts }, - R.getBegin().getRawEncoding(), - EndLoc.getRawEncoding() }; - return Result; -} - -//===----------------------------------------------------------------------===// -// Cursor visitor. -//===----------------------------------------------------------------------===// - -namespace { - -// Cursor visitor. -class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, - public TypeLocVisitor<CursorVisitor, bool>, - public StmtVisitor<CursorVisitor, bool> -{ - /// \brief The translation unit we are traversing. - ASTUnit *TU; - - /// \brief The parent cursor whose children we are traversing. - CXCursor Parent; - - /// \brief The declaration that serves at the parent of any statement or - /// expression nodes. - Decl *StmtParent; - - /// \brief The visitor function. - CXCursorVisitor Visitor; - - /// \brief The opaque client data, to be passed along to the visitor. - CXClientData ClientData; - - // MaxPCHLevel - the maximum PCH level of declarations that we will pass on - // to the visitor. Declarations with a PCH level greater than this value will - // be suppressed. - unsigned MaxPCHLevel; - - /// \brief When valid, a source range to which the cursor should restrict - /// its search. - SourceRange RegionOfInterest; - - using DeclVisitor<CursorVisitor, bool>::Visit; - using TypeLocVisitor<CursorVisitor, bool>::Visit; - using StmtVisitor<CursorVisitor, bool>::Visit; - - /// \brief Determine whether this particular source range comes before, comes - /// after, or overlaps the region of interest. - /// - /// \param R a half-open source range retrieved from the abstract syntax tree. - RangeComparisonResult CompareRegionOfInterest(SourceRange R); - -public: - CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, - unsigned MaxPCHLevel, - SourceRange RegionOfInterest = SourceRange()) - : TU(TU), Visitor(Visitor), ClientData(ClientData), - MaxPCHLevel(MaxPCHLevel), RegionOfInterest(RegionOfInterest) - { - Parent.kind = CXCursor_NoDeclFound; - Parent.data[0] = 0; - Parent.data[1] = 0; - Parent.data[2] = 0; - StmtParent = 0; - } - - bool Visit(CXCursor Cursor, bool CheckedRegionOfInterest = false); - - std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> - getPreprocessedEntities(); - - bool VisitChildren(CXCursor Parent); - - // Declaration visitors - bool VisitAttributes(Decl *D); - bool VisitBlockDecl(BlockDecl *B); - bool VisitDeclContext(DeclContext *DC); - bool VisitTranslationUnitDecl(TranslationUnitDecl *D); - bool VisitTypedefDecl(TypedefDecl *D); - bool VisitTagDecl(TagDecl *D); - bool VisitEnumConstantDecl(EnumConstantDecl *D); - bool VisitDeclaratorDecl(DeclaratorDecl *DD); - bool VisitFunctionDecl(FunctionDecl *ND); - bool VisitFieldDecl(FieldDecl *D); - bool VisitVarDecl(VarDecl *); - bool VisitObjCMethodDecl(ObjCMethodDecl *ND); - bool VisitObjCContainerDecl(ObjCContainerDecl *D); - bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); - bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); - bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); - bool VisitObjCImplDecl(ObjCImplDecl *D); - bool VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); - bool VisitObjCImplementationDecl(ObjCImplementationDecl *D); - // FIXME: ObjCPropertyDecl requires TypeSourceInfo, getter/setter locations, - // etc. - // FIXME: ObjCCompatibleAliasDecl requires aliased-class locations. - bool VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D); - bool VisitObjCClassDecl(ObjCClassDecl *D); - - // Type visitors - // FIXME: QualifiedTypeLoc doesn't provide any location information - bool VisitBuiltinTypeLoc(BuiltinTypeLoc TL); - bool VisitTypedefTypeLoc(TypedefTypeLoc TL); - bool VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL); - bool VisitTagTypeLoc(TagTypeLoc TL); - // FIXME: TemplateTypeParmTypeLoc doesn't provide any location information - bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); - bool VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL); - bool VisitPointerTypeLoc(PointerTypeLoc TL); - bool VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL); - bool VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL); - bool VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL); - bool VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL); - bool VisitFunctionTypeLoc(FunctionTypeLoc TL); - bool VisitArrayTypeLoc(ArrayTypeLoc TL); - // FIXME: Implement for TemplateSpecializationTypeLoc - // FIXME: Implement visitors here when the unimplemented TypeLocs get - // implemented - bool VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL); - bool VisitTypeOfTypeLoc(TypeOfTypeLoc TL); - - // Statement visitors - bool VisitStmt(Stmt *S); - bool VisitDeclStmt(DeclStmt *S); - // FIXME: LabelStmt label? - bool VisitIfStmt(IfStmt *S); - bool VisitSwitchStmt(SwitchStmt *S); - bool VisitWhileStmt(WhileStmt *S); - bool VisitForStmt(ForStmt *S); - - // Expression visitors - bool VisitBlockExpr(BlockExpr *B); - bool VisitCompoundLiteralExpr(CompoundLiteralExpr *E); - bool VisitExplicitCastExpr(ExplicitCastExpr *E); - bool VisitObjCMessageExpr(ObjCMessageExpr *E); - bool VisitObjCEncodeExpr(ObjCEncodeExpr *E); - bool VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); -}; - -} // end anonymous namespace - -RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) { - return RangeCompare(TU->getSourceManager(), R, RegionOfInterest); -} - -/// \brief Visit the given cursor and, if requested by the visitor, -/// its children. -/// -/// \param Cursor the cursor to visit. -/// -/// \param CheckRegionOfInterest if true, then the caller already checked that -/// this cursor is within the region of interest. -/// -/// \returns true if the visitation should be aborted, false if it -/// should continue. -bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) { - if (clang_isInvalid(Cursor.kind)) - return false; - - if (clang_isDeclaration(Cursor.kind)) { - Decl *D = getCursorDecl(Cursor); - assert(D && "Invalid declaration cursor"); - if (D->getPCHLevel() > MaxPCHLevel) - return false; - - if (D->isImplicit()) - return false; - } - - // If we have a range of interest, and this cursor doesn't intersect with it, - // we're done. - if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) { - SourceRange Range = - cxloc::translateCXSourceRange(clang_getCursorExtent(Cursor)); - if (Range.isInvalid() || CompareRegionOfInterest(Range)) - return false; - } - - switch (Visitor(Cursor, Parent, ClientData)) { - case CXChildVisit_Break: - return true; - - case CXChildVisit_Continue: - return false; - - case CXChildVisit_Recurse: - return VisitChildren(Cursor); - } - - return false; -} - -std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> -CursorVisitor::getPreprocessedEntities() { - PreprocessingRecord &PPRec - = *TU->getPreprocessor().getPreprocessingRecord(); - - bool OnlyLocalDecls - = !TU->isMainFileAST() && TU->getOnlyLocalDecls(); - - // There is no region of interest; we have to walk everything. - if (RegionOfInterest.isInvalid()) - return std::make_pair(PPRec.begin(OnlyLocalDecls), - PPRec.end(OnlyLocalDecls)); - - // Find the file in which the region of interest lands. - SourceManager &SM = TU->getSourceManager(); - std::pair<FileID, unsigned> Begin - = SM.getDecomposedInstantiationLoc(RegionOfInterest.getBegin()); - std::pair<FileID, unsigned> End - = SM.getDecomposedInstantiationLoc(RegionOfInterest.getEnd()); - - // The region of interest spans files; we have to walk everything. - if (Begin.first != End.first) - return std::make_pair(PPRec.begin(OnlyLocalDecls), - PPRec.end(OnlyLocalDecls)); - - ASTUnit::PreprocessedEntitiesByFileMap &ByFileMap - = TU->getPreprocessedEntitiesByFile(); - if (ByFileMap.empty()) { - // Build the mapping from files to sets of preprocessed entities. - for (PreprocessingRecord::iterator E = PPRec.begin(OnlyLocalDecls), - EEnd = PPRec.end(OnlyLocalDecls); - E != EEnd; ++E) { - std::pair<FileID, unsigned> P - = SM.getDecomposedInstantiationLoc((*E)->getSourceRange().getBegin()); - ByFileMap[P.first].push_back(*E); - } - } - - return std::make_pair(ByFileMap[Begin.first].begin(), - ByFileMap[Begin.first].end()); -} - -/// \brief Visit the children of the given cursor. -/// -/// \returns true if the visitation should be aborted, false if it -/// should continue. -bool CursorVisitor::VisitChildren(CXCursor Cursor) { - if (clang_isReference(Cursor.kind)) { - // By definition, references have no children. - return false; - } - - // Set the Parent field to Cursor, then back to its old value once we're - // done. - class SetParentRAII { - CXCursor &Parent; - Decl *&StmtParent; - CXCursor OldParent; - - public: - SetParentRAII(CXCursor &Parent, Decl *&StmtParent, CXCursor NewParent) - : Parent(Parent), StmtParent(StmtParent), OldParent(Parent) - { - Parent = NewParent; - if (clang_isDeclaration(Parent.kind)) - StmtParent = getCursorDecl(Parent); - } - - ~SetParentRAII() { - Parent = OldParent; - if (clang_isDeclaration(Parent.kind)) - StmtParent = getCursorDecl(Parent); - } - } SetParent(Parent, StmtParent, Cursor); - - if (clang_isDeclaration(Cursor.kind)) { - Decl *D = getCursorDecl(Cursor); - assert(D && "Invalid declaration cursor"); - return VisitAttributes(D) || Visit(D); - } - - if (clang_isStatement(Cursor.kind)) - return Visit(getCursorStmt(Cursor)); - if (clang_isExpression(Cursor.kind)) - return Visit(getCursorExpr(Cursor)); - - if (clang_isTranslationUnit(Cursor.kind)) { - ASTUnit *CXXUnit = getCursorASTUnit(Cursor); - if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() && - RegionOfInterest.isInvalid()) { - const std::vector<Decl*> &TLDs = CXXUnit->getTopLevelDecls(); - for (std::vector<Decl*>::const_iterator it = TLDs.begin(), - ie = TLDs.end(); it != ie; ++it) { - if (Visit(MakeCXCursor(*it, CXXUnit), true)) - return true; - } - } else if (VisitDeclContext( - CXXUnit->getASTContext().getTranslationUnitDecl())) - return true; - - // Walk the preprocessing record. - if (CXXUnit->getPreprocessor().getPreprocessingRecord()) { - // FIXME: Once we have the ability to deserialize a preprocessing record, - // do so. - PreprocessingRecord::iterator E, EEnd; - for (llvm::tie(E, EEnd) = getPreprocessedEntities(); E != EEnd; ++E) { - if (MacroInstantiation *MI = dyn_cast<MacroInstantiation>(*E)) { - if (Visit(MakeMacroInstantiationCursor(MI, CXXUnit))) - return true; - - continue; - } - - if (MacroDefinition *MD = dyn_cast<MacroDefinition>(*E)) { - if (Visit(MakeMacroDefinitionCursor(MD, CXXUnit))) - return true; - - continue; - } - } - } - return false; - } - - // Nothing to visit at the moment. - return false; -} - -bool CursorVisitor::VisitBlockDecl(BlockDecl *B) { - for (BlockDecl::param_iterator I=B->param_begin(), E=B->param_end(); I!=E;++I) - if (Decl *D = *I) - if (Visit(D)) - return true; - - return Visit(MakeCXCursor(B->getBody(), StmtParent, TU)); -} - -bool CursorVisitor::VisitDeclContext(DeclContext *DC) { - for (DeclContext::decl_iterator - I = DC->decls_begin(), E = DC->decls_end(); I != E; ++I) { - - CXCursor Cursor = MakeCXCursor(*I, TU); - - if (RegionOfInterest.isValid()) { - SourceRange Range = - cxloc::translateCXSourceRange(clang_getCursorExtent(Cursor)); - if (Range.isInvalid()) - continue; - - switch (CompareRegionOfInterest(Range)) { - case RangeBefore: - // This declaration comes before the region of interest; skip it. - continue; - - case RangeAfter: - // This declaration comes after the region of interest; we're done. - return false; - - case RangeOverlap: - // This declaration overlaps the region of interest; visit it. - break; - } - } - - if (Visit(Cursor, true)) - return true; - } - - return false; -} - -bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) { - llvm_unreachable("Translation units are visited directly by Visit()"); - return false; -} - -bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) { - if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; -} - -bool CursorVisitor::VisitTagDecl(TagDecl *D) { - return VisitDeclContext(D); -} - -bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) { - if (Expr *Init = D->getInitExpr()) - return Visit(MakeCXCursor(Init, StmtParent, TU)); - return false; -} - -bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { - if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return false; -} - -bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { - if (VisitDeclaratorDecl(ND)) - return true; - - if (ND->isThisDeclarationADefinition() && - Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitFieldDecl(FieldDecl *D) { - if (VisitDeclaratorDecl(D)) - return true; - - if (Expr *BitWidth = D->getBitWidth()) - return Visit(MakeCXCursor(BitWidth, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitVarDecl(VarDecl *D) { - if (VisitDeclaratorDecl(D)) - return true; - - if (Expr *Init = D->getInit()) - return Visit(MakeCXCursor(Init, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) { - if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - for (ObjCMethodDecl::param_iterator P = ND->param_begin(), - PEnd = ND->param_end(); - P != PEnd; ++P) { - if (Visit(MakeCXCursor(*P, TU))) - return true; - } - - if (ND->isThisDeclarationADefinition() && - Visit(MakeCXCursor(ND->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) { - return VisitDeclContext(D); -} - -bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) { - if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(), - TU))) - return true; - - ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin(); - for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(), - E = ND->protocol_end(); I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return VisitObjCContainerDecl(ND); -} - -bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { - ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin(); - for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(), - E = PID->protocol_end(); I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return VisitObjCContainerDecl(PID); -} - -bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { - // Issue callbacks for super class. - if (D->getSuperClass() && - Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), - D->getSuperClassLoc(), - TU))) - return true; - - ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); - for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return VisitObjCContainerDecl(D); -} - -bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) { - return VisitObjCContainerDecl(D); -} - -bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { - // 'ID' could be null when dealing with invalid code. - if (ObjCInterfaceDecl *ID = D->getClassInterface()) - if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU))) - return true; - - return VisitObjCImplDecl(D); -} - -bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { -#if 0 - // Issue callbacks for super class. - // FIXME: No source location information! - if (D->getSuperClass() && - Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(), - D->getSuperClassLoc(), - TU))) - return true; -#endif - - return VisitObjCImplDecl(D); -} - -bool CursorVisitor::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - ObjCForwardProtocolDecl::protocol_loc_iterator PL = D->protocol_loc_begin(); - for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); - I != E; ++I, ++PL) - if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitObjCClassDecl(ObjCClassDecl *D) { - for (ObjCClassDecl::iterator C = D->begin(), CEnd = D->end(); C != CEnd; ++C) - if (Visit(MakeCursorObjCClassRef(C->getInterface(), C->getLocation(), TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { - ASTContext &Context = TU->getASTContext(); - - // Some builtin types (such as Objective-C's "id", "sel", and - // "Class") have associated declarations. Create cursors for those. - QualType VisitType; - switch (TL.getType()->getAs<BuiltinType>()->getKind()) { - case BuiltinType::Void: - case BuiltinType::Bool: - case BuiltinType::Char_U: - case BuiltinType::UChar: - case BuiltinType::Char16: - case BuiltinType::Char32: - case BuiltinType::UShort: - case BuiltinType::UInt: - case BuiltinType::ULong: - case BuiltinType::ULongLong: - case BuiltinType::UInt128: - case BuiltinType::Char_S: - case BuiltinType::SChar: - case BuiltinType::WChar: - case BuiltinType::Short: - case BuiltinType::Int: - case BuiltinType::Long: - case BuiltinType::LongLong: - case BuiltinType::Int128: - case BuiltinType::Float: - case BuiltinType::Double: - case BuiltinType::LongDouble: - case BuiltinType::NullPtr: - case BuiltinType::Overload: - case BuiltinType::Dependent: - break; - - case BuiltinType::UndeducedAuto: // FIXME: Deserves a cursor? - break; - - case BuiltinType::ObjCId: - VisitType = Context.getObjCIdType(); - break; - - case BuiltinType::ObjCClass: - VisitType = Context.getObjCClassType(); - break; - - case BuiltinType::ObjCSel: - VisitType = Context.getObjCSelType(); - break; - } - - if (!VisitType.isNull()) { - if (const TypedefType *Typedef = VisitType->getAs<TypedefType>()) - return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), - TU)); - } - - return false; -} - -bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU)); -} - -bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); -} - -bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) { - return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU)); -} - -bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { - if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU))) - return true; - - for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { - if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I), - TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { - if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseTypeLoc())) - return true; - - if (TL.hasProtocolsAsWritten()) { - for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) { - if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), - TL.getProtocolLoc(I), - TU))) - return true; - } - } - - return false; -} - -bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { - return Visit(TL.getPointeeLoc()); -} - -bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL) { - if (Visit(TL.getResultLoc())) - return true; - - for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I) - if (Decl *D = TL.getArg(I)) - if (Visit(MakeCXCursor(D, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) { - if (Visit(TL.getElementLoc())) - return true; - - if (Expr *Size = TL.getSizeExpr()) - return Visit(MakeCXCursor(Size, StmtParent, TU)); - - return false; -} - -bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { - return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU)); -} - -bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { - if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; -} - -bool CursorVisitor::VisitStmt(Stmt *S) { - for (Stmt::child_iterator Child = S->child_begin(), ChildEnd = S->child_end(); - Child != ChildEnd; ++Child) { - if (*Child && Visit(MakeCXCursor(*Child, StmtParent, TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitDeclStmt(DeclStmt *S) { - for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); - D != DEnd; ++D) { - if (*D && Visit(MakeCXCursor(*D, TU))) - return true; - } - - return false; -} - -bool CursorVisitor::VisitIfStmt(IfStmt *S) { - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getThen() && Visit(MakeCXCursor(S->getThen(), StmtParent, TU))) - return true; - if (S->getElse() && Visit(MakeCXCursor(S->getElse(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitSwitchStmt(SwitchStmt *S) { - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitWhileStmt(WhileStmt *S) { - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitForStmt(ForStmt *S) { - if (S->getInit() && Visit(MakeCXCursor(S->getInit(), StmtParent, TU))) - return true; - if (VarDecl *Var = S->getConditionVariable()) { - if (Visit(MakeCXCursor(Var, TU))) - return true; - } - - if (S->getCond() && Visit(MakeCXCursor(S->getCond(), StmtParent, TU))) - return true; - if (S->getInc() && Visit(MakeCXCursor(S->getInc(), StmtParent, TU))) - return true; - if (S->getBody() && Visit(MakeCXCursor(S->getBody(), StmtParent, TU))) - return true; - - return false; -} - -bool CursorVisitor::VisitBlockExpr(BlockExpr *B) { - return Visit(B->getBlockDecl()); -} - -bool CursorVisitor::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { - if (E->isArgumentType()) { - if (TypeSourceInfo *TSInfo = E->getArgumentTypeInfo()) - return Visit(TSInfo->getTypeLoc()); - - return false; - } - - return VisitExpr(E); -} - -bool CursorVisitor::VisitExplicitCastExpr(ExplicitCastExpr *E) { - if (TypeSourceInfo *TSInfo = E->getTypeInfoAsWritten()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return VisitCastExpr(E); -} - -bool CursorVisitor::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { - if (TypeSourceInfo *TSInfo = E->getTypeSourceInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return VisitExpr(E); -} - -bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) { - if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo()) - if (Visit(TSInfo->getTypeLoc())) - return true; - - return VisitExpr(E); -} - -bool CursorVisitor::VisitObjCEncodeExpr(ObjCEncodeExpr *E) { - return Visit(E->getEncodedTypeSourceInfo()->getTypeLoc()); -} - - -bool CursorVisitor::VisitAttributes(Decl *D) { - for (const Attr *A = D->getAttrs(); A; A = A->getNext()) - if (Visit(MakeCXCursor(A, D, TU))) - return true; - - return false; -} - -extern "C" { -CXIndex clang_createIndex(int excludeDeclarationsFromPCH, - int displayDiagnostics) { - CIndexer *CIdxr = new CIndexer(); - if (excludeDeclarationsFromPCH) - CIdxr->setOnlyLocalDecls(); - if (displayDiagnostics) - CIdxr->setDisplayDiagnostics(); - return CIdxr; -} - -void clang_disposeIndex(CXIndex CIdx) { - if (CIdx) - delete static_cast<CIndexer *>(CIdx); -} - -void clang_setUseExternalASTGeneration(CXIndex CIdx, int value) { - if (CIdx) { - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - CXXIdx->setUseExternalASTGeneration(value); - } -} - -CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx, - const char *ast_filename) { - if (!CIdx) - return 0; - - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - - llvm::IntrusiveRefCntPtr<Diagnostic> Diags; - return ASTUnit::LoadFromPCHFile(ast_filename, Diags, - CXXIdx->getOnlyLocalDecls(), - 0, 0, true); -} - -CXTranslationUnit -clang_createTranslationUnitFromSourceFile(CXIndex CIdx, - const char *source_filename, - int num_command_line_args, - const char **command_line_args, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files) { - if (!CIdx) - return 0; - - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - - // Configure the diagnostics. - DiagnosticOptions DiagOpts; - llvm::IntrusiveRefCntPtr<Diagnostic> Diags; - Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - - llvm::SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles; - for (unsigned I = 0; I != num_unsaved_files; ++I) { - llvm::StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length); - const llvm::MemoryBuffer *Buffer - = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename); - RemappedFiles.push_back(std::make_pair(unsaved_files[I].Filename, - Buffer)); - } - - if (!CXXIdx->getUseExternalASTGeneration()) { - llvm::SmallVector<const char *, 16> Args; - - // The 'source_filename' argument is optional. If the caller does not - // specify it then it is assumed that the source file is specified - // in the actual argument list. - if (source_filename) - Args.push_back(source_filename); - Args.insert(Args.end(), command_line_args, - command_line_args + num_command_line_args); - Args.push_back("-Xclang"); - Args.push_back("-detailed-preprocessing-record"); - unsigned NumErrors = Diags->getNumErrors(); - -#ifdef USE_CRASHTRACER - ArgsCrashTracerInfo ACTI(Args); -#endif - - llvm::OwningPtr<ASTUnit> Unit( - ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), - Diags, - CXXIdx->getClangResourcesPath(), - CXXIdx->getOnlyLocalDecls(), - RemappedFiles.data(), - RemappedFiles.size(), - /*CaptureDiagnostics=*/true)); - - // FIXME: Until we have broader testing, just drop the entire AST if we - // encountered an error. - if (NumErrors != Diags->getNumErrors()) { - // Make sure to check that 'Unit' is non-NULL. - if (CXXIdx->getDisplayDiagnostics() && Unit.get()) { - for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(), - DEnd = Unit->stored_diag_end(); - D != DEnd; ++D) { - CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOptions()); - CXString Msg = clang_formatDiagnostic(&Diag, - clang_defaultDiagnosticDisplayOptions()); - fprintf(stderr, "%s\n", clang_getCString(Msg)); - clang_disposeString(Msg); - } -#ifdef LLVM_ON_WIN32 - // On Windows, force a flush, since there may be multiple copies of - // stderr and stdout in the file system, all with different buffers - // but writing to the same device. - fflush(stderr); -#endif - } - } - - return Unit.take(); - } - - // Build up the arguments for invoking 'clang'. - std::vector<const char *> argv; - - // First add the complete path to the 'clang' executable. - llvm::sys::Path ClangPath = static_cast<CIndexer *>(CIdx)->getClangPath(); - argv.push_back(ClangPath.c_str()); - - // Add the '-emit-ast' option as our execution mode for 'clang'. - argv.push_back("-emit-ast"); - - // The 'source_filename' argument is optional. If the caller does not - // specify it then it is assumed that the source file is specified - // in the actual argument list. - if (source_filename) - argv.push_back(source_filename); - - // Generate a temporary name for the AST file. - argv.push_back("-o"); - char astTmpFile[L_tmpnam]; - argv.push_back(tmpnam(astTmpFile)); - - // Remap any unsaved files to temporary files. - std::vector<llvm::sys::Path> TemporaryFiles; - std::vector<std::string> RemapArgs; - if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) - return 0; - - // The pointers into the elements of RemapArgs are stable because we - // won't be adding anything to RemapArgs after this point. - for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) - argv.push_back(RemapArgs[i].c_str()); - - // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'. - for (int i = 0; i < num_command_line_args; ++i) - if (const char *arg = command_line_args[i]) { - if (strcmp(arg, "-o") == 0) { - ++i; // Also skip the matching argument. - continue; - } - if (strcmp(arg, "-emit-ast") == 0 || - strcmp(arg, "-c") == 0 || - strcmp(arg, "-fsyntax-only") == 0) { - continue; - } - - // Keep the argument. - argv.push_back(arg); - } - - // Generate a temporary name for the diagnostics file. - char tmpFileResults[L_tmpnam]; - char *tmpResultsFileName = tmpnam(tmpFileResults); - llvm::sys::Path DiagnosticsFile(tmpResultsFileName); - TemporaryFiles.push_back(DiagnosticsFile); - argv.push_back("-fdiagnostics-binary"); - - argv.push_back("-Xclang"); - argv.push_back("-detailed-preprocessing-record"); - - // Add the null terminator. - argv.push_back(NULL); - - // Invoke 'clang'. - llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null - // on Unix or NUL (Windows). - std::string ErrMsg; - const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DiagnosticsFile, - NULL }; - llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL, - /* redirects */ &Redirects[0], - /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg); - - if (!ErrMsg.empty()) { - std::string AllArgs; - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - AllArgs += ' '; - if (*I) - AllArgs += *I; - } - - Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg; - } - - ASTUnit *ATU = ASTUnit::LoadFromPCHFile(astTmpFile, Diags, - CXXIdx->getOnlyLocalDecls(), - RemappedFiles.data(), - RemappedFiles.size(), - /*CaptureDiagnostics=*/true); - if (ATU) { - LoadSerializedDiagnostics(DiagnosticsFile, - num_unsaved_files, unsaved_files, - ATU->getFileManager(), - ATU->getSourceManager(), - ATU->getStoredDiagnostics()); - } else if (CXXIdx->getDisplayDiagnostics()) { - // We failed to load the ASTUnit, but we can still deserialize the - // diagnostics and emit them. - FileManager FileMgr; - Diagnostic Diag; - SourceManager SourceMgr(Diag); - // FIXME: Faked LangOpts! - LangOptions LangOpts; - llvm::SmallVector<StoredDiagnostic, 4> Diags; - LoadSerializedDiagnostics(DiagnosticsFile, - num_unsaved_files, unsaved_files, - FileMgr, SourceMgr, Diags); - for (llvm::SmallVector<StoredDiagnostic, 4>::iterator D = Diags.begin(), - DEnd = Diags.end(); - D != DEnd; ++D) { - CXStoredDiagnostic Diag(*D, LangOpts); - CXString Msg = clang_formatDiagnostic(&Diag, - clang_defaultDiagnosticDisplayOptions()); - fprintf(stderr, "%s\n", clang_getCString(Msg)); - clang_disposeString(Msg); - } - -#ifdef LLVM_ON_WIN32 - // On Windows, force a flush, since there may be multiple copies of - // stderr and stdout in the file system, all with different buffers - // but writing to the same device. - fflush(stderr); -#endif - } - - if (ATU) { - // Make the translation unit responsible for destroying all temporary files. - for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) - ATU->addTemporaryFile(TemporaryFiles[i]); - ATU->addTemporaryFile(llvm::sys::Path(ATU->getPCHFileName())); - } else { - // Destroy all of the temporary files now; they can't be referenced any - // longer. - llvm::sys::Path(astTmpFile).eraseFromDisk(); - for (unsigned i = 0, e = TemporaryFiles.size(); i != e; ++i) - TemporaryFiles[i].eraseFromDisk(); - } - - return ATU; -} - -void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) { - if (CTUnit) - delete static_cast<ASTUnit *>(CTUnit); -} - -CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) { - if (!CTUnit) - return createCXString(""); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit); - return createCXString(CXXUnit->getOriginalSourceFileName(), true); -} - -CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) { - CXCursor Result = { CXCursor_TranslationUnit, { 0, 0, TU } }; - return Result; -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXSourceLocation and CXSourceRange Operations. -//===----------------------------------------------------------------------===// - -extern "C" { -CXSourceLocation clang_getNullLocation() { - CXSourceLocation Result = { { 0, 0 }, 0 }; - return Result; -} - -unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2) { - return (loc1.ptr_data[0] == loc2.ptr_data[0] && - loc1.ptr_data[1] == loc2.ptr_data[1] && - loc1.int_data == loc2.int_data); -} - -CXSourceLocation clang_getLocation(CXTranslationUnit tu, - CXFile file, - unsigned line, - unsigned column) { - if (!tu) - return clang_getNullLocation(); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); - SourceLocation SLoc - = CXXUnit->getSourceManager().getLocation( - static_cast<const FileEntry *>(file), - line, column); - - return cxloc::translateSourceLocation(CXXUnit->getASTContext(), SLoc); -} - -CXSourceRange clang_getNullRange() { - CXSourceRange Result = { { 0, 0 }, 0, 0 }; - return Result; -} - -CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end) { - if (begin.ptr_data[0] != end.ptr_data[0] || - begin.ptr_data[1] != end.ptr_data[1]) - return clang_getNullRange(); - - CXSourceRange Result = { { begin.ptr_data[0], begin.ptr_data[1] }, - begin.int_data, end.int_data }; - return Result; -} - -void clang_getInstantiationLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, - unsigned *column, - unsigned *offset) { - SourceLocation Loc = SourceLocation::getFromRawEncoding(location.int_data); - - if (!location.ptr_data[0] || Loc.isInvalid()) { - if (file) - *file = 0; - if (line) - *line = 0; - if (column) - *column = 0; - if (offset) - *offset = 0; - return; - } - - const SourceManager &SM = - *static_cast<const SourceManager*>(location.ptr_data[0]); - SourceLocation InstLoc = SM.getInstantiationLoc(Loc); - - if (file) - *file = (void *)SM.getFileEntryForID(SM.getFileID(InstLoc)); - if (line) - *line = SM.getInstantiationLineNumber(InstLoc); - if (column) - *column = SM.getInstantiationColumnNumber(InstLoc); - if (offset) - *offset = SM.getDecomposedLoc(InstLoc).second; -} - -CXSourceLocation clang_getRangeStart(CXSourceRange range) { - CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, - range.begin_int_data }; - return Result; -} - -CXSourceLocation clang_getRangeEnd(CXSourceRange range) { - CXSourceLocation Result = { { range.ptr_data[0], range.ptr_data[1] }, - range.end_int_data }; - return Result; -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXFile Operations. -//===----------------------------------------------------------------------===// - -extern "C" { -CXString clang_getFileName(CXFile SFile) { - if (!SFile) - return createCXString(NULL); - - FileEntry *FEnt = static_cast<FileEntry *>(SFile); - return createCXString(FEnt->getName()); -} - -time_t clang_getFileTime(CXFile SFile) { - if (!SFile) - return 0; - - FileEntry *FEnt = static_cast<FileEntry *>(SFile); - return FEnt->getModificationTime(); -} - -CXFile clang_getFile(CXTranslationUnit tu, const char *file_name) { - if (!tu) - return 0; - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(tu); - - FileManager &FMgr = CXXUnit->getFileManager(); - const FileEntry *File = FMgr.getFile(file_name, file_name+strlen(file_name)); - return const_cast<FileEntry *>(File); -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXCursor Operations. -//===----------------------------------------------------------------------===// - -static Decl *getDeclFromExpr(Stmt *E) { - if (DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E)) - return RefExpr->getDecl(); - if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) - return ME->getMemberDecl(); - if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E)) - return RE->getDecl(); - - if (CallExpr *CE = dyn_cast<CallExpr>(E)) - return getDeclFromExpr(CE->getCallee()); - if (CastExpr *CE = dyn_cast<CastExpr>(E)) - return getDeclFromExpr(CE->getSubExpr()); - if (ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E)) - return OME->getMethodDecl(); - - return 0; -} - -static SourceLocation getLocationFromExpr(Expr *E) { - if (ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E)) - return /*FIXME:*/Msg->getLeftLoc(); - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) - return DRE->getLocation(); - if (MemberExpr *Member = dyn_cast<MemberExpr>(E)) - return Member->getMemberLoc(); - if (ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E)) - return Ivar->getLocation(); - return E->getLocStart(); -} - -extern "C" { - -unsigned clang_visitChildren(CXCursor parent, - CXCursorVisitor visitor, - CXClientData client_data) { - ASTUnit *CXXUnit = getCursorASTUnit(parent); - - unsigned PCHLevel = Decl::MaxPCHLevel; - - // Set the PCHLevel to filter out unwanted decls if requested. - if (CXXUnit->getOnlyLocalDecls()) { - PCHLevel = 0; - - // If the main input was an AST, bump the level. - if (CXXUnit->isMainFileAST()) - ++PCHLevel; - } - - CursorVisitor CursorVis(CXXUnit, visitor, client_data, PCHLevel); - return CursorVis.VisitChildren(parent); -} - -static CXString getDeclSpelling(Decl *D) { - NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D); - if (!ND) - return createCXString(""); - - if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND)) - return createCXString(OMD->getSelector().getAsString()); - - if (ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND)) - // No, this isn't the same as the code below. getIdentifier() is non-virtual - // and returns different names. NamedDecl returns the class name and - // ObjCCategoryImplDecl returns the category name. - return createCXString(CIMP->getIdentifier()->getNameStart()); - - if (ND->getIdentifier()) - return createCXString(ND->getIdentifier()->getNameStart()); - - return createCXString(""); -} - -CXString clang_getCursorSpelling(CXCursor C) { - if (clang_isTranslationUnit(C.kind)) - return clang_getTranslationUnitSpelling(C.data[2]); - - if (clang_isReference(C.kind)) { - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: { - ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first; - return createCXString(Super->getIdentifier()->getNameStart()); - } - case CXCursor_ObjCClassRef: { - ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first; - return createCXString(Class->getIdentifier()->getNameStart()); - } - case CXCursor_ObjCProtocolRef: { - ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first; - assert(OID && "getCursorSpelling(): Missing protocol decl"); - return createCXString(OID->getIdentifier()->getNameStart()); - } - case CXCursor_TypeRef: { - TypeDecl *Type = getCursorTypeRef(C).first; - assert(Type && "Missing type decl"); - - return createCXString(getCursorContext(C).getTypeDeclType(Type). - getAsString()); - } - - default: - return createCXString("<not implemented>"); - } - } - - if (clang_isExpression(C.kind)) { - Decl *D = getDeclFromExpr(getCursorExpr(C)); - if (D) - return getDeclSpelling(D); - return createCXString(""); - } - - if (C.kind == CXCursor_MacroInstantiation) - return createCXString(getCursorMacroInstantiation(C)->getName() - ->getNameStart()); - - if (C.kind == CXCursor_MacroDefinition) - return createCXString(getCursorMacroDefinition(C)->getName() - ->getNameStart()); - - if (clang_isDeclaration(C.kind)) - return getDeclSpelling(getCursorDecl(C)); - - return createCXString(""); -} - -CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { - switch (Kind) { - case CXCursor_FunctionDecl: - return createCXString("FunctionDecl"); - case CXCursor_TypedefDecl: - return createCXString("TypedefDecl"); - case CXCursor_EnumDecl: - return createCXString("EnumDecl"); - case CXCursor_EnumConstantDecl: - return createCXString("EnumConstantDecl"); - case CXCursor_StructDecl: - return createCXString("StructDecl"); - case CXCursor_UnionDecl: - return createCXString("UnionDecl"); - case CXCursor_ClassDecl: - return createCXString("ClassDecl"); - case CXCursor_FieldDecl: - return createCXString("FieldDecl"); - case CXCursor_VarDecl: - return createCXString("VarDecl"); - case CXCursor_ParmDecl: - return createCXString("ParmDecl"); - case CXCursor_ObjCInterfaceDecl: - return createCXString("ObjCInterfaceDecl"); - case CXCursor_ObjCCategoryDecl: - return createCXString("ObjCCategoryDecl"); - case CXCursor_ObjCProtocolDecl: - return createCXString("ObjCProtocolDecl"); - case CXCursor_ObjCPropertyDecl: - return createCXString("ObjCPropertyDecl"); - case CXCursor_ObjCIvarDecl: - return createCXString("ObjCIvarDecl"); - case CXCursor_ObjCInstanceMethodDecl: - return createCXString("ObjCInstanceMethodDecl"); - case CXCursor_ObjCClassMethodDecl: - return createCXString("ObjCClassMethodDecl"); - case CXCursor_ObjCImplementationDecl: - return createCXString("ObjCImplementationDecl"); - case CXCursor_ObjCCategoryImplDecl: - return createCXString("ObjCCategoryImplDecl"); - case CXCursor_CXXMethod: - return createCXString("CXXMethod"); - case CXCursor_UnexposedDecl: - return createCXString("UnexposedDecl"); - case CXCursor_ObjCSuperClassRef: - return createCXString("ObjCSuperClassRef"); - case CXCursor_ObjCProtocolRef: - return createCXString("ObjCProtocolRef"); - case CXCursor_ObjCClassRef: - return createCXString("ObjCClassRef"); - case CXCursor_TypeRef: - return createCXString("TypeRef"); - case CXCursor_UnexposedExpr: - return createCXString("UnexposedExpr"); - case CXCursor_BlockExpr: - return createCXString("BlockExpr"); - case CXCursor_DeclRefExpr: - return createCXString("DeclRefExpr"); - case CXCursor_MemberRefExpr: - return createCXString("MemberRefExpr"); - case CXCursor_CallExpr: - return createCXString("CallExpr"); - case CXCursor_ObjCMessageExpr: - return createCXString("ObjCMessageExpr"); - case CXCursor_UnexposedStmt: - return createCXString("UnexposedStmt"); - case CXCursor_InvalidFile: - return createCXString("InvalidFile"); - case CXCursor_InvalidCode: - return createCXString("InvalidCode"); - case CXCursor_NoDeclFound: - return createCXString("NoDeclFound"); - case CXCursor_NotImplemented: - return createCXString("NotImplemented"); - case CXCursor_TranslationUnit: - return createCXString("TranslationUnit"); - case CXCursor_UnexposedAttr: - return createCXString("UnexposedAttr"); - case CXCursor_IBActionAttr: - return createCXString("attribute(ibaction)"); - case CXCursor_IBOutletAttr: - return createCXString("attribute(iboutlet)"); - case CXCursor_PreprocessingDirective: - return createCXString("preprocessing directive"); - case CXCursor_MacroDefinition: - return createCXString("macro definition"); - case CXCursor_MacroInstantiation: - return createCXString("macro instantiation"); - } - - llvm_unreachable("Unhandled CXCursorKind"); - return createCXString(NULL); -} - -enum CXChildVisitResult GetCursorVisitor(CXCursor cursor, - CXCursor parent, - CXClientData client_data) { - CXCursor *BestCursor = static_cast<CXCursor *>(client_data); - *BestCursor = cursor; - return CXChildVisit_Recurse; -} - -CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) { - if (!TU) - return clang_getNullCursor(); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - - SourceLocation SLoc = cxloc::translateSourceLocation(Loc); - CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound); - if (SLoc.isValid()) { - SourceRange RegionOfInterest(SLoc, SLoc.getFileLocWithOffset(1)); - - // FIXME: Would be great to have a "hint" cursor, then walk from that - // hint cursor upward until we find a cursor whose source range encloses - // the region of interest, rather than starting from the translation unit. - CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); - CursorVisitor CursorVis(CXXUnit, GetCursorVisitor, &Result, - Decl::MaxPCHLevel, RegionOfInterest); - CursorVis.VisitChildren(Parent); - } - return Result; -} - -CXCursor clang_getNullCursor(void) { - return MakeCXCursorInvalid(CXCursor_InvalidFile); -} - -unsigned clang_equalCursors(CXCursor X, CXCursor Y) { - return X == Y; -} - -unsigned clang_isInvalid(enum CXCursorKind K) { - return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid; -} - -unsigned clang_isDeclaration(enum CXCursorKind K) { - return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl; -} - -unsigned clang_isReference(enum CXCursorKind K) { - return K >= CXCursor_FirstRef && K <= CXCursor_LastRef; -} - -unsigned clang_isExpression(enum CXCursorKind K) { - return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr; -} - -unsigned clang_isStatement(enum CXCursorKind K) { - return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt; -} - -unsigned clang_isTranslationUnit(enum CXCursorKind K) { - return K == CXCursor_TranslationUnit; -} - -unsigned clang_isPreprocessing(enum CXCursorKind K) { - return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing; -} - -unsigned clang_isUnexposed(enum CXCursorKind K) { - switch (K) { - case CXCursor_UnexposedDecl: - case CXCursor_UnexposedExpr: - case CXCursor_UnexposedStmt: - case CXCursor_UnexposedAttr: - return true; - default: - return false; - } -} - -CXCursorKind clang_getCursorKind(CXCursor C) { - return C.kind; -} - -CXSourceLocation clang_getCursorLocation(CXCursor C) { - if (clang_isReference(C.kind)) { - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P - = getCursorObjCSuperClassRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_ObjCProtocolRef: { - std::pair<ObjCProtocolDecl *, SourceLocation> P - = getCursorObjCProtocolRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_ObjCClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P - = getCursorObjCClassRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - case CXCursor_TypeRef: { - std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); - return cxloc::translateSourceLocation(P.first->getASTContext(), P.second); - } - - default: - // FIXME: Need a way to enumerate all non-reference cases. - llvm_unreachable("Missed a reference kind"); - } - } - - if (clang_isExpression(C.kind)) - return cxloc::translateSourceLocation(getCursorContext(C), - getLocationFromExpr(getCursorExpr(C))); - - if (C.kind == CXCursor_PreprocessingDirective) { - SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin(); - return cxloc::translateSourceLocation(getCursorContext(C), L); - } - - if (C.kind == CXCursor_MacroInstantiation) { - SourceLocation L - = cxcursor::getCursorMacroInstantiation(C)->getSourceRange().getBegin(); - return cxloc::translateSourceLocation(getCursorContext(C), L); - } - - if (C.kind == CXCursor_MacroDefinition) { - SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation(); - return cxloc::translateSourceLocation(getCursorContext(C), L); - } - - if (!getCursorDecl(C)) - return clang_getNullLocation(); - - Decl *D = getCursorDecl(C); - SourceLocation Loc = D->getLocation(); - if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(D)) - Loc = Class->getClassLoc(); - return cxloc::translateSourceLocation(getCursorContext(C), Loc); -} - -CXSourceRange clang_getCursorExtent(CXCursor C) { - if (clang_isReference(C.kind)) { - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P - = getCursorObjCSuperClassRef(C); - return cxloc::translateSourceRange(P.first->getASTContext(), P.second); - } - - case CXCursor_ObjCProtocolRef: { - std::pair<ObjCProtocolDecl *, SourceLocation> P - = getCursorObjCProtocolRef(C); - return cxloc::translateSourceRange(P.first->getASTContext(), P.second); - } - - case CXCursor_ObjCClassRef: { - std::pair<ObjCInterfaceDecl *, SourceLocation> P - = getCursorObjCClassRef(C); - - return cxloc::translateSourceRange(P.first->getASTContext(), P.second); - } - - case CXCursor_TypeRef: { - std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); - return cxloc::translateSourceRange(P.first->getASTContext(), P.second); - } - - default: - // FIXME: Need a way to enumerate all non-reference cases. - llvm_unreachable("Missed a reference kind"); - } - } - - if (clang_isExpression(C.kind)) - return cxloc::translateSourceRange(getCursorContext(C), - getCursorExpr(C)->getSourceRange()); - - if (clang_isStatement(C.kind)) - return cxloc::translateSourceRange(getCursorContext(C), - getCursorStmt(C)->getSourceRange()); - - if (C.kind == CXCursor_PreprocessingDirective) { - SourceRange R = cxcursor::getCursorPreprocessingDirective(C); - return cxloc::translateSourceRange(getCursorContext(C), R); - } - - if (C.kind == CXCursor_MacroInstantiation) { - SourceRange R = cxcursor::getCursorMacroInstantiation(C)->getSourceRange(); - return cxloc::translateSourceRange(getCursorContext(C), R); - } - - if (C.kind == CXCursor_MacroDefinition) { - SourceRange R = cxcursor::getCursorMacroDefinition(C)->getSourceRange(); - return cxloc::translateSourceRange(getCursorContext(C), R); - } - - if (!getCursorDecl(C)) - return clang_getNullRange(); - - Decl *D = getCursorDecl(C); - return cxloc::translateSourceRange(getCursorContext(C), D->getSourceRange()); -} - -CXCursor clang_getCursorReferenced(CXCursor C) { - if (clang_isInvalid(C.kind)) - return clang_getNullCursor(); - - ASTUnit *CXXUnit = getCursorASTUnit(C); - if (clang_isDeclaration(C.kind)) - return C; - - if (clang_isExpression(C.kind)) { - Decl *D = getDeclFromExpr(getCursorExpr(C)); - if (D) - return MakeCXCursor(D, CXXUnit); - return clang_getNullCursor(); - } - - if (C.kind == CXCursor_MacroInstantiation) { - if (MacroDefinition *Def = getCursorMacroInstantiation(C)->getDefinition()) - return MakeMacroDefinitionCursor(Def, CXXUnit); - } - - if (!clang_isReference(C.kind)) - return clang_getNullCursor(); - - switch (C.kind) { - case CXCursor_ObjCSuperClassRef: - return MakeCXCursor(getCursorObjCSuperClassRef(C).first, CXXUnit); - - case CXCursor_ObjCProtocolRef: { - return MakeCXCursor(getCursorObjCProtocolRef(C).first, CXXUnit); - - case CXCursor_ObjCClassRef: - return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit); - - case CXCursor_TypeRef: - return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit); - - default: - // We would prefer to enumerate all non-reference cursor kinds here. - llvm_unreachable("Unhandled reference cursor kind"); - break; - } - } - - return clang_getNullCursor(); -} - -CXCursor clang_getCursorDefinition(CXCursor C) { - if (clang_isInvalid(C.kind)) - return clang_getNullCursor(); - - ASTUnit *CXXUnit = getCursorASTUnit(C); - - bool WasReference = false; - if (clang_isReference(C.kind) || clang_isExpression(C.kind)) { - C = clang_getCursorReferenced(C); - WasReference = true; - } - - if (C.kind == CXCursor_MacroInstantiation) - return clang_getCursorReferenced(C); - - if (!clang_isDeclaration(C.kind)) - return clang_getNullCursor(); - - Decl *D = getCursorDecl(C); - if (!D) - return clang_getNullCursor(); - - switch (D->getKind()) { - // Declaration kinds that don't really separate the notions of - // declaration and definition. - case Decl::Namespace: - case Decl::Typedef: - case Decl::TemplateTypeParm: - case Decl::EnumConstant: - case Decl::Field: - case Decl::ObjCIvar: - case Decl::ObjCAtDefsField: - case Decl::ImplicitParam: - case Decl::ParmVar: - case Decl::NonTypeTemplateParm: - case Decl::TemplateTemplateParm: - case Decl::ObjCCategoryImpl: - case Decl::ObjCImplementation: - case Decl::LinkageSpec: - case Decl::ObjCPropertyImpl: - case Decl::FileScopeAsm: - case Decl::StaticAssert: - case Decl::Block: - return C; - - // Declaration kinds that don't make any sense here, but are - // nonetheless harmless. - case Decl::TranslationUnit: - break; - - // Declaration kinds for which the definition is not resolvable. - case Decl::UnresolvedUsingTypename: - case Decl::UnresolvedUsingValue: - break; - - case Decl::UsingDirective: - return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(), - CXXUnit); - - case Decl::NamespaceAlias: - return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), CXXUnit); - - case Decl::Enum: - case Decl::Record: - case Decl::CXXRecord: - case Decl::ClassTemplateSpecialization: - case Decl::ClassTemplatePartialSpecialization: - if (TagDecl *Def = cast<TagDecl>(D)->getDefinition()) - return MakeCXCursor(Def, CXXUnit); - return clang_getNullCursor(); - - case Decl::Function: - case Decl::CXXMethod: - case Decl::CXXConstructor: - case Decl::CXXDestructor: - case Decl::CXXConversion: { - const FunctionDecl *Def = 0; - if (cast<FunctionDecl>(D)->getBody(Def)) - return MakeCXCursor(const_cast<FunctionDecl *>(Def), CXXUnit); - return clang_getNullCursor(); - } - - case Decl::Var: { - // Ask the variable if it has a definition. - if (VarDecl *Def = cast<VarDecl>(D)->getDefinition()) - return MakeCXCursor(Def, CXXUnit); - return clang_getNullCursor(); - } - - case Decl::FunctionTemplate: { - const FunctionDecl *Def = 0; - if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def)) - return MakeCXCursor(Def->getDescribedFunctionTemplate(), CXXUnit); - return clang_getNullCursor(); - } - - case Decl::ClassTemplate: { - if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl() - ->getDefinition()) - return MakeCXCursor( - cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(), - CXXUnit); - return clang_getNullCursor(); - } - - case Decl::Using: { - UsingDecl *Using = cast<UsingDecl>(D); - CXCursor Def = clang_getNullCursor(); - for (UsingDecl::shadow_iterator S = Using->shadow_begin(), - SEnd = Using->shadow_end(); - S != SEnd; ++S) { - if (Def != clang_getNullCursor()) { - // FIXME: We have no way to return multiple results. - return clang_getNullCursor(); - } - - Def = clang_getCursorDefinition(MakeCXCursor((*S)->getTargetDecl(), - CXXUnit)); - } - - return Def; - } - - case Decl::UsingShadow: - return clang_getCursorDefinition( - MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), - CXXUnit)); - - case Decl::ObjCMethod: { - ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D); - if (Method->isThisDeclarationADefinition()) - return C; - - // Dig out the method definition in the associated - // @implementation, if we have it. - // FIXME: The ASTs should make finding the definition easier. - if (ObjCInterfaceDecl *Class - = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext())) - if (ObjCImplementationDecl *ClassImpl = Class->getImplementation()) - if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(), - Method->isInstanceMethod())) - if (Def->isThisDeclarationADefinition()) - return MakeCXCursor(Def, CXXUnit); - - return clang_getNullCursor(); - } - - case Decl::ObjCCategory: - if (ObjCCategoryImplDecl *Impl - = cast<ObjCCategoryDecl>(D)->getImplementation()) - return MakeCXCursor(Impl, CXXUnit); - return clang_getNullCursor(); - - case Decl::ObjCProtocol: - if (!cast<ObjCProtocolDecl>(D)->isForwardDecl()) - return C; - return clang_getNullCursor(); - - case Decl::ObjCInterface: - // There are two notions of a "definition" for an Objective-C - // class: the interface and its implementation. When we resolved a - // reference to an Objective-C class, produce the @interface as - // the definition; when we were provided with the interface, - // produce the @implementation as the definition. - if (WasReference) { - if (!cast<ObjCInterfaceDecl>(D)->isForwardDecl()) - return C; - } else if (ObjCImplementationDecl *Impl - = cast<ObjCInterfaceDecl>(D)->getImplementation()) - return MakeCXCursor(Impl, CXXUnit); - return clang_getNullCursor(); - - case Decl::ObjCProperty: - // FIXME: We don't really know where to find the - // ObjCPropertyImplDecls that implement this property. - return clang_getNullCursor(); - - case Decl::ObjCCompatibleAlias: - if (ObjCInterfaceDecl *Class - = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface()) - if (!Class->isForwardDecl()) - return MakeCXCursor(Class, CXXUnit); - - return clang_getNullCursor(); - - case Decl::ObjCForwardProtocol: { - ObjCForwardProtocolDecl *Forward = cast<ObjCForwardProtocolDecl>(D); - if (Forward->protocol_size() == 1) - return clang_getCursorDefinition( - MakeCXCursor(*Forward->protocol_begin(), - CXXUnit)); - - // FIXME: Cannot return multiple definitions. - return clang_getNullCursor(); - } - - case Decl::ObjCClass: { - ObjCClassDecl *Class = cast<ObjCClassDecl>(D); - if (Class->size() == 1) { - ObjCInterfaceDecl *IFace = Class->begin()->getInterface(); - if (!IFace->isForwardDecl()) - return MakeCXCursor(IFace, CXXUnit); - return clang_getNullCursor(); - } - - // FIXME: Cannot return multiple definitions. - return clang_getNullCursor(); - } - - case Decl::Friend: - if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl()) - return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); - return clang_getNullCursor(); - - case Decl::FriendTemplate: - if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl()) - return clang_getCursorDefinition(MakeCXCursor(Friend, CXXUnit)); - return clang_getNullCursor(); - } - - return clang_getNullCursor(); -} - -unsigned clang_isCursorDefinition(CXCursor C) { - if (!clang_isDeclaration(C.kind)) - return 0; - - return clang_getCursorDefinition(C) == C; -} - -void clang_getDefinitionSpellingAndExtent(CXCursor C, - const char **startBuf, - const char **endBuf, - unsigned *startLine, - unsigned *startColumn, - unsigned *endLine, - unsigned *endColumn) { - assert(getCursorDecl(C) && "CXCursor has null decl"); - NamedDecl *ND = static_cast<NamedDecl *>(getCursorDecl(C)); - FunctionDecl *FD = dyn_cast<FunctionDecl>(ND); - CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody()); - - SourceManager &SM = FD->getASTContext().getSourceManager(); - *startBuf = SM.getCharacterData(Body->getLBracLoc()); - *endBuf = SM.getCharacterData(Body->getRBracLoc()); - *startLine = SM.getSpellingLineNumber(Body->getLBracLoc()); - *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc()); - *endLine = SM.getSpellingLineNumber(Body->getRBracLoc()); - *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc()); -} - -void clang_enableStackTraces(void) { - llvm::sys::PrintStackTraceOnErrorSignal(); -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Token-based Operations. -//===----------------------------------------------------------------------===// - -/* CXToken layout: - * int_data[0]: a CXTokenKind - * int_data[1]: starting token location - * int_data[2]: token length - * int_data[3]: reserved - * ptr_data: for identifiers and keywords, an IdentifierInfo*. - * otherwise unused. - */ -extern "C" { - -CXTokenKind clang_getTokenKind(CXToken CXTok) { - return static_cast<CXTokenKind>(CXTok.int_data[0]); -} - -CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) { - switch (clang_getTokenKind(CXTok)) { - case CXToken_Identifier: - case CXToken_Keyword: - // We know we have an IdentifierInfo*, so use that. - return createCXString(static_cast<IdentifierInfo *>(CXTok.ptr_data) - ->getNameStart()); - - case CXToken_Literal: { - // We have stashed the starting pointer in the ptr_data field. Use it. - const char *Text = static_cast<const char *>(CXTok.ptr_data); - return createCXString(llvm::StringRef(Text, CXTok.int_data[2])); - } - - case CXToken_Punctuation: - case CXToken_Comment: - break; - } - - // We have to find the starting buffer pointer the hard way, by - // deconstructing the source location. - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) - return createCXString(""); - - SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]); - std::pair<FileID, unsigned> LocInfo - = CXXUnit->getSourceManager().getDecomposedLoc(Loc); - bool Invalid = false; - llvm::StringRef Buffer - = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); - if (Invalid) - return createCXString(""); - - return createCXString(Buffer.substr(LocInfo.second, CXTok.int_data[2])); -} - -CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) - return clang_getNullLocation(); - - return cxloc::translateSourceLocation(CXXUnit->getASTContext(), - SourceLocation::getFromRawEncoding(CXTok.int_data[1])); -} - -CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit) - return clang_getNullRange(); - - return cxloc::translateSourceRange(CXXUnit->getASTContext(), - SourceLocation::getFromRawEncoding(CXTok.int_data[1])); -} - -void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, - CXToken **Tokens, unsigned *NumTokens) { - if (Tokens) - *Tokens = 0; - if (NumTokens) - *NumTokens = 0; - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit || !Tokens || !NumTokens) - return; - - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - - SourceRange R = cxloc::translateCXSourceRange(Range); - if (R.isInvalid()) - return; - - SourceManager &SourceMgr = CXXUnit->getSourceManager(); - std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(R.getBegin()); - std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(R.getEnd()); - - // Cannot tokenize across files. - if (BeginLocInfo.first != EndLocInfo.first) - return; - - // Create a lexer - bool Invalid = false; - llvm::StringRef Buffer - = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid); - if (Invalid) - return; - - Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), - CXXUnit->getASTContext().getLangOptions(), - Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end()); - Lex.SetCommentRetentionState(true); - - // Lex tokens until we hit the end of the range. - const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second; - llvm::SmallVector<CXToken, 32> CXTokens; - Token Tok; - do { - // Lex the next token - Lex.LexFromRawLexer(Tok); - if (Tok.is(tok::eof)) - break; - - // Initialize the CXToken. - CXToken CXTok; - - // - Common fields - CXTok.int_data[1] = Tok.getLocation().getRawEncoding(); - CXTok.int_data[2] = Tok.getLength(); - CXTok.int_data[3] = 0; - - // - Kind-specific fields - if (Tok.isLiteral()) { - CXTok.int_data[0] = CXToken_Literal; - CXTok.ptr_data = (void *)Tok.getLiteralData(); - } else if (Tok.is(tok::identifier)) { - // Lookup the identifier to determine whether we have a keyword. - std::pair<FileID, unsigned> LocInfo - = SourceMgr.getDecomposedLoc(Tok.getLocation()); - bool Invalid = false; - llvm::StringRef Buf - = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid); - if (Invalid) - return; - - const char *StartPos = Buf.data() + LocInfo.second; - IdentifierInfo *II - = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok, StartPos); - CXTok.int_data[0] = II->getTokenID() == tok::identifier? - CXToken_Identifier - : CXToken_Keyword; - CXTok.ptr_data = II; - } else if (Tok.is(tok::comment)) { - CXTok.int_data[0] = CXToken_Comment; - CXTok.ptr_data = 0; - } else { - CXTok.int_data[0] = CXToken_Punctuation; - CXTok.ptr_data = 0; - } - CXTokens.push_back(CXTok); - } while (Lex.getBufferLocation() <= EffectiveBufferEnd); - - if (CXTokens.empty()) - return; - - *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size()); - memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size()); - *NumTokens = CXTokens.size(); -} - -typedef llvm::DenseMap<unsigned, CXCursor> AnnotateTokensData; - -enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor, - CXCursor parent, - CXClientData client_data) { - AnnotateTokensData *Data = static_cast<AnnotateTokensData *>(client_data); - - // We only annotate the locations of declarations, simple - // references, and expressions which directly reference something. - CXCursorKind Kind = clang_getCursorKind(cursor); - if (clang_isDeclaration(Kind) || clang_isReference(Kind)) { - // Okay: We can annotate the location of this declaration with the - // declaration or reference - } else if (clang_isExpression(cursor.kind)) { - if (Kind != CXCursor_DeclRefExpr && - Kind != CXCursor_MemberRefExpr && - Kind != CXCursor_ObjCMessageExpr) - return CXChildVisit_Recurse; - - CXCursor Referenced = clang_getCursorReferenced(cursor); - if (Referenced == cursor || Referenced == clang_getNullCursor()) - return CXChildVisit_Recurse; - - // Okay: we can annotate the location of this expression - } else if (clang_isPreprocessing(cursor.kind)) { - // We can always annotate a preprocessing directive/macro instantiation. - } else { - // Nothing to annotate - return CXChildVisit_Recurse; - } - - CXSourceLocation Loc = clang_getCursorLocation(cursor); - (*Data)[Loc.int_data] = cursor; - return CXChildVisit_Recurse; -} - -void clang_annotateTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens, - CXCursor *Cursors) { - if (NumTokens == 0) - return; - - // Any token we don't specifically annotate will have a NULL cursor. - for (unsigned I = 0; I != NumTokens; ++I) - Cursors[I] = clang_getNullCursor(); - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - if (!CXXUnit || !Tokens) - return; - - ASTUnit::ConcurrencyCheck Check(*CXXUnit); - - // Determine the region of interest, which contains all of the tokens. - SourceRange RegionOfInterest; - RegionOfInterest.setBegin( - cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0]))); - SourceLocation End - = cxloc::translateSourceLocation(clang_getTokenLocation(TU, - Tokens[NumTokens - 1])); - RegionOfInterest.setEnd(CXXUnit->getPreprocessor().getLocForEndOfToken(End)); - - // A mapping from the source locations found when re-lexing or traversing the - // region of interest to the corresponding cursors. - AnnotateTokensData Annotated; - - // Relex the tokens within the source range to look for preprocessing - // directives. - SourceManager &SourceMgr = CXXUnit->getSourceManager(); - std::pair<FileID, unsigned> BeginLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getBegin()); - std::pair<FileID, unsigned> EndLocInfo - = SourceMgr.getDecomposedLoc(RegionOfInterest.getEnd()); - - llvm::StringRef Buffer; - bool Invalid = false; - if (BeginLocInfo.first == EndLocInfo.first && - ((Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid)),true) && - !Invalid) { - Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first), - CXXUnit->getASTContext().getLangOptions(), - Buffer.begin(), Buffer.data() + BeginLocInfo.second, - Buffer.end()); - Lex.SetCommentRetentionState(true); - - // Lex tokens in raw mode until we hit the end of the range, to avoid - // entering #includes or expanding macros. - while (true) { - Token Tok; - Lex.LexFromRawLexer(Tok); - - reprocess: - if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) { - // We have found a preprocessing directive. Gobble it up so that we - // don't see it while preprocessing these tokens later, but keep track of - // all of the token locations inside this preprocessing directive so that - // we can annotate them appropriately. - // - // FIXME: Some simple tests here could identify macro definitions and - // #undefs, to provide specific cursor kinds for those. - std::vector<SourceLocation> Locations; - do { - Locations.push_back(Tok.getLocation()); - Lex.LexFromRawLexer(Tok); - } while (!Tok.isAtStartOfLine() && !Tok.is(tok::eof)); - - using namespace cxcursor; - CXCursor Cursor - = MakePreprocessingDirectiveCursor(SourceRange(Locations.front(), - Locations.back()), - CXXUnit); - for (unsigned I = 0, N = Locations.size(); I != N; ++I) { - Annotated[Locations[I].getRawEncoding()] = Cursor; - } - - if (Tok.isAtStartOfLine()) - goto reprocess; - - continue; - } - - if (Tok.is(tok::eof)) - break; - } - } - - // Annotate all of the source locations in the region of interest that map to - // a specific cursor. - CXCursor Parent = clang_getTranslationUnitCursor(CXXUnit); - CursorVisitor AnnotateVis(CXXUnit, AnnotateTokensVisitor, &Annotated, - Decl::MaxPCHLevel, RegionOfInterest); - AnnotateVis.VisitChildren(Parent); - - for (unsigned I = 0; I != NumTokens; ++I) { - // Determine whether we saw a cursor at this token's location. - AnnotateTokensData::iterator Pos = Annotated.find(Tokens[I].int_data[1]); - if (Pos == Annotated.end()) - continue; - - Cursors[I] = Pos->second; - } -} - -void clang_disposeTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens) { - free(Tokens); -} - -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Operations for querying linkage of a cursor. -//===----------------------------------------------------------------------===// - -extern "C" { -CXLinkageKind clang_getCursorLinkage(CXCursor cursor) { - if (!clang_isDeclaration(cursor.kind)) - return CXLinkage_Invalid; - - Decl *D = cxcursor::getCursorDecl(cursor); - if (NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D)) - switch (ND->getLinkage()) { - case NoLinkage: return CXLinkage_NoLinkage; - case InternalLinkage: return CXLinkage_Internal; - case UniqueExternalLinkage: return CXLinkage_UniqueExternal; - case ExternalLinkage: return CXLinkage_External; - }; - - return CXLinkage_Invalid; -} -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// Operations for querying language of a cursor. -//===----------------------------------------------------------------------===// - -static CXLanguageKind getDeclLanguage(const Decl *D) { - switch (D->getKind()) { - default: - break; - case Decl::ImplicitParam: - case Decl::ObjCAtDefsField: - case Decl::ObjCCategory: - case Decl::ObjCCategoryImpl: - case Decl::ObjCClass: - case Decl::ObjCCompatibleAlias: - case Decl::ObjCForwardProtocol: - case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCIvar: - case Decl::ObjCMethod: - case Decl::ObjCProperty: - case Decl::ObjCPropertyImpl: - case Decl::ObjCProtocol: - return CXLanguage_ObjC; - case Decl::CXXConstructor: - case Decl::CXXConversion: - case Decl::CXXDestructor: - case Decl::CXXMethod: - case Decl::CXXRecord: - case Decl::ClassTemplate: - case Decl::ClassTemplatePartialSpecialization: - case Decl::ClassTemplateSpecialization: - case Decl::Friend: - case Decl::FriendTemplate: - case Decl::FunctionTemplate: - case Decl::LinkageSpec: - case Decl::Namespace: - case Decl::NamespaceAlias: - case Decl::NonTypeTemplateParm: - case Decl::StaticAssert: - case Decl::TemplateTemplateParm: - case Decl::TemplateTypeParm: - case Decl::UnresolvedUsingTypename: - case Decl::UnresolvedUsingValue: - case Decl::Using: - case Decl::UsingDirective: - case Decl::UsingShadow: - return CXLanguage_CPlusPlus; - } - - return CXLanguage_C; -} - -extern "C" { -CXLanguageKind clang_getCursorLanguage(CXCursor cursor) { - if (clang_isDeclaration(cursor.kind)) - return getDeclLanguage(cxcursor::getCursorDecl(cursor)); - - return CXLanguage_Invalid; -} -} // end: extern "C" - -//===----------------------------------------------------------------------===// -// CXString Operations. -//===----------------------------------------------------------------------===// - -extern "C" { -const char *clang_getCString(CXString string) { - return string.Spelling; -} - -void clang_disposeString(CXString string) { - if (string.MustFreeString && string.Spelling) - free((void*)string.Spelling); -} - -} // end: extern "C" - -namespace clang { namespace cxstring { -CXString createCXString(const char *String, bool DupString){ - CXString Str; - if (DupString) { - Str.Spelling = strdup(String); - Str.MustFreeString = 1; - } else { - Str.Spelling = String; - Str.MustFreeString = 0; - } - return Str; -} - -CXString createCXString(llvm::StringRef String, bool DupString) { - CXString Result; - if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { - char *Spelling = (char *)malloc(String.size() + 1); - memmove(Spelling, String.data(), String.size()); - Spelling[String.size()] = 0; - Result.Spelling = Spelling; - Result.MustFreeString = 1; - } else { - Result.Spelling = String.data(); - Result.MustFreeString = 0; - } - return Result; -} -}} - -//===----------------------------------------------------------------------===// -// Misc. utility functions. -//===----------------------------------------------------------------------===// - -extern "C" { - -CXString clang_getClangVersion() { - return createCXString(getClangFullVersion()); -} - -} // end: extern "C" diff --git a/tools/CIndex/CIndex.darwin.exports b/tools/CIndex/CIndex.darwin.exports deleted file mode 100644 index b361168..0000000 --- a/tools/CIndex/CIndex.darwin.exports +++ /dev/null @@ -1,81 +0,0 @@ -_clang_annotateTokens -_clang_codeComplete -_clang_codeCompleteGetDiagnostic -_clang_codeCompleteGetNumDiagnostics -_clang_constructUSR_ObjCCategory -_clang_constructUSR_ObjCClass -_clang_constructUSR_ObjCIvar -_clang_constructUSR_ObjCMethod -_clang_constructUSR_ObjCProperty -_clang_constructUSR_ObjCProtocol -_clang_createIndex -_clang_createTranslationUnit -_clang_createTranslationUnitFromSourceFile -_clang_defaultDiagnosticDisplayOptions -_clang_disposeCodeCompleteResults -_clang_disposeDiagnostic -_clang_disposeIndex -_clang_disposeString -_clang_disposeTokens -_clang_disposeTranslationUnit -_clang_enableStackTraces -_clang_equalCursors -_clang_equalLocations -_clang_formatDiagnostic -_clang_getCString -_clang_getClangVersion -_clang_getCompletionChunkCompletionString -_clang_getCompletionChunkKind -_clang_getCompletionChunkText -_clang_getCursor -_clang_getCursorDefinition -_clang_getCursorExtent -_clang_getCursorKind -_clang_getCursorKindSpelling -_clang_getCursorLanguage -_clang_getCursorLinkage -_clang_getCursorLocation -_clang_getCursorReferenced -_clang_getCursorSpelling -_clang_getCursorUSR -_clang_getDefinitionSpellingAndExtent -_clang_getDiagnostic -_clang_getDiagnosticFixIt -_clang_getDiagnosticLocation -_clang_getDiagnosticNumFixIts -_clang_getDiagnosticNumRanges -_clang_getDiagnosticRange -_clang_getDiagnosticSeverity -_clang_getDiagnosticSpelling -_clang_getFile -_clang_getFileName -_clang_getFileTime -_clang_getInclusions -_clang_getInstantiationLocation -_clang_getLocation -_clang_getNullCursor -_clang_getNullLocation -_clang_getNullRange -_clang_getNumCompletionChunks -_clang_getNumDiagnostics -_clang_getRange -_clang_getRangeEnd -_clang_getRangeStart -_clang_getTokenExtent -_clang_getTokenKind -_clang_getTokenLocation -_clang_getTokenSpelling -_clang_getTranslationUnitCursor -_clang_getTranslationUnitSpelling -_clang_isCursorDefinition -_clang_isDeclaration -_clang_isExpression -_clang_isInvalid -_clang_isPreprocessing -_clang_isReference -_clang_isStatement -_clang_isTranslationUnit -_clang_isUnexposed -_clang_setUseExternalASTGeneration -_clang_tokenize -_clang_visitChildren diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports deleted file mode 100644 index 991bb06..0000000 --- a/tools/CIndex/CIndex.exports +++ /dev/null @@ -1,81 +0,0 @@ -clang_annotateTokens -clang_codeComplete -clang_codeCompleteGetDiagnostic -clang_codeCompleteGetNumDiagnostics -clang_constructUSR_ObjCCategory -clang_constructUSR_ObjCClass -clang_constructUSR_ObjCIvar -clang_constructUSR_ObjCMethod -clang_constructUSR_ObjCProperty -clang_constructUSR_ObjCProtocol -clang_createIndex -clang_createTranslationUnit -clang_createTranslationUnitFromSourceFile -clang_defaultDiagnosticDisplayOptions -clang_disposeCodeCompleteResults -clang_disposeDiagnostic -clang_disposeIndex -clang_disposeString -clang_disposeTokens -clang_disposeTranslationUnit -clang_enableStackTraces -clang_equalCursors -clang_equalLocations -clang_formatDiagnostic -clang_getCString -clang_getClangVersion -clang_getCompletionChunkCompletionString -clang_getCompletionChunkKind -clang_getCompletionChunkText -clang_getCursor -clang_getCursorDefinition -clang_getCursorExtent -clang_getCursorKind -clang_getCursorKindSpelling -clang_getCursorLanguage -clang_getCursorLinkage -clang_getCursorLocation -clang_getCursorReferenced -clang_getCursorSpelling -clang_getCursorUSR -clang_getDefinitionSpellingAndExtent -clang_getDiagnostic -clang_getDiagnosticFixIt -clang_getDiagnosticLocation -clang_getDiagnosticNumFixIts -clang_getDiagnosticNumRanges -clang_getDiagnosticRange -clang_getDiagnosticSeverity -clang_getDiagnosticSpelling -clang_getFile -clang_getFileName -clang_getFileTime -clang_getInclusions -clang_getInstantiationLocation -clang_getLocation -clang_getNullCursor -clang_getNullLocation -clang_getNullRange -clang_getNumCompletionChunks -clang_getNumDiagnostics -clang_getRange -clang_getRangeEnd -clang_getRangeStart -clang_getTokenExtent -clang_getTokenKind -clang_getTokenLocation -clang_getTokenSpelling -clang_getTranslationUnitCursor -clang_getTranslationUnitSpelling -clang_isCursorDefinition -clang_isDeclaration -clang_isExpression -clang_isInvalid -clang_isPreprocessing -clang_isReference -clang_isStatement -clang_isTranslationUnit -clang_isUnexposed -clang_setUseExternalASTGeneration -clang_tokenize -clang_visitChildren diff --git a/tools/CIndex/CIndexCodeCompletion.cpp b/tools/CIndex/CIndexCodeCompletion.cpp deleted file mode 100644 index a21614c..0000000 --- a/tools/CIndex/CIndexCodeCompletion.cpp +++ /dev/null @@ -1,512 +0,0 @@ -//===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Clang-C Source Indexing library hooks for -// code completion. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CIndexDiagnostic.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/FileManager.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "clang/Sema/CodeCompleteConsumer.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/System/Program.h" - -#ifdef UDP_CODE_COMPLETION_LOGGER -#include "clang/Basic/Version.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" -#include <arpa/inet.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <unistd.h> -#endif - -using namespace clang; -using namespace clang::cxstring; - -extern "C" { - -enum CXCompletionChunkKind -clang_getCompletionChunkKind(CXCompletionString completion_string, - unsigned chunk_number) { - CodeCompletionString *CCStr = (CodeCompletionString *)completion_string; - if (!CCStr || chunk_number >= CCStr->size()) - return CXCompletionChunk_Text; - - switch ((*CCStr)[chunk_number].Kind) { - case CodeCompletionString::CK_TypedText: - return CXCompletionChunk_TypedText; - case CodeCompletionString::CK_Text: - return CXCompletionChunk_Text; - case CodeCompletionString::CK_Optional: - return CXCompletionChunk_Optional; - case CodeCompletionString::CK_Placeholder: - return CXCompletionChunk_Placeholder; - case CodeCompletionString::CK_Informative: - return CXCompletionChunk_Informative; - case CodeCompletionString::CK_ResultType: - return CXCompletionChunk_ResultType; - case CodeCompletionString::CK_CurrentParameter: - return CXCompletionChunk_CurrentParameter; - case CodeCompletionString::CK_LeftParen: - return CXCompletionChunk_LeftParen; - case CodeCompletionString::CK_RightParen: - return CXCompletionChunk_RightParen; - case CodeCompletionString::CK_LeftBracket: - return CXCompletionChunk_LeftBracket; - case CodeCompletionString::CK_RightBracket: - return CXCompletionChunk_RightBracket; - case CodeCompletionString::CK_LeftBrace: - return CXCompletionChunk_LeftBrace; - case CodeCompletionString::CK_RightBrace: - return CXCompletionChunk_RightBrace; - case CodeCompletionString::CK_LeftAngle: - return CXCompletionChunk_LeftAngle; - case CodeCompletionString::CK_RightAngle: - return CXCompletionChunk_RightAngle; - case CodeCompletionString::CK_Comma: - return CXCompletionChunk_Comma; - case CodeCompletionString::CK_Colon: - return CXCompletionChunk_Colon; - case CodeCompletionString::CK_SemiColon: - return CXCompletionChunk_SemiColon; - case CodeCompletionString::CK_Equal: - return CXCompletionChunk_Equal; - case CodeCompletionString::CK_HorizontalSpace: - return CXCompletionChunk_HorizontalSpace; - case CodeCompletionString::CK_VerticalSpace: - return CXCompletionChunk_VerticalSpace; - } - - // Should be unreachable, but let's be careful. - return CXCompletionChunk_Text; -} - -CXString clang_getCompletionChunkText(CXCompletionString completion_string, - unsigned chunk_number) { - CodeCompletionString *CCStr = (CodeCompletionString *)completion_string; - if (!CCStr || chunk_number >= CCStr->size()) - return createCXString(0); - - switch ((*CCStr)[chunk_number].Kind) { - case CodeCompletionString::CK_TypedText: - case CodeCompletionString::CK_Text: - case CodeCompletionString::CK_Placeholder: - case CodeCompletionString::CK_CurrentParameter: - case CodeCompletionString::CK_Informative: - case CodeCompletionString::CK_LeftParen: - case CodeCompletionString::CK_RightParen: - case CodeCompletionString::CK_LeftBracket: - case CodeCompletionString::CK_RightBracket: - case CodeCompletionString::CK_LeftBrace: - case CodeCompletionString::CK_RightBrace: - case CodeCompletionString::CK_LeftAngle: - case CodeCompletionString::CK_RightAngle: - case CodeCompletionString::CK_Comma: - case CodeCompletionString::CK_ResultType: - case CodeCompletionString::CK_Colon: - case CodeCompletionString::CK_SemiColon: - case CodeCompletionString::CK_Equal: - case CodeCompletionString::CK_HorizontalSpace: - case CodeCompletionString::CK_VerticalSpace: - return createCXString((*CCStr)[chunk_number].Text, false); - - case CodeCompletionString::CK_Optional: - // Note: treated as an empty text block. - return createCXString(""); - } - - // Should be unreachable, but let's be careful. - return createCXString(0); -} - - -CXCompletionString -clang_getCompletionChunkCompletionString(CXCompletionString completion_string, - unsigned chunk_number) { - CodeCompletionString *CCStr = (CodeCompletionString *)completion_string; - if (!CCStr || chunk_number >= CCStr->size()) - return 0; - - switch ((*CCStr)[chunk_number].Kind) { - case CodeCompletionString::CK_TypedText: - case CodeCompletionString::CK_Text: - case CodeCompletionString::CK_Placeholder: - case CodeCompletionString::CK_CurrentParameter: - case CodeCompletionString::CK_Informative: - case CodeCompletionString::CK_LeftParen: - case CodeCompletionString::CK_RightParen: - case CodeCompletionString::CK_LeftBracket: - case CodeCompletionString::CK_RightBracket: - case CodeCompletionString::CK_LeftBrace: - case CodeCompletionString::CK_RightBrace: - case CodeCompletionString::CK_LeftAngle: - case CodeCompletionString::CK_RightAngle: - case CodeCompletionString::CK_Comma: - case CodeCompletionString::CK_ResultType: - case CodeCompletionString::CK_Colon: - case CodeCompletionString::CK_SemiColon: - case CodeCompletionString::CK_Equal: - case CodeCompletionString::CK_HorizontalSpace: - case CodeCompletionString::CK_VerticalSpace: - return 0; - - case CodeCompletionString::CK_Optional: - // Note: treated as an empty text block. - return (*CCStr)[chunk_number].Optional; - } - - // Should be unreachable, but let's be careful. - return 0; -} - -unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) { - CodeCompletionString *CCStr = (CodeCompletionString *)completion_string; - return CCStr? CCStr->size() : 0; -} - -static bool ReadUnsigned(const char *&Memory, const char *MemoryEnd, - unsigned &Value) { - if (Memory + sizeof(unsigned) > MemoryEnd) - return true; - - memmove(&Value, Memory, sizeof(unsigned)); - Memory += sizeof(unsigned); - return false; -} - -/// \brief The CXCodeCompleteResults structure we allocate internally; -/// the client only sees the initial CXCodeCompleteResults structure. -struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults { - AllocatedCXCodeCompleteResults(); - ~AllocatedCXCodeCompleteResults(); - - /// \brief The memory buffer from which we parsed the results. We - /// retain this buffer because the completion strings point into it. - llvm::MemoryBuffer *Buffer; - - /// \brief Diagnostics produced while performing code completion. - llvm::SmallVector<StoredDiagnostic, 8> Diagnostics; - - /// \brief Diag object - Diagnostic Diag; - - /// \brief Language options used to adjust source locations. - LangOptions LangOpts; - - /// \brief Source manager, used for diagnostics. - SourceManager SourceMgr; - - /// \brief File manager, used for diagnostics. - FileManager FileMgr; - - /// \brief Temporary files that should be removed once we have finished - /// with the code-completion results. - std::vector<llvm::sys::Path> TemporaryFiles; -}; - -AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults() - : CXCodeCompleteResults(), Buffer(0), SourceMgr(Diag) { } - -AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() { - for (unsigned I = 0, N = NumResults; I != N; ++I) - delete (CodeCompletionString *)Results[I].CompletionString; - delete [] Results; - delete Buffer; - - for (unsigned I = 0, N = TemporaryFiles.size(); I != N; ++I) - TemporaryFiles[I].eraseFromDisk(); -} - -CXCodeCompleteResults *clang_codeComplete(CXIndex CIdx, - const char *source_filename, - int num_command_line_args, - const char **command_line_args, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - const char *complete_filename, - unsigned complete_line, - unsigned complete_column) { -#ifdef UDP_CODE_COMPLETION_LOGGER -#ifdef UDP_CODE_COMPLETION_LOGGER_PORT - const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime(); -#endif -#endif - - // The indexer, which is mainly used to determine where diagnostics go. - CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx); - - // Configure the diagnostics. - DiagnosticOptions DiagOpts; - llvm::IntrusiveRefCntPtr<Diagnostic> Diags; - Diags = CompilerInstance::createDiagnostics(DiagOpts, 0, 0); - - // The set of temporary files that we've built. - std::vector<llvm::sys::Path> TemporaryFiles; - - // Build up the arguments for invoking 'clang'. - std::vector<const char *> argv; - - // First add the complete path to the 'clang' executable. - llvm::sys::Path ClangPath = CXXIdx->getClangPath(); - argv.push_back(ClangPath.c_str()); - - // Add the '-fsyntax-only' argument so that we only perform a basic - // syntax check of the code. - argv.push_back("-fsyntax-only"); - - // Add the appropriate '-code-completion-at=file:line:column' argument - // to perform code completion, with an "-Xclang" preceding it. - std::string code_complete_at; - code_complete_at += complete_filename; - code_complete_at += ":"; - code_complete_at += llvm::utostr(complete_line); - code_complete_at += ":"; - code_complete_at += llvm::utostr(complete_column); - argv.push_back("-Xclang"); - argv.push_back("-code-completion-at"); - argv.push_back("-Xclang"); - argv.push_back(code_complete_at.c_str()); - argv.push_back("-Xclang"); - argv.push_back("-no-code-completion-debug-printer"); - argv.push_back("-Xclang"); - argv.push_back("-code-completion-macros"); - argv.push_back("-fdiagnostics-binary"); - - // Remap any unsaved files to temporary files. - std::vector<std::string> RemapArgs; - if (RemapFiles(num_unsaved_files, unsaved_files, RemapArgs, TemporaryFiles)) - return 0; - - // The pointers into the elements of RemapArgs are stable because we - // won't be adding anything to RemapArgs after this point. - for (unsigned i = 0, e = RemapArgs.size(); i != e; ++i) - argv.push_back(RemapArgs[i].c_str()); - - // Add the source file name (FIXME: later, we'll want to build temporary - // file from the buffer, or just feed the source text via standard input). - if (source_filename) - argv.push_back(source_filename); - - // Process the compiler options, stripping off '-o', '-c', '-fsyntax-only'. - for (int i = 0; i < num_command_line_args; ++i) - if (const char *arg = command_line_args[i]) { - if (strcmp(arg, "-o") == 0) { - ++i; // Also skip the matching argument. - continue; - } - if (strcmp(arg, "-emit-ast") == 0 || - strcmp(arg, "-c") == 0 || - strcmp(arg, "-fsyntax-only") == 0) { - continue; - } - - // Keep the argument. - argv.push_back(arg); - } - - // Add the null terminator. - argv.push_back(NULL); - - // Generate a temporary name for the code-completion results file. - char tmpFile[L_tmpnam]; - char *tmpFileName = tmpnam(tmpFile); - llvm::sys::Path ResultsFile(tmpFileName); - TemporaryFiles.push_back(ResultsFile); - - // Generate a temporary name for the diagnostics file. - char tmpFileResults[L_tmpnam]; - char *tmpResultsFileName = tmpnam(tmpFileResults); - llvm::sys::Path DiagnosticsFile(tmpResultsFileName); - TemporaryFiles.push_back(DiagnosticsFile); - - // Invoke 'clang'. - llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null - // on Unix or NUL (Windows). - std::string ErrMsg; - const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile, - &DiagnosticsFile, 0 }; - llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL, - /* redirects */ &Redirects[0], - /* secondsToWait */ 0, - /* memoryLimits */ 0, &ErrMsg); - - if (!ErrMsg.empty()) { - std::string AllArgs; - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - AllArgs += ' '; - if (*I) - AllArgs += *I; - } - - Diags->Report(diag::err_fe_invoking) << AllArgs << ErrMsg; - } - - // Parse the resulting source file to find code-completion results. - using llvm::MemoryBuffer; - using llvm::StringRef; - AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults; - Results->Results = 0; - Results->NumResults = 0; - Results->Buffer = 0; - // FIXME: Set Results->LangOpts! - if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) { - llvm::SmallVector<CXCompletionResult, 4> CompletionResults; - StringRef Buffer = F->getBuffer(); - for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size(); - Str < StrEnd;) { - unsigned KindValue; - if (ReadUnsigned(Str, StrEnd, KindValue)) - break; - - CodeCompletionString *CCStr - = CodeCompletionString::Deserialize(Str, StrEnd); - if (!CCStr) - continue; - - if (!CCStr->empty()) { - // Vend the code-completion result to the caller. - CXCompletionResult Result; - Result.CursorKind = (CXCursorKind)KindValue; - Result.CompletionString = CCStr; - CompletionResults.push_back(Result); - } - }; - - // Allocate the results. - Results->Results = new CXCompletionResult [CompletionResults.size()]; - Results->NumResults = CompletionResults.size(); - memcpy(Results->Results, CompletionResults.data(), - CompletionResults.size() * sizeof(CXCompletionResult)); - Results->Buffer = F; - } - - LoadSerializedDiagnostics(DiagnosticsFile, num_unsaved_files, unsaved_files, - Results->FileMgr, Results->SourceMgr, - Results->Diagnostics); - - // Make sure we delete temporary files when the code-completion results are - // destroyed. - Results->TemporaryFiles.swap(TemporaryFiles); - -#ifdef UDP_CODE_COMPLETION_LOGGER -#ifdef UDP_CODE_COMPLETION_LOGGER_PORT - const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime(); - llvm::SmallString<256> LogResult; - llvm::raw_svector_ostream os(LogResult); - - // Figure out the language and whether or not it uses PCH. - const char *lang = 0; - bool usesPCH = false; - - for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end(); - I != E; ++I) { - if (*I == 0) - continue; - if (strcmp(*I, "-x") == 0) { - if (I + 1 != E) { - lang = *(++I); - continue; - } - } - else if (strcmp(*I, "-include") == 0) { - if (I+1 != E) { - const char *arg = *(++I); - llvm::SmallString<512> pchName; - { - llvm::raw_svector_ostream os(pchName); - os << arg << ".pth"; - } - pchName.push_back('\0'); - struct stat stat_results; - if (stat(pchName.data(), &stat_results) == 0) - usesPCH = true; - continue; - } - } - } - - os << "{ "; - os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime()); - os << ", \"numRes\": " << Results->NumResults; - os << ", \"diags\": " << Results->Diagnostics.size(); - os << ", \"pch\": " << (usesPCH ? "true" : "false"); - os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"'; - const char *name = getlogin(); - os << ", \"user\": \"" << (name ? name : "unknown") << '"'; - os << ", \"clangVer\": \"" << getClangFullVersion() << '"'; - os << " }"; - - llvm::StringRef res = os.str(); - if (res.size() > 0) { - do { - // Setup the UDP socket. - struct sockaddr_in servaddr; - bzero(&servaddr, sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT); - if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER, - &servaddr.sin_addr) <= 0) - break; - - int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd < 0) - break; - - sendto(sockfd, res.data(), res.size(), 0, - (struct sockaddr *)&servaddr, sizeof(servaddr)); - close(sockfd); - } - while (false); - } -#endif -#endif - return Results; -} - -void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) { - if (!ResultsIn) - return; - - AllocatedCXCodeCompleteResults *Results - = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); - delete Results; -} - -unsigned -clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) { - AllocatedCXCodeCompleteResults *Results - = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); - if (!Results) - return 0; - - return Results->Diagnostics.size(); -} - -CXDiagnostic -clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn, - unsigned Index) { - AllocatedCXCodeCompleteResults *Results - = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn); - if (!Results || Index >= Results->Diagnostics.size()) - return 0; - - return new CXStoredDiagnostic(Results->Diagnostics[Index], Results->LangOpts); -} - - -} // end extern "C" diff --git a/tools/CIndex/CIndexDiagnostic.cpp b/tools/CIndex/CIndexDiagnostic.cpp deleted file mode 100644 index 3db37b9..0000000 --- a/tools/CIndex/CIndexDiagnostic.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/*===-- CIndexDiagnostics.cpp - Diagnostics C Interface ---------*- C++ -*-===*\ -|* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* Implements the diagnostic functions of the Clang C interface. *| -|* *| -\*===----------------------------------------------------------------------===*/ -#include "CIndexDiagnostic.h" -#include "CIndexer.h" -#include "CXSourceLocation.h" - -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/FrontendDiagnostic.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" - -using namespace clang; -using namespace clang::cxloc; -using namespace clang::cxstring; -using namespace llvm; - -//----------------------------------------------------------------------------- -// C Interface Routines -//----------------------------------------------------------------------------- -extern "C" { - -unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit); - return CXXUnit? CXXUnit->stored_diag_size() : 0; -} - -CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) { - ASTUnit *CXXUnit = static_cast<ASTUnit *>(Unit); - if (!CXXUnit || Index >= CXXUnit->stored_diag_size()) - return 0; - - return new CXStoredDiagnostic(CXXUnit->stored_diag_begin()[Index], - CXXUnit->getASTContext().getLangOptions()); -} - -void clang_disposeDiagnostic(CXDiagnostic Diagnostic) { - CXStoredDiagnostic *Stored = static_cast<CXStoredDiagnostic *>(Diagnostic); - delete Stored; -} - -CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) { - if (!Diagnostic) - return createCXString(""); - - CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic); - - // Ignore diagnostics that should be ignored. - if (Severity == CXDiagnostic_Ignored) - return createCXString(""); - - llvm::SmallString<256> Str; - llvm::raw_svector_ostream Out(Str); - - if (Options & CXDiagnostic_DisplaySourceLocation) { - // Print source location (file:line), along with optional column - // and source ranges. - CXFile File; - unsigned Line, Column; - clang_getInstantiationLocation(clang_getDiagnosticLocation(Diagnostic), - &File, &Line, &Column, 0); - if (File) { - CXString FName = clang_getFileName(File); - Out << clang_getCString(FName) << ":" << Line << ":"; - clang_disposeString(FName); - if (Options & CXDiagnostic_DisplayColumn) - Out << Column << ":"; - - if (Options & CXDiagnostic_DisplaySourceRanges) { - unsigned N = clang_getDiagnosticNumRanges(Diagnostic); - bool PrintedRange = false; - for (unsigned I = 0; I != N; ++I) { - CXFile StartFile, EndFile; - CXSourceRange Range = clang_getDiagnosticRange(Diagnostic, I); - - unsigned StartLine, StartColumn, EndLine, EndColumn; - clang_getInstantiationLocation(clang_getRangeStart(Range), - &StartFile, &StartLine, &StartColumn, - 0); - clang_getInstantiationLocation(clang_getRangeEnd(Range), - &EndFile, &EndLine, &EndColumn, 0); - - if (StartFile != EndFile || StartFile != File) - continue; - - Out << "{" << StartLine << ":" << StartColumn << "-" - << EndLine << ":" << EndColumn << "}"; - PrintedRange = true; - } - if (PrintedRange) - Out << ":"; - } - } - - Out << " "; - } - - /* Print warning/error/etc. */ - switch (Severity) { - case CXDiagnostic_Ignored: assert(0 && "impossible"); break; - case CXDiagnostic_Note: Out << "note: "; break; - case CXDiagnostic_Warning: Out << "warning: "; break; - case CXDiagnostic_Error: Out << "error: "; break; - case CXDiagnostic_Fatal: Out << "fatal error: "; break; - } - - CXString Text = clang_getDiagnosticSpelling(Diagnostic); - if (clang_getCString(Text)) - Out << clang_getCString(Text); - else - Out << "<no diagnostic text>"; - clang_disposeString(Text); - return createCXString(Out.str(), true); -} - -unsigned clang_defaultDiagnosticDisplayOptions() { - return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn; -} - -enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag) - return CXDiagnostic_Ignored; - - switch (StoredDiag->Diag.getLevel()) { - case Diagnostic::Ignored: return CXDiagnostic_Ignored; - case Diagnostic::Note: return CXDiagnostic_Note; - case Diagnostic::Warning: return CXDiagnostic_Warning; - case Diagnostic::Error: return CXDiagnostic_Error; - case Diagnostic::Fatal: return CXDiagnostic_Fatal; - } - - llvm_unreachable("Invalid diagnostic level"); - return CXDiagnostic_Ignored; -} - -CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) - return clang_getNullLocation(); - - return translateSourceLocation(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - StoredDiag->Diag.getLocation()); -} - -CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag) - return createCXString(""); - - return createCXString(StoredDiag->Diag.getMessage(), false); -} - -unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || StoredDiag->Diag.getLocation().isInvalid()) - return 0; - - return StoredDiag->Diag.range_size(); -} - -CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag || Range >= StoredDiag->Diag.range_size() || - StoredDiag->Diag.getLocation().isInvalid()) - return clang_getNullRange(); - - return translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - StoredDiag->Diag.range_begin()[Range]); -} - -unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) { - CXStoredDiagnostic *StoredDiag = static_cast<CXStoredDiagnostic *>(Diag); - if (!StoredDiag) - return 0; - - return StoredDiag->Diag.fixit_size(); -} - -CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, unsigned FixIt, - CXSourceRange *ReplacementRange) { - CXStoredDiagnostic *StoredDiag - = static_cast<CXStoredDiagnostic *>(Diagnostic); - if (!StoredDiag || FixIt >= StoredDiag->Diag.fixit_size() || - StoredDiag->Diag.getLocation().isInvalid()) { - if (ReplacementRange) - *ReplacementRange = clang_getNullRange(); - - return createCXString(""); - } - - const FixItHint &Hint = StoredDiag->Diag.fixit_begin()[FixIt]; - if (ReplacementRange) { - if (Hint.RemoveRange.isInvalid()) { - // Create an empty range that refers to a single source - // location (which is the insertion point). - CXSourceRange Range = { - { (void *)&StoredDiag->Diag.getLocation().getManager(), - (void *)&StoredDiag->LangOpts }, - Hint.InsertionLoc.getRawEncoding(), - Hint.InsertionLoc.getRawEncoding() - }; - - *ReplacementRange = Range; - } else { - // Create a range that covers the entire replacement (or - // removal) range, adjusting the end of the range to point to - // the end of the token. - *ReplacementRange - = translateSourceRange(StoredDiag->Diag.getLocation().getManager(), - StoredDiag->LangOpts, - Hint.RemoveRange); - } - } - - return createCXString(Hint.CodeToInsert); -} - -} // end extern "C" - -void clang::LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - FileManager &FileMgr, - SourceManager &SourceMgr, - SmallVectorImpl<StoredDiagnostic> &Diags) { - using llvm::MemoryBuffer; - using llvm::StringRef; - MemoryBuffer *F = MemoryBuffer::getFile(DiagnosticsPath.c_str()); - if (!F) - return; - - // Enter the unsaved files into the file manager. - for (unsigned I = 0; I != num_unsaved_files; ++I) { - const FileEntry *File = FileMgr.getVirtualFile(unsaved_files[I].Filename, - unsaved_files[I].Length, - 0); - if (!File) { - // FIXME: Hard to localize when we have no diagnostics engine! - Diags.push_back(StoredDiagnostic(Diagnostic::Fatal, - (Twine("could not remap from missing file ") + - unsaved_files[I].Filename).str())); - delete F; - return; - } - - MemoryBuffer *Buffer - = MemoryBuffer::getMemBuffer(unsaved_files[I].Contents, - unsaved_files[I].Contents + unsaved_files[I].Length); - if (!Buffer) { - delete F; - return; - } - - SourceMgr.overrideFileContents(File, Buffer); - SourceMgr.createFileID(File, SourceLocation(), SrcMgr::C_User); - } - - // Parse the diagnostics, emitting them one by one until we've - // exhausted the data. - StringRef Buffer = F->getBuffer(); - const char *Memory = Buffer.data(), *MemoryEnd = Memory + Buffer.size(); - while (Memory != MemoryEnd) { - StoredDiagnostic Stored = StoredDiagnostic::Deserialize(FileMgr, SourceMgr, - Memory, MemoryEnd); - if (!Stored) - break; - - Diags.push_back(Stored); - } - delete F; -} diff --git a/tools/CIndex/CIndexDiagnostic.h b/tools/CIndex/CIndexDiagnostic.h deleted file mode 100644 index 919c21c..0000000 --- a/tools/CIndex/CIndexDiagnostic.h +++ /dev/null @@ -1,53 +0,0 @@ -/*===-- CIndexDiagnostic.h - Diagnostics C Interface ------------*- C++ -*-===*\ -|* *| -|* The LLVM Compiler Infrastructure *| -|* *| -|* This file is distributed under the University of Illinois Open Source *| -|* License. See LICENSE.TXT for details. *| -|* *| -|*===----------------------------------------------------------------------===*| -|* *| -|* Implements the diagnostic functions of the Clang C interface. *| -|* *| -\*===----------------------------------------------------------------------===*/ -#ifndef LLVM_CLANG_CINDEX_DIAGNOSTIC_H -#define LLVM_CLANG_CINDEX_DIAGNOSTIC_H - -struct CXUnsavedFile; - -namespace llvm { -template<typename T> class SmallVectorImpl; -namespace sys { class Path; } -} - -namespace clang { - -class Diagnostic; -class FileManager; -class LangOptions; -class Preprocessor; -class StoredDiagnostic; -class SourceManager; - -/// \brief The storage behind a CXDiagnostic -struct CXStoredDiagnostic { - const StoredDiagnostic &Diag; - const LangOptions &LangOpts; - - CXStoredDiagnostic(const StoredDiagnostic &Diag, - const LangOptions &LangOpts) - : Diag(Diag), LangOpts(LangOpts) { } -}; - -/// \brief Given the path to a file that contains binary, serialized -/// diagnostics produced by Clang, load those diagnostics. -void LoadSerializedDiagnostics(const llvm::sys::Path &DiagnosticsPath, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - FileManager &FileMgr, - SourceManager &SourceMgr, - llvm::SmallVectorImpl<StoredDiagnostic> &Diags); - -} // end namespace clang - -#endif // LLVM_CLANG_CINDEX_DIAGNOSTIC_H diff --git a/tools/CIndex/CIndexInclusionStack.cpp b/tools/CIndex/CIndexInclusionStack.cpp deleted file mode 100644 index e863239..0000000 --- a/tools/CIndex/CIndexInclusionStack.cpp +++ /dev/null @@ -1,67 +0,0 @@ -//===- CIndexInclusionStack.cpp - Clang-C Source Indexing Library ---------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines a callback mechanism for clients to get the inclusion -// stack from a translation unit. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXSourceLocation.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/Frontend/ASTUnit.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -extern "C" { -void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB, - CXClientData clientData) { - - ASTUnit *CXXUnit = static_cast<ASTUnit *>(TU); - SourceManager &SM = CXXUnit->getSourceManager(); - ASTContext &Ctx = CXXUnit->getASTContext(); - - llvm::SmallVector<CXSourceLocation, 10> InclusionStack; - unsigned i = SM.sloc_loaded_entry_size(); - unsigned n = SM.sloc_entry_size(); - - // In the case where all the SLocEntries are in an external source, traverse - // those SLocEntries as well. This is the case where we are looking - // at the inclusion stack of an AST/PCH file. - if (i >= n) - i = 0; - - for ( ; i < n ; ++i) { - - const SrcMgr::SLocEntry &SL = SM.getSLocEntry(i); - - if (!SL.isFile()) - continue; - - const SrcMgr::FileInfo &FI = SL.getFile(); - if (!FI.getContentCache()->Entry) - continue; - - // Build the inclusion stack. - SourceLocation L = FI.getIncludeLoc(); - InclusionStack.clear(); - while (L.isValid()) { - PresumedLoc PLoc = SM.getPresumedLoc(L); - InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L)); - L = PLoc.getIncludeLoc(); - } - - // Callback to the client. - // FIXME: We should have a function to construct CXFiles. - CB((CXFile) FI.getContentCache()->Entry, - InclusionStack.data(), InclusionStack.size(), clientData); - } -} -} // end extern C diff --git a/tools/CIndex/CIndexUSRs.cpp b/tools/CIndex/CIndexUSRs.cpp deleted file mode 100644 index 58870b9..0000000 --- a/tools/CIndex/CIndexUSRs.cpp +++ /dev/null @@ -1,469 +0,0 @@ -//===- CIndexUSR.cpp - Clang-C Source Indexing Library --------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the generation and use of USRs from CXEntities. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" -#include "CXCursor.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Lex/PreprocessingRecord.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/raw_ostream.h" - -using namespace clang; -using namespace clang::cxstring; - -//===----------------------------------------------------------------------===// -// USR generation. -//===----------------------------------------------------------------------===// - -namespace { -class USRGenerator : public DeclVisitor<USRGenerator> { - llvm::raw_ostream &Out; - bool IgnoreResults; - ASTUnit *AU; -public: - USRGenerator(ASTUnit *au, llvm::raw_ostream &out) - : Out(out), IgnoreResults(false), AU(au) {} - - bool ignoreResults() const { return IgnoreResults; } - - // Visitation methods from generating USRs from AST elements. - void VisitBlockDecl(BlockDecl *D); - void VisitDeclContext(DeclContext *D); - void VisitFieldDecl(FieldDecl *D); - void VisitFunctionDecl(FunctionDecl *D); - void VisitNamedDecl(NamedDecl *D); - void VisitNamespaceDecl(NamespaceDecl *D); - void VisitObjCClassDecl(ObjCClassDecl *CD); - void VisitObjCContainerDecl(ObjCContainerDecl *CD); - void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *P); - void VisitObjCMethodDecl(ObjCMethodDecl *MD); - void VisitObjCPropertyDecl(ObjCPropertyDecl *D); - void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); - void VisitTagDecl(TagDecl *D); - void VisitTypedefDecl(TypedefDecl *D); - void VisitVarDecl(VarDecl *D); - - /// Generate the string component containing the location of the - /// declaration. - void GenLoc(const Decl *D); - - /// String generation methods used both by the visitation methods - /// and from other clients that want to directly generate USRs. These - /// methods do not construct complete USRs (which incorporate the parents - /// of an AST element), but only the fragments concerning the AST element - /// itself. - - /// Generate a USR fragment for a named declaration. This does - /// not include the USR component for the parent. - void GenNamedDecl(llvm::StringRef name); - - /// Generate a USR for an Objective-C class. - void GenObjCClass(llvm::StringRef cls); - /// Generate a USR for an Objective-C class category. - void GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat); - /// Generate a USR fragment for an Objective-C instance variable. The - /// complete USR can be created by concatenating the USR for the - /// encompassing class with this USR fragment. - void GenObjCIvar(llvm::StringRef ivar); - /// Generate a USR fragment for an Objective-C method. - void GenObjCMethod(llvm::StringRef sel, bool isInstanceMethod); - /// Generate a USR fragment for an Objective-C property. - void GenObjCProperty(llvm::StringRef prop); - /// Generate a USR for an Objective-C protocol. - void GenObjCProtocol(llvm::StringRef prot); -}; - -class StringUSRGenerator { -private: - llvm::SmallString<1024> StrBuf; - llvm::raw_svector_ostream Out; - USRGenerator UG; -public: - StringUSRGenerator(const CXCursor *C = 0) - : Out(StrBuf), UG(C ? cxcursor::getCursorASTUnit(*C) : 0, Out) { - // Add the USR space prefix. - Out << "c:"; - } - - llvm::StringRef str() { - return Out.str(); - } - - USRGenerator* operator->() { return &UG; } - - template <typename T> - llvm::raw_svector_ostream &operator<<(const T &x) { - Out << x; - return Out; - } -}; - -} // end anonymous namespace - -//===----------------------------------------------------------------------===// -// Generating USRs from ASTS. -//===----------------------------------------------------------------------===// - -void USRGenerator::VisitBlockDecl(BlockDecl *D) { - VisitDeclContext(D->getDeclContext()); - // FIXME: Better support for anonymous blocks. - Out << "@B@anon"; -} - -void USRGenerator::VisitDeclContext(DeclContext *DC) { - if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) - Visit(D); -} - -void USRGenerator::VisitFieldDecl(FieldDecl *D) { - const std::string &s = D->getNameAsString(); - if (s.empty()) { - // Bit fields can be anonymous. - IgnoreResults = true; - return; - } - VisitDeclContext(D->getDeclContext()); - Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@") << s; -} - -void USRGenerator::VisitFunctionDecl(FunctionDecl *D) { - VisitDeclContext(D->getDeclContext()); - Out << "@F@" << D; -} - -void USRGenerator::VisitNamedDecl(NamedDecl *D) { - VisitDeclContext(D->getDeclContext()); - const std::string &s = D->getNameAsString(); - // The string can be empty if the declaration has no name; e.g., it is - // the ParmDecl with no name for declaration of a function pointer type, e.g.: - // void (*f)(void *); - // In this case, don't generate a USR. - if (s.empty()) - IgnoreResults = true; - else - GenNamedDecl(s); -} - -void USRGenerator::VisitVarDecl(VarDecl *D) { - // VarDecls can be declared 'extern' within a function or method body, - // but their enclosing DeclContext is the function, not the TU. We need - // to check the storage class to correctly generate the USR. - if (!D->hasExternalStorage()) - VisitDeclContext(D->getDeclContext()); - - const std::string &s = D->getNameAsString(); - // The string can be empty if the declaration has no name; e.g., it is - // the ParmDecl with no name for declaration of a function pointer type, e.g.: - // void (*f)(void *); - // In this case, don't generate a USR. - if (s.empty()) - IgnoreResults = true; - else - GenNamedDecl(s); -} - -void USRGenerator::VisitNamespaceDecl(NamespaceDecl *D) { - VisitDeclContext(D->getDeclContext()); - Out << "@N@" << D; -} - -void USRGenerator::VisitObjCMethodDecl(ObjCMethodDecl *D) { - Visit(cast<Decl>(D->getDeclContext())); - GenObjCMethod(DeclarationName(D->getSelector()).getAsString(), - D->isInstanceMethod()); -} - -void USRGenerator::VisitObjCClassDecl(ObjCClassDecl *D) { - // FIXME: @class declarations can refer to multiple classes. We need - // to be able to traverse these. - IgnoreResults = true; -} - -void USRGenerator::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) { - // FIXME: @protocol declarations can refer to multiple protocols. We need - // to be able to traverse these. - IgnoreResults = true; -} - -void USRGenerator::VisitObjCContainerDecl(ObjCContainerDecl *D) { - switch (D->getKind()) { - default: - assert(false && "Invalid ObjC container."); - case Decl::ObjCInterface: - case Decl::ObjCImplementation: - GenObjCClass(D->getName()); - break; - case Decl::ObjCCategory: { - ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D); - ObjCInterfaceDecl *ID = CD->getClassInterface(); - if (!ID) { - // Handle invalid code where the @interface might not - // have been specified. - // FIXME: We should be able to generate this USR even if the - // @interface isn't available. - IgnoreResults = true; - return; - } - GenObjCCategory(ID->getName(), CD->getName()); - break; - } - case Decl::ObjCCategoryImpl: { - ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D); - ObjCInterfaceDecl *ID = CD->getClassInterface(); - if (!ID) { - // Handle invalid code where the @interface might not - // have been specified. - // FIXME: We should be able to generate this USR even if the - // @interface isn't available. - IgnoreResults = true; - return; - } - GenObjCCategory(ID->getName(), CD->getName()); - break; - } - case Decl::ObjCProtocol: - GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName()); - break; - } -} - -void USRGenerator::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { - Visit(cast<Decl>(D->getDeclContext())); - GenObjCProperty(D->getName()); -} - -void USRGenerator::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { - if (ObjCPropertyDecl *PD = D->getPropertyDecl()) { - VisitObjCPropertyDecl(PD); - return; - } - - IgnoreResults = true; -} - -void USRGenerator::VisitTagDecl(TagDecl *D) { - D = D->getCanonicalDecl(); - VisitDeclContext(D->getDeclContext()); - switch (D->getTagKind()) { - case TagDecl::TK_struct: Out << "@S"; break; - case TagDecl::TK_class: Out << "@C"; break; - case TagDecl::TK_union: Out << "@U"; break; - case TagDecl::TK_enum: Out << "@E"; break; - } - - const std::string &s = D->getNameAsString(); - const TypedefDecl *TD = 0; - if (s.empty()) { - TD = D->getTypedefForAnonDecl(); - Out << (TD ? 'A' : 'a'); - } - - // Add the location of the tag decl to handle resolution across - // translation units. - if (D->getLinkage() == NoLinkage) { - Out << '@'; - GenLoc(D); - if (IgnoreResults) - return; - } - - if (s.empty()) { - if (TD) - Out << '@' << TD; - } - else - Out << '@' << s; -} - -void USRGenerator::VisitTypedefDecl(TypedefDecl *D) { - DeclContext *DC = D->getDeclContext(); - if (NamedDecl *DCN = dyn_cast<NamedDecl>(DC)) - Visit(DCN); - Out << "@T@"; - if (D->getLinkage() == NoLinkage) { - GenLoc(D); - if (IgnoreResults) - return; - Out << '@'; - } - Out << D->getName(); -} - -void USRGenerator::GenLoc(const Decl *D) { - const SourceManager &SM = AU->getSourceManager(); - SourceLocation L = D->getLocStart(); - if (L.isInvalid()) { - IgnoreResults = true; - return; - } - L = SM.getInstantiationLoc(L); - const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(L); - const FileEntry *FE = SM.getFileEntryForID(Decomposed.first); - if (FE) { - llvm::sys::Path P(FE->getName()); - Out << P.getLast(); - } - else { - // This case really isn't interesting. - IgnoreResults = true; - return; - } - Out << '@' - << SM.getLineNumber(Decomposed.first, Decomposed.second) << ':' - << SM.getColumnNumber(Decomposed.first, Decomposed.second); -} - -//===----------------------------------------------------------------------===// -// General purpose USR generation methods. -//===----------------------------------------------------------------------===// - -void USRGenerator::GenNamedDecl(llvm::StringRef name) { - Out << "@" << name; -} - -void USRGenerator::GenObjCClass(llvm::StringRef cls) { - Out << "objc(cs)" << cls; -} - -void USRGenerator::GenObjCCategory(llvm::StringRef cls, llvm::StringRef cat) { - Out << "objc(cy)" << cls << '@' << cat; -} - -void USRGenerator::GenObjCIvar(llvm::StringRef ivar) { - GenNamedDecl(ivar); -} - -void USRGenerator::GenObjCMethod(llvm::StringRef meth, bool isInstanceMethod) { - Out << (isInstanceMethod ? "(im)" : "(cm)") << meth; -} - -void USRGenerator::GenObjCProperty(llvm::StringRef prop) { - Out << "(py)" << prop; -} - -void USRGenerator::GenObjCProtocol(llvm::StringRef prot) { - Out << "objc(pl)" << prot; -} - -//===----------------------------------------------------------------------===// -// API hooks. -//===----------------------------------------------------------------------===// - -static inline llvm::StringRef extractUSRSuffix(llvm::StringRef s) { - return s.startswith("c:") ? s.substr(2) : ""; -} - -static CXString getDeclCursorUSR(const CXCursor &C) { - Decl *D = cxcursor::getCursorDecl(C); - - // Don't generate USRs for things with invalid locations. - if (!D || D->getLocStart().isInvalid()) - return createCXString(""); - - // Check if the cursor has 'NoLinkage'. - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - switch (ND->getLinkage()) { - case ExternalLinkage: - // Generate USRs for all entities with external linkage. - break; - case NoLinkage: - // We allow enums, typedefs, and structs that have no linkage to - // have USRs that are anchored to the file they were defined in - // (e.g., the header). This is a little gross, but in principal - // enums/anonymous structs/etc. defined in a common header file - // are referred to across multiple translation units. - if (isa<TagDecl>(ND) || isa<TypedefDecl>(ND) || - isa<EnumConstantDecl>(ND) || isa<FieldDecl>(ND)) - break; - // Fall-through. - case InternalLinkage: - case UniqueExternalLinkage: - return createCXString(""); - } - - StringUSRGenerator SUG(&C); - SUG->Visit(D); - - if (SUG->ignoreResults()) - return createCXString(""); - - // For development testing. - // assert(SUG.str().size() > 2); - - // Return a copy of the string that must be disposed by the caller. - return createCXString(SUG.str(), true); -} - -extern "C" { - -CXString clang_getCursorUSR(CXCursor C) { - const CXCursorKind &K = clang_getCursorKind(C); - - if (clang_isDeclaration(K)) - return getDeclCursorUSR(C); - - if (K == CXCursor_MacroDefinition) { - StringUSRGenerator SUG(&C); - SUG << "macro@" - << cxcursor::getCursorMacroDefinition(C)->getName()->getNameStart(); - return createCXString(SUG.str(), true); - } - - return createCXString(""); -} - -CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) { - StringUSRGenerator SUG; - SUG << extractUSRSuffix(clang_getCString(classUSR)); - SUG->GenObjCIvar(name); - return createCXString(SUG.str(), true); -} - -CXString clang_constructUSR_ObjCMethod(const char *name, - unsigned isInstanceMethod, - CXString classUSR) { - StringUSRGenerator SUG; - SUG << extractUSRSuffix(clang_getCString(classUSR)); - SUG->GenObjCMethod(name, isInstanceMethod); - return createCXString(SUG.str(), true); -} - -CXString clang_constructUSR_ObjCClass(const char *name) { - StringUSRGenerator SUG; - SUG->GenObjCClass(name); - return createCXString(SUG.str(), true); -} - -CXString clang_constructUSR_ObjCProtocol(const char *name) { - StringUSRGenerator SUG; - SUG->GenObjCProtocol(name); - return createCXString(SUG.str(), true); -} - -CXString clang_constructUSR_ObjCCategory(const char *class_name, - const char *category_name) { - StringUSRGenerator SUG; - SUG->GenObjCCategory(class_name, category_name); - return createCXString(SUG.str(), true); -} - -CXString clang_constructUSR_ObjCProperty(const char *property, - CXString classUSR) { - StringUSRGenerator SUG; - SUG << extractUSRSuffix(clang_getCString(classUSR)); - SUG->GenObjCProperty(property); - return createCXString(SUG.str(), true); -} - -} // end extern "C" diff --git a/tools/CIndex/CIndexer.cpp b/tools/CIndex/CIndexer.cpp deleted file mode 100644 index d5131ff..0000000 --- a/tools/CIndex/CIndexer.cpp +++ /dev/null @@ -1,154 +0,0 @@ -//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Clang-C Source Indexing library. -// -//===----------------------------------------------------------------------===// - -#include "CIndexer.h" - -#include "clang/AST/Decl.h" -#include "clang/AST/DeclVisitor.h" -#include "clang/AST/StmtVisitor.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "clang/Basic/Version.h" -#include "clang/Sema/CodeCompleteConsumer.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Config/config.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Program.h" - -#include <cstdio> -#include <vector> -#include <sstream> - -#ifdef LLVM_ON_WIN32 -#include <windows.h> -#else -#include <dlfcn.h> -#endif - -using namespace clang; - -const llvm::sys::Path& CIndexer::getClangPath() { - // Did we already compute the path? - if (!ClangPath.empty()) - return ClangPath; - - // Find the location where this library lives (libCIndex.dylib). -#ifdef LLVM_ON_WIN32 - MEMORY_BASIC_INFORMATION mbi; - char path[MAX_PATH]; - VirtualQuery((void *)(uintptr_t)clang_createTranslationUnit, &mbi, - sizeof(mbi)); - GetModuleFileNameA((HINSTANCE)mbi.AllocationBase, path, MAX_PATH); - - llvm::sys::Path CIndexPath(path); - - CIndexPath.eraseComponent(); - CIndexPath.appendComponent("clang"); - CIndexPath.appendSuffix("exe"); - CIndexPath.makeAbsolute(); -#else - // This silly cast below avoids a C++ warning. - Dl_info info; - if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0) - assert(0 && "Call to dladdr() failed"); - - llvm::sys::Path CIndexPath(info.dli_fname); - - // We now have the CIndex directory, locate clang relative to it. - CIndexPath.eraseComponent(); - CIndexPath.appendComponent(".."); - CIndexPath.appendComponent("bin"); - CIndexPath.appendComponent("clang"); -#endif - - // Cache our result. - ClangPath = CIndexPath; - return ClangPath; -} - -std::string CIndexer::getClangResourcesPath() { - llvm::sys::Path P = getClangPath(); - - if (!P.empty()) { - P.eraseComponent(); // Remove /clang from foo/bin/clang - P.eraseComponent(); // Remove /bin from foo/bin - - // Get foo/lib/clang/<version>/include - P.appendComponent("lib"); - P.appendComponent("clang"); - P.appendComponent(CLANG_VERSION_STRING); - } - - return P.str(); -} - -static llvm::sys::Path GetTemporaryPath() { - // FIXME: This is lame; sys::Path should provide this function (in particular, - // it should know how to find the temporary files dir). - std::string Error; - const char *TmpDir = ::getenv("TMPDIR"); - if (!TmpDir) - TmpDir = ::getenv("TEMP"); - if (!TmpDir) - TmpDir = ::getenv("TMP"); - if (!TmpDir) - TmpDir = "/tmp"; - llvm::sys::Path P(TmpDir); - P.appendComponent("remap"); - if (P.makeUnique(false, &Error)) - return llvm::sys::Path(""); - - // FIXME: Grumble, makeUnique sometimes leaves the file around!? PR3837. - P.eraseFromDisk(false, 0); - - return P; -} - -bool clang::RemapFiles(unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - std::vector<std::string> &RemapArgs, - std::vector<llvm::sys::Path> &TemporaryFiles) { - for (unsigned i = 0; i != num_unsaved_files; ++i) { - // Write the contents of this unsaved file into the temporary file. - llvm::sys::Path SavedFile(GetTemporaryPath()); - if (SavedFile.empty()) - return true; - - std::string ErrorInfo; - llvm::raw_fd_ostream OS(SavedFile.c_str(), ErrorInfo); - if (!ErrorInfo.empty()) - return true; - - OS.write(unsaved_files[i].Contents, unsaved_files[i].Length); - OS.close(); - if (OS.has_error()) { - SavedFile.eraseFromDisk(); - return true; - } - - // Remap the file. - std::string RemapArg = unsaved_files[i].Filename; - RemapArg += ';'; - RemapArg += SavedFile.str(); - RemapArgs.push_back("-Xclang"); - RemapArgs.push_back("-remap-file"); - RemapArgs.push_back("-Xclang"); - RemapArgs.push_back(RemapArg); - TemporaryFiles.push_back(SavedFile); - } - - return false; -} - diff --git a/tools/CIndex/CIndexer.h b/tools/CIndex/CIndexer.h deleted file mode 100644 index 31bf779..0000000 --- a/tools/CIndex/CIndexer.h +++ /dev/null @@ -1,78 +0,0 @@ -//===- CIndexer.h - Clang-C Source Indexing Library -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines CIndexer, a subclass of Indexer that provides extra -// functionality needed by the CIndex library. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CINDEXER_H -#define LLVM_CLANG_CINDEXER_H - -#include "clang-c/Index.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/System/Path.h" -#include <vector> - -namespace clang { -namespace cxstring { - CXString createCXString(const char *String, bool DupString = false); - CXString createCXString(llvm::StringRef String, bool DupString = true); -} -} - -class CIndexer { - bool UseExternalASTGeneration; - bool OnlyLocalDecls; - bool DisplayDiagnostics; - - llvm::sys::Path ClangPath; - -public: - CIndexer() - : UseExternalASTGeneration(false), OnlyLocalDecls(false), - DisplayDiagnostics(false) { } - - /// \brief Whether we only want to see "local" declarations (that did not - /// come from a previous precompiled header). If false, we want to see all - /// declarations. - bool getOnlyLocalDecls() const { return OnlyLocalDecls; } - void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; } - - bool getDisplayDiagnostics() const { return DisplayDiagnostics; } - void setDisplayDiagnostics(bool Display = true) { - DisplayDiagnostics = Display; - } - - bool getUseExternalASTGeneration() const { return UseExternalASTGeneration; } - void setUseExternalASTGeneration(bool Value) { - UseExternalASTGeneration = Value; - } - - /// \brief Get the path of the clang binary. - const llvm::sys::Path& getClangPath(); - - /// \brief Get the path of the clang resource files. - std::string getClangResourcesPath(); -}; - -namespace clang { - /** - * \brief Given a set of "unsaved" files, create temporary files and - * construct the clang -cc1 argument list needed to perform the remapping. - * - * \returns true if an error occurred. - */ - bool RemapFiles(unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - std::vector<std::string> &RemapArgs, - std::vector<llvm::sys::Path> &TemporaryFiles); -} - -#endif diff --git a/tools/CIndex/CMakeLists.txt b/tools/CIndex/CMakeLists.txt deleted file mode 100644 index 609719e..0000000 --- a/tools/CIndex/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -set(SHARED_LIBRARY TRUE) - -set(LLVM_NO_RTTI 1) - -set(LLVM_USED_LIBS - clangFrontend - clangDriver - clangSema - clangAnalysis - clangAST - clangParse - clangLex - clangBasic) - -set( LLVM_LINK_COMPONENTS - bitreader - mc - core - ) - -add_clang_library(CIndex - CIndex.cpp - CIndexCodeCompletion.cpp - CIndexDiagnostic.cpp - CIndexInclusionStack.cpp - CIndexUSRs.cpp - CIndexer.cpp - CXCursor.cpp - ../../include/clang-c/Index.h -) - -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - # FIXME: Deal with LLVM_SUBMIT_VERSION? - - # FIXME: This uses a special darwin-specific exports file in order to - # get underscore-prefixed names. It would be better to have build rules - # which know how to produce a darwin-suitable exports file from the - # regular exports file. - set_target_properties(CIndex - PROPERTIES - LINK_FLAGS "-avoid-version -Wl,-exported_symbols_list -Wl,${CMAKE_CURRENT_SOURCE_DIR}/CIndex.darwin.exports -Wl,-dead_strip -Wl,-seg1addr -Wl,0xE0000000" - INSTALL_NAME_DIR "@executable_path/../lib" - ) -endif() - -if(MSVC) - # windows.h doesn't compile with /Za - get_target_property(NON_ANSI_COMPILE_FLAGS CIndex COMPILE_FLAGS) - string(REPLACE /Za "" NON_ANSI_COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS}) - set_target_properties(CIndex PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS}) -endif(MSVC) - -set_target_properties(CIndex - PROPERTIES - LINKER_LANGUAGE CXX - DEFINE_SYMBOL _CINDEX_LIB_) diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp deleted file mode 100644 index 3bc5d01..0000000 --- a/tools/CIndex/CXCursor.cpp +++ /dev/null @@ -1,369 +0,0 @@ -//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXCursors. It should be the -// only file that has internal knowledge of the encoding of the data in -// CXCursor. -// -//===----------------------------------------------------------------------===// - -#include "CXCursor.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/Expr.h" -#include "llvm/Support/ErrorHandling.h" - -using namespace clang; - -CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) { - assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid); - CXCursor C = { K, { 0, 0, 0 } }; - return C; -} - -static CXCursorKind GetCursorKind(Decl *D) { - assert(D && "Invalid arguments!"); - switch (D->getKind()) { - case Decl::Enum: return CXCursor_EnumDecl; - case Decl::EnumConstant: return CXCursor_EnumConstantDecl; - case Decl::Field: return CXCursor_FieldDecl; - case Decl::Function: - return CXCursor_FunctionDecl; - case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl; - case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl; - case Decl::ObjCClass: - // FIXME - return CXCursor_UnexposedDecl; - case Decl::ObjCForwardProtocol: - // FIXME - return CXCursor_UnexposedDecl; - case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl; - case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl; - case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl; - case Decl::ObjCMethod: - return cast<ObjCMethodDecl>(D)->isInstanceMethod() - ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl; - case Decl::CXXMethod: return CXCursor_CXXMethod; - case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl; - case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; - case Decl::ParmVar: return CXCursor_ParmDecl; - case Decl::Typedef: return CXCursor_TypedefDecl; - case Decl::Var: return CXCursor_VarDecl; - default: - if (TagDecl *TD = dyn_cast<TagDecl>(D)) { - switch (TD->getTagKind()) { - case TagDecl::TK_struct: return CXCursor_StructDecl; - case TagDecl::TK_class: return CXCursor_ClassDecl; - case TagDecl::TK_union: return CXCursor_UnionDecl; - case TagDecl::TK_enum: return CXCursor_EnumDecl; - } - } - - return CXCursor_UnexposedDecl; - } - - llvm_unreachable("Invalid Decl"); - return CXCursor_NotImplemented; -} - -static CXCursorKind GetCursorKind(const Attr *A) { - assert(A && "Invalid arguments!"); - switch (A->getKind()) { - default: break; - case Attr::IBActionKind: return CXCursor_IBActionAttr; - case Attr::IBOutletKind: return CXCursor_IBOutletAttr; - } - - return CXCursor_UnexposedAttr; -} - -CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent, ASTUnit *TU) { - assert(A && Parent && TU && "Invalid arguments!"); - CXCursor C = { GetCursorKind(A), { Parent, (void*)A, TU } }; - return C; -} - -CXCursor cxcursor::MakeCXCursor(Decl *D, ASTUnit *TU) { - assert(D && TU && "Invalid arguments!"); - CXCursor C = { GetCursorKind(D), { D, 0, TU } }; - return C; -} - -CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { - assert(S && TU && "Invalid arguments!"); - CXCursorKind K = CXCursor_NotImplemented; - - switch (S->getStmtClass()) { - case Stmt::NoStmtClass: - break; - - case Stmt::NullStmtClass: - case Stmt::CompoundStmtClass: - case Stmt::CaseStmtClass: - case Stmt::DefaultStmtClass: - case Stmt::LabelStmtClass: - case Stmt::IfStmtClass: - case Stmt::SwitchStmtClass: - case Stmt::WhileStmtClass: - case Stmt::DoStmtClass: - case Stmt::ForStmtClass: - case Stmt::GotoStmtClass: - case Stmt::IndirectGotoStmtClass: - case Stmt::ContinueStmtClass: - case Stmt::BreakStmtClass: - case Stmt::ReturnStmtClass: - case Stmt::DeclStmtClass: - case Stmt::SwitchCaseClass: - case Stmt::AsmStmtClass: - case Stmt::ObjCAtTryStmtClass: - case Stmt::ObjCAtCatchStmtClass: - case Stmt::ObjCAtFinallyStmtClass: - case Stmt::ObjCAtThrowStmtClass: - case Stmt::ObjCAtSynchronizedStmtClass: - case Stmt::ObjCForCollectionStmtClass: - case Stmt::CXXCatchStmtClass: - case Stmt::CXXTryStmtClass: - K = CXCursor_UnexposedStmt; - break; - - case Stmt::PredefinedExprClass: - case Stmt::IntegerLiteralClass: - case Stmt::FloatingLiteralClass: - case Stmt::ImaginaryLiteralClass: - case Stmt::StringLiteralClass: - case Stmt::CharacterLiteralClass: - case Stmt::ParenExprClass: - case Stmt::UnaryOperatorClass: - case Stmt::SizeOfAlignOfExprClass: - case Stmt::ArraySubscriptExprClass: - case Stmt::BinaryOperatorClass: - case Stmt::CompoundAssignOperatorClass: - case Stmt::ConditionalOperatorClass: - case Stmt::ImplicitCastExprClass: - case Stmt::CStyleCastExprClass: - case Stmt::CompoundLiteralExprClass: - case Stmt::ExtVectorElementExprClass: - case Stmt::InitListExprClass: - case Stmt::DesignatedInitExprClass: - case Stmt::ImplicitValueInitExprClass: - case Stmt::ParenListExprClass: - case Stmt::VAArgExprClass: - case Stmt::AddrLabelExprClass: - case Stmt::StmtExprClass: - case Stmt::TypesCompatibleExprClass: - case Stmt::ChooseExprClass: - case Stmt::GNUNullExprClass: - case Stmt::CXXStaticCastExprClass: - case Stmt::CXXDynamicCastExprClass: - case Stmt::CXXReinterpretCastExprClass: - case Stmt::CXXConstCastExprClass: - case Stmt::CXXFunctionalCastExprClass: - case Stmt::CXXTypeidExprClass: - case Stmt::CXXBoolLiteralExprClass: - case Stmt::CXXNullPtrLiteralExprClass: - case Stmt::CXXThisExprClass: - case Stmt::CXXThrowExprClass: - case Stmt::CXXDefaultArgExprClass: - case Stmt::CXXZeroInitValueExprClass: - case Stmt::CXXNewExprClass: - case Stmt::CXXDeleteExprClass: - case Stmt::CXXPseudoDestructorExprClass: - case Stmt::UnresolvedLookupExprClass: - case Stmt::UnaryTypeTraitExprClass: - case Stmt::DependentScopeDeclRefExprClass: - case Stmt::CXXBindTemporaryExprClass: - case Stmt::CXXBindReferenceExprClass: - case Stmt::CXXExprWithTemporariesClass: - case Stmt::CXXUnresolvedConstructExprClass: - case Stmt::CXXDependentScopeMemberExprClass: - case Stmt::UnresolvedMemberExprClass: - case Stmt::ObjCStringLiteralClass: - case Stmt::ObjCEncodeExprClass: - case Stmt::ObjCSelectorExprClass: - case Stmt::ObjCProtocolExprClass: - case Stmt::ObjCImplicitSetterGetterRefExprClass: - case Stmt::ObjCSuperExprClass: - case Stmt::ObjCIsaExprClass: - case Stmt::ShuffleVectorExprClass: - case Stmt::BlockExprClass: - K = CXCursor_UnexposedExpr; - break; - case Stmt::DeclRefExprClass: - case Stmt::BlockDeclRefExprClass: - // FIXME: UnresolvedLookupExpr? - // FIXME: DependentScopeDeclRefExpr? - K = CXCursor_DeclRefExpr; - break; - - case Stmt::MemberExprClass: - case Stmt::ObjCIvarRefExprClass: - case Stmt::ObjCPropertyRefExprClass: - // FIXME: UnresolvedMemberExpr? - // FIXME: CXXDependentScopeMemberExpr? - K = CXCursor_MemberRefExpr; - break; - - case Stmt::CallExprClass: - case Stmt::CXXOperatorCallExprClass: - case Stmt::CXXMemberCallExprClass: - case Stmt::CXXConstructExprClass: - case Stmt::CXXTemporaryObjectExprClass: - // FIXME: CXXUnresolvedConstructExpr - // FIXME: ObjCImplicitSetterGetterRefExpr? - K = CXCursor_CallExpr; - break; - - case Stmt::ObjCMessageExprClass: - K = CXCursor_ObjCMessageExpr; - break; - } - - CXCursor C = { K, { Parent, S, TU } }; - return C; -} - -CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, - SourceLocation Loc, - ASTUnit *TU) { - assert(Super && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, TU } }; - return C; -} - -std::pair<ObjCInterfaceDecl *, SourceLocation> -cxcursor::getCursorObjCSuperClassRef(CXCursor C) { - assert(C.kind == CXCursor_ObjCSuperClassRef); - return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super, - SourceLocation Loc, - ASTUnit *TU) { - assert(Super && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, TU } }; - return C; -} - -std::pair<ObjCProtocolDecl *, SourceLocation> -cxcursor::getCursorObjCProtocolRef(CXCursor C) { - assert(C.kind == CXCursor_ObjCProtocolRef); - return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, - SourceLocation Loc, - ASTUnit *TU) { - // 'Class' can be null for invalid code. - if (!Class) - return MakeCXCursorInvalid(CXCursor_InvalidCode); - assert(TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, TU } }; - return C; -} - -std::pair<ObjCInterfaceDecl *, SourceLocation> -cxcursor::getCursorObjCClassRef(CXCursor C) { - assert(C.kind == CXCursor_ObjCClassRef); - return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, - ASTUnit *TU) { - assert(Type && TU && "Invalid arguments!"); - void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); - CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } }; - return C; -} - -std::pair<TypeDecl *, SourceLocation> -cxcursor::getCursorTypeRef(CXCursor C) { - assert(C.kind == CXCursor_TypeRef); - return std::make_pair(static_cast<TypeDecl *>(C.data[0]), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t>(C.data[1]))); -} - -CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range, - ASTUnit *TU) { - CXCursor C = { CXCursor_PreprocessingDirective, - { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()), - reinterpret_cast<void *>(Range.getEnd().getRawEncoding()), - TU } - }; - return C; -} - -SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) { - assert(C.kind == CXCursor_PreprocessingDirective); - return SourceRange(SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t> (C.data[0])), - SourceLocation::getFromRawEncoding( - reinterpret_cast<uintptr_t> (C.data[1]))); -} - -CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI, ASTUnit *TU) { - CXCursor C = { CXCursor_MacroDefinition, { MI, 0, TU } }; - return C; -} - -MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) { - assert(C.kind == CXCursor_MacroDefinition); - return static_cast<MacroDefinition *>(C.data[0]); -} - -CXCursor cxcursor::MakeMacroInstantiationCursor(MacroInstantiation *MI, - ASTUnit *TU) { - CXCursor C = { CXCursor_MacroInstantiation, { MI, 0, TU } }; - return C; -} - -MacroInstantiation *cxcursor::getCursorMacroInstantiation(CXCursor C) { - assert(C.kind == CXCursor_MacroInstantiation); - return static_cast<MacroInstantiation *>(C.data[0]); -} - -Decl *cxcursor::getCursorDecl(CXCursor Cursor) { - return (Decl *)Cursor.data[0]; -} - -Expr *cxcursor::getCursorExpr(CXCursor Cursor) { - return dyn_cast_or_null<Expr>(getCursorStmt(Cursor)); -} - -Stmt *cxcursor::getCursorStmt(CXCursor Cursor) { - if (Cursor.kind == CXCursor_ObjCSuperClassRef || - Cursor.kind == CXCursor_ObjCProtocolRef || - Cursor.kind == CXCursor_ObjCClassRef) - return 0; - - return (Stmt *)Cursor.data[1]; -} - -ASTContext &cxcursor::getCursorContext(CXCursor Cursor) { - return getCursorASTUnit(Cursor)->getASTContext(); -} - -ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) { - return static_cast<ASTUnit *>(Cursor.data[2]); -} - -bool cxcursor::operator==(CXCursor X, CXCursor Y) { - return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] && - X.data[2] == Y.data[2]; -} diff --git a/tools/CIndex/CXCursor.h b/tools/CIndex/CXCursor.h deleted file mode 100644 index 1664f5a..0000000 --- a/tools/CIndex/CXCursor.h +++ /dev/null @@ -1,112 +0,0 @@ -//===- CXCursor.h - Routines for manipulating CXCursors -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXCursors. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CXCURSOR_H -#define LLVM_CLANG_CXCURSOR_H - -#include "clang-c/Index.h" -#include "clang/Basic/SourceLocation.h" -#include <utility> - -namespace clang { - -class ASTContext; -class ASTUnit; -class Attr; -class Decl; -class Expr; -class MacroDefinition; -class MacroInstantiation; -class NamedDecl; -class ObjCInterfaceDecl; -class ObjCProtocolDecl; -class Stmt; -class TypeDecl; - -namespace cxcursor { - -CXCursor MakeCXCursor(const clang::Attr *A, clang::Decl *Parent, ASTUnit *TU); -CXCursor MakeCXCursor(clang::Decl *D, ASTUnit *TU); -CXCursor MakeCXCursor(clang::Stmt *S, clang::Decl *Parent, ASTUnit *TU); -CXCursor MakeCXCursorInvalid(CXCursorKind K); - -/// \brief Create an Objective-C superclass reference at the given location. -CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, - SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references -/// and optionally the location where the reference occurred. -std::pair<ObjCInterfaceDecl *, SourceLocation> - getCursorObjCSuperClassRef(CXCursor C); - -/// \brief Create an Objective-C protocol reference at the given location. -CXCursor MakeCursorObjCProtocolRef(ObjCProtocolDecl *Proto, SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references -/// and optionally the location where the reference occurred. -std::pair<ObjCProtocolDecl *, SourceLocation> - getCursorObjCProtocolRef(CXCursor C); - -/// \brief Create an Objective-C class reference at the given location. -CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc, - ASTUnit *TU); - -/// \brief Unpack an ObjCClassRef cursor into the class it references -/// and optionally the location where the reference occurred. -std::pair<ObjCInterfaceDecl *, SourceLocation> - getCursorObjCClassRef(CXCursor C); - -/// \brief Create a type reference at the given location. -CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, ASTUnit *TU); - -/// \brief Unpack a TypeRef cursor into the class it references -/// and optionally the location where the reference occurred. -std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C); - -/// \brief Create a preprocessing directive cursor. -CXCursor MakePreprocessingDirectiveCursor(SourceRange Range, ASTUnit *TU); - -/// \brief Unpack a given preprocessing directive to retrieve its source range. -SourceRange getCursorPreprocessingDirective(CXCursor C); - -/// \brief Create a macro definition cursor. -CXCursor MakeMacroDefinitionCursor(MacroDefinition *, ASTUnit *TU); - -/// \brief Unpack a given macro definition cursor to retrieve its -/// source range. -MacroDefinition *getCursorMacroDefinition(CXCursor C); - -/// \brief Create a macro instantiation cursor. -CXCursor MakeMacroInstantiationCursor(MacroInstantiation *, ASTUnit *TU); - -/// \brief Unpack a given macro instantiation cursor to retrieve its -/// source range. -MacroInstantiation *getCursorMacroInstantiation(CXCursor C); - -Decl *getCursorDecl(CXCursor Cursor); -Expr *getCursorExpr(CXCursor Cursor); -Stmt *getCursorStmt(CXCursor Cursor); -ASTContext &getCursorContext(CXCursor Cursor); -ASTUnit *getCursorASTUnit(CXCursor Cursor); - -bool operator==(CXCursor X, CXCursor Y); - -inline bool operator!=(CXCursor X, CXCursor Y) { - return !(X == Y); -} - -}} // end namespace: clang::cxcursor - -#endif diff --git a/tools/CIndex/CXSourceLocation.h b/tools/CIndex/CXSourceLocation.h deleted file mode 100644 index 66566c1..0000000 --- a/tools/CIndex/CXSourceLocation.h +++ /dev/null @@ -1,75 +0,0 @@ -//===- CXSourceLocation.h - CXSourceLocations Utilities ---------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines routines for manipulating CXSourceLocations. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_CXSOURCELOCATION_H -#define LLVM_CLANG_CXSOURCELOCATION_H - -#include "clang-c/Index.h" -#include "clang/Basic/SourceLocation.h" -#include "clang/Basic/LangOptions.h" -#include "clang/AST/ASTContext.h" - -namespace clang { - -class SourceManager; - -namespace cxloc { - -/// \brief Translate a Clang source location into a CIndex source location. -static inline CXSourceLocation -translateSourceLocation(const SourceManager &SM, const LangOptions &LangOpts, - SourceLocation Loc) { - CXSourceLocation Result = { { (void*) &SM, (void*) &LangOpts, }, - Loc.getRawEncoding() }; - return Result; -} - -/// \brief Translate a Clang source location into a CIndex source location. -static inline CXSourceLocation translateSourceLocation(ASTContext &Context, - SourceLocation Loc) { - return translateSourceLocation(Context.getSourceManager(), - Context.getLangOptions(), - Loc); -} - -/// \brief Translate a Clang source range into a CIndex source range. -/// -/// Clang internally represents ranges where the end location points to the -/// start of the token at the end. However, for external clients it is more -/// useful to have a CXSourceRange be a proper half-open interval. This routine -/// does the appropriate translation. -CXSourceRange translateSourceRange(const SourceManager &SM, - const LangOptions &LangOpts, - SourceRange R); - -/// \brief Translate a Clang source range into a CIndex source range. -static inline CXSourceRange translateSourceRange(ASTContext &Context, - SourceRange R) { - return translateSourceRange(Context.getSourceManager(), - Context.getLangOptions(), - R); -} - -static inline SourceLocation translateSourceLocation(CXSourceLocation L) { - return SourceLocation::getFromRawEncoding(L.int_data); -} - -static inline SourceRange translateCXSourceRange(CXSourceRange R) { - return SourceRange(SourceLocation::getFromRawEncoding(R.begin_int_data), - SourceLocation::getFromRawEncoding(R.end_int_data)); -} - - -}} // end namespace: clang::cxloc - -#endif diff --git a/tools/CIndex/Makefile b/tools/CIndex/Makefile deleted file mode 100644 index 391746d..0000000 --- a/tools/CIndex/Makefile +++ /dev/null @@ -1,55 +0,0 @@ -##===- tools/CIndex/Makefile -------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../../.. -LIBRARYNAME = CIndex - -EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/CIndex.exports - -CPP.Flags += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include - -# Include this here so we can get the configuration of the targets -# that have been configured for construction. We have to do this -# early so we can set up LINK_COMPONENTS before including Makefile.rules -include $(LEVEL)/Makefile.config - -LINK_LIBS_IN_SHARED = 1 -SHARED_LIBRARY = 1 - -LINK_COMPONENTS := bitreader mc core -USEDLIBS = clangFrontend.a clangDriver.a clangSema.a \ - clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a - -include $(LEVEL)/Makefile.common - -##===----------------------------------------------------------------------===## -# FIXME: This is copied from the 'lto' makefile. Should we share this? -##===----------------------------------------------------------------------===## - -ifeq ($(HOST_OS),Darwin) - # set dylib internal version number to llvmCore submission number - ifdef LLVM_SUBMIT_VERSION - LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version \ - -Wl,$(LLVM_SUBMIT_VERSION).$(LLVM_SUBMIT_SUBVERSION) \ - -Wl,-compatibility_version -Wl,1 - endif - # extra options to override libtool defaults - LLVMLibsOptions := $(LLVMLibsOptions) \ - -avoid-version \ - -Wl,-dead_strip \ - -Wl,-seg1addr -Wl,0xE0000000 - - # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line - DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') - ifneq ($(DARWIN_VERS),8) - LLVMLibsOptions := $(LLVMLibsOptions) \ - -no-undefined -Wl,-install_name \ - -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)" - endif -endif diff --git a/tools/index-test/CMakeLists.txt b/tools/index-test/CMakeLists.txt deleted file mode 100644 index 9472e58..0000000 --- a/tools/index-test/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -set(LLVM_NO_RTTI 1) - -set( LLVM_USED_LIBS - clangIndex - clangFrontend - clangDriver - clangSema - clangAnalysis - clangAST - clangParse - clangLex - clangBasic - ) - -set( LLVM_LINK_COMPONENTS - bitreader - mc - core - ) - -add_clang_executable(index-test - index-test.cpp - ) diff --git a/tools/index-test/Makefile b/tools/index-test/Makefile deleted file mode 100644 index 4ee98fc..0000000 --- a/tools/index-test/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -##===- tools/index-test/Makefile ---------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## -LEVEL = ../../../.. - -TOOLNAME = index-test -CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include -CXXFLAGS = -fno-rtti -NO_INSTALL = 1 - -# No plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.config - -LINK_COMPONENTS := bitreader mc core -USEDLIBS = clangIndex.a clangFrontend.a clangDriver.a clangSema.a \ - clangAnalysis.a clangAST.a clangParse.a clangLex.a clangBasic.a - -include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/tools/index-test/index-test.cpp b/tools/index-test/index-test.cpp deleted file mode 100644 index ff9fd54..0000000 --- a/tools/index-test/index-test.cpp +++ /dev/null @@ -1,334 +0,0 @@ -//===--- index-test.cpp - Indexing test bed -------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This utility may be invoked in the following manner: -// index-test --help - Output help info. -// index-test [options] - Read from stdin. -// index-test [options] file - Read from "file". -// index-test [options] file1 file2 - Read these files. -// -// Files must be AST files. -// -//===----------------------------------------------------------------------===// -// -// -point-at [file:line:column] -// Point at a declaration/statement/expression. If no other operation is -// specified, prints some info about it. -// -// -print-refs -// Print ASTLocations that reference the -point-at node -// -// -print-defs -// Print ASTLocations that define the -point-at node -// -// -print-decls -// Print ASTLocations that declare the -point-at node -// -//===----------------------------------------------------------------------===// - -#include "clang/Index/Program.h" -#include "clang/Index/Indexer.h" -#include "clang/Index/Entity.h" -#include "clang/Index/TranslationUnit.h" -#include "clang/Index/ASTLocation.h" -#include "clang/Index/DeclReferenceMap.h" -#include "clang/Index/SelectorMap.h" -#include "clang/Index/Handlers.h" -#include "clang/Index/Analyzer.h" -#include "clang/Index/Utils.h" -#include "clang/Frontend/ASTUnit.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/CompilerInvocation.h" -#include "clang/Frontend/DiagnosticOptions.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Frontend/CommandLineSourceLoc.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/ExprObjC.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/SourceManager.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/System/Signals.h" -using namespace clang; -using namespace idx; - -class TUnit : public TranslationUnit { -public: - TUnit(ASTUnit *ast, const std::string &filename) - : AST(ast), Filename(filename), - DeclRefMap(ast->getASTContext()), - SelMap(ast->getASTContext()) { } - - virtual ASTContext &getASTContext() { return AST->getASTContext(); } - virtual DeclReferenceMap &getDeclReferenceMap() { return DeclRefMap; } - virtual SelectorMap &getSelectorMap() { return SelMap; } - - llvm::OwningPtr<ASTUnit> AST; - std::string Filename; - DeclReferenceMap DeclRefMap; - SelectorMap SelMap; -}; - -static llvm::cl::list<ParsedSourceLocation> -PointAtLocation("point-at", llvm::cl::Optional, - llvm::cl::value_desc("source-location"), - llvm::cl::desc("Point at the given source location of the first AST file")); - -enum ProgActions { - PrintPoint, // Just print the point-at node - PrintRefs, // Print references of the point-at node - PrintDefs, // Print definitions of the point-at node - PrintDecls // Print declarations of the point-at node -}; - -static llvm::cl::opt<ProgActions> -ProgAction( - llvm::cl::desc("Choose action to perform on the pointed-at AST node:"), - llvm::cl::ZeroOrMore, - llvm::cl::init(PrintPoint), - llvm::cl::values( - clEnumValN(PrintRefs, "print-refs", - "Print references"), - clEnumValN(PrintDefs, "print-defs", - "Print definitions"), - clEnumValN(PrintDecls, "print-decls", - "Print declarations"), - clEnumValEnd)); - -static llvm::cl::opt<bool> -DisableFree("disable-free", - llvm::cl::desc("Disable freeing of memory on exit"), - llvm::cl::init(false)); - -static bool HadErrors = false; - -static void ProcessObjCMessage(ObjCMessageExpr *Msg, Indexer &Idxer) { - llvm::raw_ostream &OS = llvm::outs(); - typedef Storing<TULocationHandler> ResultsTy; - ResultsTy Results; - - Analyzer Analyz(Idxer.getProgram(), Idxer); - - switch (ProgAction) { - default: assert(0); - case PrintRefs: - llvm::errs() << "Error: Cannot -print-refs on a ObjC message expression\n"; - HadErrors = true; - return; - - case PrintDecls: { - Analyz.FindObjCMethods(Msg, Results); - for (ResultsTy::iterator - I = Results.begin(), E = Results.end(); I != E; ++I) - I->print(OS); - break; - } - - case PrintDefs: { - Analyz.FindObjCMethods(Msg, Results); - for (ResultsTy::iterator - I = Results.begin(), E = Results.end(); I != E; ++I) { - const ObjCMethodDecl *D = cast<ObjCMethodDecl>(I->AsDecl()); - if (D->isThisDeclarationADefinition()) - I->print(OS); - } - break; - } - - } -} - -static void ProcessASTLocation(ASTLocation ASTLoc, Indexer &Idxer) { - assert(ASTLoc.isValid()); - - if (ObjCMessageExpr *Msg = - dyn_cast_or_null<ObjCMessageExpr>(ASTLoc.dyn_AsStmt())) - return ProcessObjCMessage(Msg, Idxer); - - Decl *D = ASTLoc.getReferencedDecl(); - if (D == 0) { - llvm::errs() << "Error: Couldn't get referenced Decl for the ASTLocation\n"; - HadErrors = true; - return; - } - - llvm::raw_ostream &OS = llvm::outs(); - typedef Storing<TULocationHandler> ResultsTy; - ResultsTy Results; - - Analyzer Analyz(Idxer.getProgram(), Idxer); - - switch (ProgAction) { - default: assert(0); - case PrintRefs: { - Analyz.FindReferences(D, Results); - for (ResultsTy::iterator - I = Results.begin(), E = Results.end(); I != E; ++I) - I->print(OS); - break; - } - - case PrintDecls: { - Analyz.FindDeclarations(D, Results); - for (ResultsTy::iterator - I = Results.begin(), E = Results.end(); I != E; ++I) - I->print(OS); - break; - } - - case PrintDefs: { - Analyz.FindDeclarations(D, Results); - for (ResultsTy::iterator - I = Results.begin(), E = Results.end(); I != E; ++I) { - const Decl *D = I->AsDecl(); - bool isDef = false; - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - isDef = FD->isThisDeclarationADefinition(); - else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) - isDef = VD->getInit() != 0; - else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) - isDef = MD->isThisDeclarationADefinition(); - - if (isDef) - I->print(OS); - } - break; - } - - } -} - -static llvm::cl::opt<bool> -ASTFromSource("ast-from-source", - llvm::cl::desc("Treat the inputs as source files to parse")); - -static llvm::cl::list<std::string> -CompilerArgs("arg", llvm::cl::desc("Extra arguments to use during parsing")); - -static llvm::cl::list<std::string> -InputFilenames(llvm::cl::Positional, llvm::cl::desc("<input AST files>")); - -ASTUnit *CreateFromSource(const std::string &Filename, Diagnostic &Diags, - const char *Argv0) { - llvm::SmallVector<const char *, 16> Args; - Args.push_back(Filename.c_str()); - for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i) - Args.push_back(CompilerArgs[i].c_str()); - - void *MainAddr = (void*) (intptr_t) CreateFromSource; - std::string ResourceDir = - CompilerInvocation::GetResourcesPath(Argv0, MainAddr); - return ASTUnit::LoadFromCommandLine(Args.data(), Args.data() + Args.size(), - Diags, ResourceDir); -} - -int main(int argc, char **argv) { - llvm::sys::PrintStackTraceOnErrorSignal(); - llvm::PrettyStackTraceProgram X(argc, argv); - llvm::cl::ParseCommandLineOptions(argc, argv, - "LLVM 'Clang' Indexing Test Bed: http://clang.llvm.org\n"); - - Program Prog; - Indexer Idxer(Prog); - llvm::SmallVector<TUnit*, 4> TUnits; - - DiagnosticOptions DiagOpts; - llvm::OwningPtr<Diagnostic> Diags( - CompilerInstance::createDiagnostics(DiagOpts, argc, argv)); - - // If no input was specified, read from stdin. - if (InputFilenames.empty()) - InputFilenames.push_back("-"); - - for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { - const std::string &InFile = InputFilenames[i]; - llvm::OwningPtr<ASTUnit> AST; - if (ASTFromSource) - AST.reset(CreateFromSource(InFile, *Diags, argv[0])); - else - AST.reset(ASTUnit::LoadFromPCHFile(InFile, *Diags)); - if (!AST) - return 1; - - TUnit *TU = new TUnit(AST.take(), InFile); - TUnits.push_back(TU); - - Idxer.IndexAST(TU); - } - - ASTLocation ASTLoc; - const std::string &FirstFile = TUnits[0]->Filename; - ASTUnit *FirstAST = TUnits[0]->AST.get(); - - if (!PointAtLocation.empty()) { - const std::string &Filename = PointAtLocation[0].FileName; - const FileEntry *File = FirstAST->getFileManager().getFile(Filename); - if (File == 0) { - llvm::errs() << "File '" << Filename << "' does not exist\n"; - return 1; - } - - // Safety check. Using an out-of-date AST file will only lead to crashes - // or incorrect results. - // FIXME: Check all the source files that make up the AST file. - const FileEntry *ASTFile = FirstAST->getFileManager().getFile(FirstFile); - if (File->getModificationTime() > ASTFile->getModificationTime()) { - llvm::errs() << "[" << FirstFile << "] Error: " << - "Pointing at a source file which was modified after creating " - "the AST file\n"; - return 1; - } - - unsigned Line = PointAtLocation[0].Line; - unsigned Col = PointAtLocation[0].Column; - - SourceLocation Loc = - FirstAST->getSourceManager().getLocation(File, Line, Col); - if (Loc.isInvalid()) { - llvm::errs() << "[" << FirstFile << "] Error: " << - "Couldn't resolve source location (invalid location)\n"; - return 1; - } - - ASTLoc = ResolveLocationInAST(FirstAST->getASTContext(), Loc); - if (ASTLoc.isInvalid()) { - llvm::errs() << "[" << FirstFile << "] Error: " << - "Couldn't resolve source location (no declaration found)\n"; - return 1; - } - } - - if (ASTLoc.isValid()) { - if (ProgAction == PrintPoint) { - llvm::raw_ostream &OS = llvm::outs(); - ASTLoc.print(OS); - if (const char *Comment = - FirstAST->getASTContext().getCommentForDecl(ASTLoc.dyn_AsDecl())) - OS << "Comment associated with this declaration:\n" << Comment << "\n"; - } else { - ProcessASTLocation(ASTLoc, Idxer); - } - } - - if (HadErrors) - return 1; - - if (!DisableFree) { - for (int i=0, e=TUnits.size(); i != e; ++i) - delete TUnits[i]; - } - - // Managed static deconstruction. Useful for making things like - // -time-passes usable. - llvm::llvm_shutdown(); - - return 0; -} |