summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/CIndex/CIndex.cpp344
-rw-r--r--tools/CIndex/CIndex.exports3
-rw-r--r--tools/CIndex/CMakeLists.txt7
-rw-r--r--tools/c-index-test/c-index-test.c32
-rw-r--r--tools/clang-cc/clang-cc.cpp9
-rw-r--r--tools/index-test/index-test.cpp7
6 files changed, 321 insertions, 81 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 9204d1863d67c..64dfcfea51439 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -22,12 +22,27 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Program.h"
+#include "llvm/Support/raw_ostream.h"
+
#include <cstdio>
+#include <vector>
+
+#ifdef LLVM_ON_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
using namespace clang;
using namespace idx;
namespace {
-
static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
{
NamedDecl *D = DRE->getDecl();
@@ -76,6 +91,14 @@ public:
}
};
#endif
+
+/// IgnoreDiagnosticsClient - A DiagnosticsClient that just ignores emitted
+/// warnings and errors.
+class VISIBILITY_HIDDEN IgnoreDiagnosticsClient : public DiagnosticClient {
+public:
+ virtual ~IgnoreDiagnosticsClient() {}
+ virtual void HandleDiagnostic(Diagnostic::Level, const DiagnosticInfo &) {}
+};
// Translation Unit Visitor.
class TUVisitor : public DeclVisitor<TUVisitor> {
@@ -83,14 +106,24 @@ class TUVisitor : public DeclVisitor<TUVisitor> {
CXTranslationUnitIterator Callback;
CXClientData CData;
+ // 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;
+
void Call(enum CXCursorKind CK, NamedDecl *ND) {
+ // Filter any declarations that have a PCH level greater than what we allow.
+ if (ND->getPCHLevel() > MaxPCHLevel)
+ return;
+
CXCursor C = { CK, ND, 0 };
Callback(TUnit, C, CData);
}
public:
TUVisitor(CXTranslationUnit CTU,
- CXTranslationUnitIterator cback, CXClientData D) :
- TUnit(CTU), Callback(cback), CData(D) {}
+ CXTranslationUnitIterator cback, CXClientData D,
+ unsigned MaxPCHLevel) :
+ TUnit(CTU), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
VisitDeclContext(dyn_cast<DeclContext>(D));
@@ -149,16 +182,27 @@ class CDeclVisitor : public DeclVisitor<CDeclVisitor> {
CXDeclIterator Callback;
CXClientData CData;
+ // 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;
+
void Call(enum CXCursorKind CK, NamedDecl *ND) {
// Disable the callback when the context is equal to the visiting decl.
if (CDecl == ND && !clang_isReference(CK))
return;
+
+ // Filter any declarations that have a PCH level greater than what we allow.
+ if (ND->getPCHLevel() > MaxPCHLevel)
+ return;
+
CXCursor C = { CK, ND, 0 };
Callback(CDecl, C, CData);
}
public:
- CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
- CDecl(C), Callback(cback), CData(D) {}
+ CDeclVisitor(CXDecl C, CXDeclIterator cback, CXClientData D,
+ unsigned MaxPCHLevel) :
+ CDecl(C), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
void VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
// Issue callbacks for the containing class.
@@ -237,20 +281,87 @@ public:
}
};
+class CIndexer : public Indexer {
+public:
+ explicit CIndexer(Program *prog) : Indexer(*prog),
+ OnlyLocalDecls(false),
+ DisplayDiagnostics(false) {}
+
+ virtual ~CIndexer() { delete &getProgram(); }
+
+ /// \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; }
+
+ void setDisplayDiagnostics(bool Display = true) {
+ DisplayDiagnostics = Display;
+ }
+ bool getDisplayDiagnostics() const { return DisplayDiagnostics; }
+
+ /// \brief Get the path of the clang binary.
+ const llvm::sys::Path& getClangPath();
+private:
+ bool OnlyLocalDecls;
+ bool DisplayDiagnostics;
+
+ llvm::sys::Path ClangPath;
+};
+
+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);
+#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);
+#endif
+
+ // We now have the CIndex directory, locate clang relative to it.
+ CIndexPath.eraseComponent();
+ CIndexPath.eraseComponent();
+ CIndexPath.appendComponent("bin");
+ CIndexPath.appendComponent("clang");
+
+ // Cache our result.
+ ClangPath = CIndexPath;
+ return ClangPath;
+}
+
}
extern "C" {
-CXIndex clang_createIndex()
-{
- // FIXME: Program is leaked.
- return new Indexer(*new Program());
+CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
+ int displayDiagnostics)
+{
+ CIndexer *CIdxr = new CIndexer(new Program());
+ if (excludeDeclarationsFromPCH)
+ CIdxr->setOnlyLocalDecls();
+ if (displayDiagnostics)
+ CIdxr->setDisplayDiagnostics();
+ return CIdxr;
}
void clang_disposeIndex(CXIndex CIdx)
{
assert(CIdx && "Passed null CXIndex");
- delete static_cast<Indexer *>(CIdx);
+ delete static_cast<CIndexer *>(CIdx);
}
// FIXME: need to pass back error info.
@@ -258,12 +369,102 @@ CXTranslationUnit clang_createTranslationUnit(
CXIndex CIdx, const char *ast_filename)
{
assert(CIdx && "Passed null CXIndex");
- Indexer *CXXIdx = static_cast<Indexer *>(CIdx);
+ CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
std::string astName(ast_filename);
std::string ErrMsg;
- return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getDiagnostics(),
- CXXIdx->getFileManager(), &ErrMsg);
+ CXTranslationUnit TU =
+ ASTUnit::LoadFromPCHFile(astName, &ErrMsg,
+ CXXIdx->getDisplayDiagnostics() ?
+ NULL : new IgnoreDiagnosticsClient(),
+ CXXIdx->getOnlyLocalDecls(),
+ /* UseBumpAllocator = */ true);
+
+ if (!ErrMsg.empty()) {
+ (llvm::errs() << "clang_createTranslationUnit: " << ErrMsg
+ << '\n').flush();
+ }
+
+ return TU;
+}
+
+CXTranslationUnit clang_createTranslationUnitFromSourceFile(
+ CXIndex CIdx,
+ const char *source_filename,
+ int num_command_line_args, const char **command_line_args) {
+ assert(CIdx && "Passed null CXIndex");
+ CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
+
+ // 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));
+
+ // 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);
+
+#ifndef LLVM_ON_WIN32
+ llvm::sys::Path DevNull("/dev/null");
+ std::string ErrMsg;
+ const llvm::sys::Path *Redirects[] = { &DevNull, &DevNull, &DevNull, NULL };
+ llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
+ /* redirects */ !CXXIdx->getDisplayDiagnostics() ? &Redirects[0] : NULL,
+ /* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg);
+
+ if (!ErrMsg.empty()) {
+ llvm::errs() << "clang_createTranslationUnitFromSourceFile: " << ErrMsg
+ << '\n' << "Arguments: \n";
+ for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
+ I!=E; ++I)
+ if (*I) llvm::errs() << ' ' << *I << '\n';
+
+ (llvm::errs() << '\n').flush();
+ }
+#else
+ // FIXME: I don't know what is the equivalent '/dev/null' redirect for
+ // Windows for this API.
+ llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0]);
+#endif
+
+ // Finally, we create the translation unit from the ast file.
+ ASTUnit *ATU = static_cast<ASTUnit *>(
+ clang_createTranslationUnit(CIdx, astTmpFile));
+ if (ATU)
+ ATU->unlinkTemporaryFile();
+ return ATU;
}
void clang_disposeTranslationUnit(
@@ -272,7 +473,7 @@ void clang_disposeTranslationUnit(
assert(CTUnit && "Passed null CXTranslationUnit");
delete static_cast<ASTUnit *>(CTUnit);
}
-
+
const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)
{
assert(CTUnit && "Passed null CXTranslationUnit");
@@ -288,7 +489,8 @@ void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
ASTContext &Ctx = CXXUnit->getASTContext();
- TUVisitor DVisit(CTUnit, callback, CData);
+ TUVisitor DVisit(CTUnit, callback, CData,
+ CXXUnit->getOnlyLocalDecls()? 1 : Decl::MaxPCHLevel);
DVisit.Visit(Ctx.getTranslationUnitDecl());
}
@@ -298,7 +500,8 @@ void clang_loadDeclaration(CXDecl Dcl,
{
assert(Dcl && "Passed null CXDecl");
- CDeclVisitor DVisit(Dcl, callback, CData);
+ CDeclVisitor DVisit(Dcl, callback, CData,
+ static_cast<Decl *>(Dcl)->getPCHLevel());
DVisit.Visit(static_cast<Decl *>(Dcl));
}
@@ -349,7 +552,7 @@ const char *clang_getDeclSpelling(CXDecl AnonDecl)
return OMD->getSelector().getAsString().c_str();
}
if (ND->getIdentifier())
- return ND->getIdentifier()->getName();
+ return ND->getIdentifier()->getNameStart();
else
return "";
}
@@ -385,43 +588,38 @@ const char *clang_getCursorSpelling(CXCursor C)
if (clang_isReference(C.kind)) {
switch (C.kind) {
- case CXCursor_ObjCSuperClassRef:
- {
+ case CXCursor_ObjCSuperClassRef: {
ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing interface decl");
- return OID->getSuperClass()->getIdentifier()->getName();
- }
- case CXCursor_ObjCClassRef:
- {
+ return OID->getSuperClass()->getIdentifier()->getNameStart();
+ }
+ case CXCursor_ObjCClassRef: {
if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND)) {
- return OID->getIdentifier()->getName();
+ return OID->getIdentifier()->getNameStart();
}
ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing category decl");
- return OID->getClassInterface()->getIdentifier()->getName();
- }
- case CXCursor_ObjCProtocolRef:
- {
+ return OID->getClassInterface()->getIdentifier()->getNameStart();
+ }
+ case CXCursor_ObjCProtocolRef: {
ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing protocol decl");
- return OID->getIdentifier()->getName();
- }
- case CXCursor_ObjCSelectorRef:
- {
+ return OID->getIdentifier()->getNameStart();
+ }
+ case CXCursor_ObjCSelectorRef: {
ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
static_cast<Stmt *>(C.stmt));
assert(OME && "clang_getCursorLine(): Missing message expr");
return OME->getSelector().getAsString().c_str();
- }
+ }
case CXCursor_VarRef:
case CXCursor_FunctionRef:
- case CXCursor_EnumConstantRef:
- {
+ case CXCursor_EnumConstantRef: {
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
static_cast<Stmt *>(C.stmt));
assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
- return DRE->getDecl()->getIdentifier()->getName();
- }
+ return DRE->getDecl()->getIdentifier()->getNameStart();
+ }
default:
return "<not implemented>";
}
@@ -497,12 +695,26 @@ static enum CXCursorKind TranslateKind(Decl *D) {
//
// CXCursor Operations.
//
+void clang_initCXLookupHint(CXLookupHint *hint) {
+ memset(hint, 0, sizeof(*hint));
+}
+
CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
- unsigned line, unsigned column)
+ unsigned line, unsigned column) {
+ return clang_getCursorWithHint(CTUnit, source_name, line, column, NULL);
+}
+
+CXCursor clang_getCursorWithHint(CXTranslationUnit CTUnit,
+ const char *source_name,
+ unsigned line, unsigned column,
+ CXLookupHint *hint)
{
assert(CTUnit && "Passed null CXTranslationUnit");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
+ // FIXME: Make this better.
+ CXDecl RelativeToDecl = hint ? hint->decl : NULL;
+
FileManager &FMgr = CXXUnit->getFileManager();
const FileEntry *File = FMgr.getFile(source_name,
source_name+strlen(source_name));
@@ -513,7 +725,8 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
SourceLocation SLoc =
CXXUnit->getSourceManager().getLocation(File, line, column);
- ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc);
+ ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
+ static_cast<NamedDecl *>(RelativeToDecl));
Decl *Dcl = ALoc.getParentDecl();
if (ALoc.isNamedRef())
@@ -623,8 +836,7 @@ static SourceLocation getLocationFromCursor(CXCursor C,
NamedDecl *ND) {
if (clang_isReference(C.kind)) {
switch (C.kind) {
- case CXCursor_ObjCClassRef:
- {
+ case CXCursor_ObjCClassRef: {
if (isa<ObjCInterfaceDecl>(ND)) {
// FIXME: This is a hack (storing the parent decl in the stmt slot).
NamedDecl *parentDecl = static_cast<NamedDecl *>(C.stmt);
@@ -633,56 +845,49 @@ static SourceLocation getLocationFromCursor(CXCursor C,
ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing category decl");
return OID->getClassInterface()->getLocation();
- }
- case CXCursor_ObjCSuperClassRef:
- {
+ }
+ case CXCursor_ObjCSuperClassRef: {
ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing interface decl");
return OID->getSuperClassLoc();
- }
- case CXCursor_ObjCProtocolRef:
- {
+ }
+ case CXCursor_ObjCProtocolRef: {
ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
assert(OID && "clang_getCursorLine(): Missing protocol decl");
return OID->getLocation();
- }
- case CXCursor_ObjCSelectorRef:
- {
+ }
+ case CXCursor_ObjCSelectorRef: {
ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
static_cast<Stmt *>(C.stmt));
assert(OME && "clang_getCursorLine(): Missing message expr");
return OME->getLeftLoc(); /* FIXME: should be a range */
- }
+ }
case CXCursor_VarRef:
case CXCursor_FunctionRef:
- case CXCursor_EnumConstantRef:
- {
+ case CXCursor_EnumConstantRef: {
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
static_cast<Stmt *>(C.stmt));
assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
return DRE->getLocation();
- }
+ }
default:
return SourceLocation();
}
} else { // We have a declaration or a definition.
SourceLocation SLoc;
switch (ND->getKind()) {
- case Decl::ObjCInterface:
- {
+ case Decl::ObjCInterface: {
SLoc = dyn_cast<ObjCInterfaceDecl>(ND)->getClassLoc();
break;
- }
- case Decl::ObjCProtocol:
- {
+ }
+ case Decl::ObjCProtocol: {
SLoc = ND->getLocation(); /* FIXME: need to get the name location. */
break;
- }
- default:
- {
+ }
+ default: {
SLoc = ND->getLocation();
break;
- }
+ }
}
if (SLoc.isInvalid())
return SourceLocation();
@@ -716,7 +921,18 @@ const char *clang_getCursorSource(CXCursor C)
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
- return SourceMgr.getBufferName(SLoc);
+ if (SLoc.isFileID())
+ return SourceMgr.getBufferName(SLoc);
+
+ // Retrieve the file in which the macro was instantiated, then provide that
+ // buffer name.
+ // FIXME: Do we want to give specific macro-instantiation information?
+ const llvm::MemoryBuffer *Buffer
+ = SourceMgr.getBuffer(SourceMgr.getDecomposedSpellingLoc(SLoc).first);
+ if (!Buffer)
+ return 0;
+
+ return Buffer->getBufferIdentifier();
}
void clang_getDefinitionSpellingAndExtent(CXCursor C,
diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports
index c1ca0c7735198..e9d44a0dc918f 100644
--- a/tools/CIndex/CIndex.exports
+++ b/tools/CIndex/CIndex.exports
@@ -7,6 +7,7 @@ _clang_getCursorFromDecl
_clang_getCursorKind
_clang_getCursorLine
_clang_getCursorSource
+_clang_getCursorWithHint
_clang_getDeclarationName
_clang_getDeclSpelling
_clang_getDeclLine
@@ -18,7 +19,9 @@ _clang_getURI
_clang_loadDeclaration
_clang_loadTranslationUnit
_clang_createTranslationUnit
+_clang_createTranslationUnitFromSourceFile
_clang_disposeTranslationUnit
+_clang_initCXLookupHint
_clang_isDeclaration
_clang_isReference
_clang_isDefinition
diff --git a/tools/CIndex/CMakeLists.txt b/tools/CIndex/CMakeLists.txt
index 71bbde546a6ee..ee77c0398f729 100644
--- a/tools/CIndex/CMakeLists.txt
+++ b/tools/CIndex/CMakeLists.txt
@@ -22,6 +22,13 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
)
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)
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index c514b63d94be2..cf2a706891e3b 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -53,17 +53,23 @@ static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor,
unsigned curLine = startLine, curColumn = startColumn;
CXCursor Ref;
- while (startBuf <= endBuf) {
+ while (startBuf < endBuf) {
+ CXLookupHint hint;
if (*startBuf == '\n') {
startBuf++;
curLine++;
curColumn = 1;
} else if (*startBuf != '\t')
curColumn++;
+
+ clang_initCXLookupHint(&hint);
+ hint.decl = Cursor.decl;
- Ref = clang_getCursor(Unit, clang_getCursorSource(Cursor),
- curLine, curColumn);
- if (Ref.kind != CXCursor_FunctionDecl) {
+ Ref = clang_getCursorWithHint(Unit, clang_getCursorSource(Cursor),
+ curLine, curColumn, &hint);
+ if (Ref.kind == CXCursor_NoDeclFound) {
+ /* Nothing found here; that's fine. */
+ } else if (Ref.kind != CXCursor_FunctionDecl) {
printf("// CHECK: %s:%d:%d: ", basename(clang_getCursorSource(Ref)),
curLine, curColumn);
PrintCursor(Ref);
@@ -85,12 +91,23 @@ int main(int argc, char **argv) {
return 0;
}
{
- CXIndex Idx = clang_createIndex();
- CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]);
+ CXIndex Idx;
+ CXTranslationUnit TU;
enum CXCursorKind K = CXCursor_NotImplemented;
+
+ Idx = clang_createIndex(/* excludeDeclsFromPCH */ !strcmp(argv[2], "local") ? 1 : 0,
+ /* displayDiagnostics */ 1);
+
+ TU = clang_createTranslationUnit(Idx, argv[1]);
- if (!strcmp(argv[2], "all")) {
+ if (!TU) {
+ fprintf(stderr, "Unable to load translation unit!\n");
+ return 1;
+ }
+
+ if (!strcmp(argv[2], "all") || !strcmp(argv[2], "local")) {
clang_loadTranslationUnit(TU, TranslationUnitVisitor, 0);
+ clang_disposeTranslationUnit(TU);
return 1;
}
/* Perform some simple filtering. */
@@ -101,6 +118,7 @@ int main(int argc, char **argv) {
else if (!strcmp(argv[2], "typedef")) K = CXCursor_TypedefDecl;
clang_loadTranslationUnit(TU, TranslationUnitVisitor, &K);
+ clang_disposeTranslationUnit(TU);
return 1;
}
}
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index 0ad7efbc4839d..f77767c150e96 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -1139,9 +1139,6 @@ isysroot("isysroot", llvm::cl::value_desc("dir"), llvm::cl::init("/"),
// Add the clang headers, which are relative to the clang binary.
void AddClangIncludePaths(const char *Argv0, InitHeaderSearch *Init) {
- if (nostdclanginc)
- return;
-
llvm::sys::Path MainExecutablePath =
llvm::sys::Path::GetMainExecutable(Argv0,
(void*)(intptr_t)AddClangIncludePaths);
@@ -1243,7 +1240,8 @@ void InitializeIncludePaths(const char *Argv0, HeaderSearch &Headers,
Init.AddDefaultEnvVarPaths(Lang);
- AddClangIncludePaths(Argv0, &Init);
+ if (!nostdclanginc)
+ AddClangIncludePaths(Argv0, &Init);
if (!nostdinc)
Init.AddDefaultSystemIncludePaths(Lang, triple);
@@ -2190,8 +2188,7 @@ static void ProcessASTInputFile(const std::string &InFile, ProgActions PA,
Diagnostic &Diags, FileManager &FileMgr,
llvm::LLVMContext& Context) {
std::string Error;
- llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, Diags, FileMgr,
- &Error));
+ llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromPCHFile(InFile, &Error));
if (!AST) {
Diags.Report(FullSourceLoc(), diag::err_fe_invalid_ast_file) << Error;
return;
diff --git a/tools/index-test/index-test.cpp b/tools/index-test/index-test.cpp
index 103874c77d7d9..fce48edf26e08 100644
--- a/tools/index-test/index-test.cpp
+++ b/tools/index-test/index-test.cpp
@@ -225,8 +225,7 @@ int main(int argc, char **argv) {
std::string ErrMsg;
llvm::OwningPtr<ASTUnit> AST;
- AST.reset(ASTUnit::LoadFromPCHFile(InFile, Idxer.getDiagnostics(),
- Idxer.getFileManager(), &ErrMsg));
+ AST.reset(ASTUnit::LoadFromPCHFile(InFile, &ErrMsg));
if (!AST) {
llvm::errs() << "[" << InFile << "] Error: " << ErrMsg << '\n';
return 1;
@@ -244,7 +243,7 @@ int main(int argc, char **argv) {
if (!PointAtLocation.empty()) {
const std::string &Filename = PointAtLocation[0].FileName;
- const FileEntry *File = Idxer.getFileManager().getFile(Filename);
+ const FileEntry *File = FirstAST->getFileManager().getFile(Filename);
if (File == 0) {
llvm::errs() << "File '" << Filename << "' does not exist\n";
return 1;
@@ -253,7 +252,7 @@ int main(int argc, char **argv) {
// 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 = Idxer.getFileManager().getFile(FirstFile);
+ 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 "