summaryrefslogtreecommitdiffstats
path: root/tools/CIndex/CIndex.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/CIndex/CIndex.cpp')
-rw-r--r--tools/CIndex/CIndex.cpp777
1 files changed, 339 insertions, 438 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp
index 46732de..4681b939 100644
--- a/tools/CIndex/CIndex.cpp
+++ b/tools/CIndex/CIndex.cpp
@@ -4,7 +4,7 @@
//
// 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.
@@ -24,7 +24,6 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Frontend/ASTUnit.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -47,7 +46,7 @@ using namespace clang;
using namespace idx;
namespace {
-static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
+static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
{
NamedDecl *D = DRE->getDecl();
if (isa<VarDecl>(D))
@@ -56,7 +55,7 @@ static enum CXCursorKind TranslateDeclRefExpr(DeclRefExpr *DRE)
return CXCursor_FunctionRef;
else if (isa<EnumConstantDecl>(D))
return CXCursor_EnumConstantRef;
- else
+ else
return CXCursor_NotImplemented;
}
@@ -66,16 +65,16 @@ class CRefVisitor : public StmtVisitor<CRefVisitor> {
CXDecl CDecl;
CXDeclIterator Callback;
CXClientData CData;
-
+
void Call(enum CXCursorKind CK, Stmt *SRef) {
CXCursor C = { CK, CDecl, SRef };
Callback(CDecl, C, CData);
}
public:
- CRefVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
+ CRefVisitor(CXDecl C, CXDeclIterator cback, CXClientData D) :
CDecl(C), Callback(cback), CData(D) {}
-
+
void VisitStmt(Stmt *S) {
for (Stmt::child_iterator C = S->child_begin(), CEnd = S->child_end();
C != CEnd; ++C)
@@ -95,13 +94,13 @@ 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 &) {}
+ virtual void HandleDiagnostic(Diagnostic::Level, const DiagnosticInfo &) {}
};
// Translation Unit Visitor.
@@ -109,30 +108,30 @@ class TUVisitor : public DeclVisitor<TUVisitor> {
CXTranslationUnit TUnit;
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;
-
+
// Filter any implicit declarations (since the source info will be bogus).
if (ND->isImplicit())
return;
-
+
CXCursor C = { CK, ND, 0 };
Callback(TUnit, C, CData);
}
public:
- TUVisitor(CXTranslationUnit CTU,
+ TUVisitor(CXTranslationUnit CTU,
CXTranslationUnitIterator cback, CXClientData D,
- unsigned MaxPCHLevel) :
+ unsigned MaxPCHLevel) :
TUnit(CTU), Callback(cback), CData(D), MaxPCHLevel(MaxPCHLevel) {}
-
+
void VisitTranslationUnitDecl(TranslationUnitDecl *D) {
VisitDeclContext(dyn_cast<DeclContext>(D));
}
@@ -157,63 +156,63 @@ public:
}
void VisitObjCInterfaceDecl(ObjCInterfaceDecl *ND) {
Call(CXCursor_ObjCInterfaceDecl, ND);
- }
+ }
void VisitObjCProtocolDecl(ObjCProtocolDecl *ND) {
Call(CXCursor_ObjCProtocolDecl, ND);
}
void VisitTagDecl(TagDecl *ND) {
switch (ND->getTagKind()) {
- case TagDecl::TK_struct:
- Call(CXCursor_StructDecl, ND);
- break;
- case TagDecl::TK_class:
- Call(CXCursor_ClassDecl, ND);
- break;
- case TagDecl::TK_union:
- Call(CXCursor_UnionDecl, ND);
- break;
- case TagDecl::TK_enum:
- Call(CXCursor_EnumDecl, ND);
- break;
+ case TagDecl::TK_struct:
+ Call(CXCursor_StructDecl, ND);
+ break;
+ case TagDecl::TK_class:
+ Call(CXCursor_ClassDecl, ND);
+ break;
+ case TagDecl::TK_union:
+ Call(CXCursor_UnionDecl, ND);
+ break;
+ case TagDecl::TK_enum:
+ Call(CXCursor_EnumDecl, ND);
+ break;
}
}
- void VisitTypedefDecl(TypedefDecl *ND) {
- Call(CXCursor_TypedefDecl, ND);
- }
+ void VisitTypedefDecl(TypedefDecl *ND) {
+ Call(CXCursor_TypedefDecl, ND);
+ }
void VisitVarDecl(VarDecl *ND) {
Call(CXCursor_VarDecl, ND);
- }
+ }
};
-
+
// Declaration visitor.
class CDeclVisitor : public DeclVisitor<CDeclVisitor> {
CXDecl CDecl;
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,
- unsigned MaxPCHLevel) :
+ 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.
Call(CXCursor_ObjCClassRef, ND);
@@ -225,16 +224,16 @@ public:
if (D->getSuperClass())
Call(CXCursor_ObjCSuperClassRef, D);
- for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end(); I != E; ++I)
+ for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
+ E = D->protocol_end(); I != E; ++I)
Call(CXCursor_ObjCProtocolRef, *I);
VisitDeclContext(dyn_cast<DeclContext>(D));
}
void VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
- for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
- E = PID->protocol_end(); I != E; ++I)
+ for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
+ E = PID->protocol_end(); I != E; ++I)
Call(CXCursor_ObjCProtocolRef, *I);
-
+
VisitDeclContext(dyn_cast<DeclContext>(PID));
}
void VisitTagDecl(TagDecl *D) {
@@ -292,9 +291,9 @@ public:
};
class CIndexer : public Indexer {
-public:
- explicit CIndexer(Program *prog) : Indexer(*prog),
- OnlyLocalDecls(false),
+public:
+ explicit CIndexer(Program *prog) : Indexer(*prog),
+ OnlyLocalDecls(false),
DisplayDiagnostics(false) {}
virtual ~CIndexer() { delete &getProgram(); }
@@ -305,17 +304,17 @@ public:
bool getOnlyLocalDecls() const { return OnlyLocalDecls; }
void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; }
- void setDisplayDiagnostics(bool Display = true) {
+ 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;
};
@@ -360,63 +359,63 @@ const llvm::sys::Path& CIndexer::getClangPath() {
}
-static SourceLocation getLocationFromCursor(CXCursor C,
+static SourceLocation getLocationFromCursor(CXCursor C,
SourceManager &SourceMgr,
NamedDecl *ND) {
if (clang_isReference(C.kind)) {
switch (C.kind) {
- 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);
- return parentDecl->getLocation();
- }
- ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
- assert(OID && "clang_getCursorLine(): Missing category decl");
- return OID->getClassInterface()->getLocation();
- }
- case CXCursor_ObjCSuperClassRef: {
- ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
- assert(OID && "clang_getCursorLine(): Missing interface decl");
- return OID->getSuperClassLoc();
- }
- case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
- assert(OID && "clang_getCursorLine(): Missing protocol decl");
- return OID->getLocation();
- }
- 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_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);
+ return parentDecl->getLocation();
}
- case CXCursor_VarRef:
- case CXCursor_FunctionRef:
- 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();
+ ObjCCategoryDecl *OID = dyn_cast<ObjCCategoryDecl>(ND);
+ assert(OID && "clang_getCursorLine(): Missing category decl");
+ return OID->getClassInterface()->getLocation();
+ }
+ case CXCursor_ObjCSuperClassRef: {
+ ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
+ assert(OID && "clang_getCursorLine(): Missing interface decl");
+ return OID->getSuperClassLoc();
+ }
+ case CXCursor_ObjCProtocolRef: {
+ ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
+ assert(OID && "clang_getCursorLine(): Missing protocol decl");
+ return OID->getLocation();
+ }
+ 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: {
+ 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: {
- SLoc = dyn_cast<ObjCInterfaceDecl>(ND)->getClassLoc();
- break;
- }
- case Decl::ObjCProtocol: {
- SLoc = ND->getLocation(); /* FIXME: need to get the name location. */
- break;
- }
- default: {
- SLoc = ND->getLocation();
- break;
- }
+ case Decl::ObjCInterface: {
+ SLoc = dyn_cast<ObjCInterfaceDecl>(ND)->getClassLoc();
+ break;
+ }
+ case Decl::ObjCProtocol: {
+ SLoc = ND->getLocation(); /* FIXME: need to get the name location. */
+ break;
+ }
+ default: {
+ SLoc = ND->getLocation();
+ break;
+ }
}
if (SLoc.isInvalid())
return SourceLocation();
@@ -439,8 +438,7 @@ static CXString createCXString(const char *String, bool DupString = false) {
extern "C" {
CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
- int displayDiagnostics)
-{
+ int displayDiagnostics) {
CIndexer *CIdxr = new CIndexer(new Program());
if (excludeDeclarationsFromPCH)
CIdxr->setOnlyLocalDecls();
@@ -449,56 +447,55 @@ CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
return CIdxr;
}
-void clang_disposeIndex(CXIndex CIdx)
-{
+void clang_disposeIndex(CXIndex CIdx) {
assert(CIdx && "Passed null CXIndex");
delete static_cast<CIndexer *>(CIdx);
}
// FIXME: need to pass back error info.
-CXTranslationUnit clang_createTranslationUnit(
- CXIndex CIdx, const char *ast_filename)
-{
+CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
+ const char *ast_filename) {
assert(CIdx && "Passed null CXIndex");
CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
std::string astName(ast_filename);
std::string ErrMsg;
-
+
CXTranslationUnit TU =
- ASTUnit::LoadFromPCHFile(astName, &ErrMsg,
- CXXIdx->getDisplayDiagnostics() ?
- NULL : new IgnoreDiagnosticsClient(),
- CXXIdx->getOnlyLocalDecls(),
- /* UseBumpAllocator = */ true);
-
+ ASTUnit::LoadFromPCHFile(astName, &ErrMsg,
+ CXXIdx->getDisplayDiagnostics() ?
+ NULL : new IgnoreDiagnosticsClient(),
+ CXXIdx->getOnlyLocalDecls(),
+ /* UseBumpAllocator = */ true);
+
if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty())
llvm::errs() << "clang_createTranslationUnit: " << ErrMsg << '\n';
-
+
return TU;
}
-CXTranslationUnit clang_createTranslationUnitFromSourceFile(
- CXIndex CIdx,
- const char *source_filename,
- int num_command_line_args, const char **command_line_args) {
+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);
+ if (source_filename)
+ argv.push_back(source_filename);
// Generate a temporary name for the AST file.
argv.push_back("-o");
@@ -521,7 +518,7 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile(
// Keep the argument.
argv.push_back(arg);
}
-
+
// Add the null terminator.
argv.push_back(NULL);
@@ -533,10 +530,10 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile(
llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
/* redirects */ !CXXIdx->getDisplayDiagnostics() ? &Redirects[0] : NULL,
/* secondsToWait */ 0, /* memoryLimits */ 0, &ErrMsg);
-
+
if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty()) {
- llvm::errs() << "clang_createTranslationUnitFromSourceFile: " << ErrMsg
- << '\n' << "Arguments: \n";
+ 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)
@@ -547,45 +544,40 @@ CXTranslationUnit clang_createTranslationUnitFromSourceFile(
// Finally, we create the translation unit from the ast file.
ASTUnit *ATU = static_cast<ASTUnit *>(
- clang_createTranslationUnit(CIdx, astTmpFile));
+ clang_createTranslationUnit(CIdx, astTmpFile));
if (ATU)
ATU->unlinkTemporaryFile();
return ATU;
}
-void clang_disposeTranslationUnit(
- CXTranslationUnit CTUnit)
-{
+void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
assert(CTUnit && "Passed null CXTranslationUnit");
delete static_cast<ASTUnit *>(CTUnit);
}
-
-CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit)
-{
+
+CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
assert(CTUnit && "Passed null CXTranslationUnit");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
return createCXString(CXXUnit->getOriginalSourceFileName().c_str(), true);
}
-void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
+void clang_loadTranslationUnit(CXTranslationUnit CTUnit,
CXTranslationUnitIterator callback,
- CXClientData CData)
-{
+ CXClientData CData) {
assert(CTUnit && "Passed null CXTranslationUnit");
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());
}
-void clang_loadDeclaration(CXDecl Dcl,
- CXDeclIterator callback,
- CXClientData CData)
-{
+void clang_loadDeclaration(CXDecl Dcl,
+ CXDeclIterator callback,
+ CXClientData CData) {
assert(Dcl && "Passed null CXDecl");
-
+
CDeclVisitor DVisit(Dcl, callback, CData,
static_cast<Decl *>(Dcl)->getPCHLevel());
DVisit.Visit(static_cast<Decl *>(Dcl));
@@ -593,14 +585,14 @@ void clang_loadDeclaration(CXDecl Dcl,
// Some notes on CXEntity:
//
-// - Since the 'ordinary' namespace includes functions, data, typedefs,
-// ObjC interfaces, thecurrent algorithm is a bit naive (resulting in one
+// - Since the 'ordinary' namespace includes functions, data, typedefs,
+// ObjC interfaces, thecurrent algorithm is a bit naive (resulting in one
// entity for 2 different types). For example:
//
// module1.m: @interface Foo @end Foo *x;
// module2.m: void Foo(int);
//
-// - Since the unique name spans translation units, static data/functions
+// - Since the unique name spans translation units, static data/functions
// within a CXTranslationUnit are *not* currently represented by entities.
// As a result, there will be no entity for the following:
//
@@ -608,29 +600,27 @@ void clang_loadDeclaration(CXDecl Dcl,
//
-const char *clang_getDeclarationName(CXEntity)
-{
+const char *clang_getDeclarationName(CXEntity) {
return "";
}
-const char *clang_getURI(CXEntity)
-{
+
+const char *clang_getURI(CXEntity) {
return "";
}
-CXEntity clang_getEntity(const char *URI)
-{
+CXEntity clang_getEntity(const char *URI) {
return 0;
}
//
// CXDecl Operations.
//
-CXEntity clang_getEntityFromDecl(CXDecl)
-{
+
+CXEntity clang_getEntityFromDecl(CXDecl) {
return 0;
}
-CXString clang_getDeclSpelling(CXDecl AnonDecl)
-{
+
+CXString clang_getDeclSpelling(CXDecl AnonDecl) {
assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
@@ -649,24 +639,21 @@ CXString clang_getDeclSpelling(CXDecl AnonDecl)
return createCXString("");
}
-unsigned clang_getDeclLine(CXDecl AnonDecl)
-{
+unsigned clang_getDeclLine(CXDecl AnonDecl) {
assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
return SourceMgr.getSpellingLineNumber(ND->getLocation());
}
-unsigned clang_getDeclColumn(CXDecl AnonDecl)
-{
+unsigned clang_getDeclColumn(CXDecl AnonDecl) {
assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
return SourceMgr.getSpellingColumnNumber(ND->getLocation());
}
-const char *clang_getDeclSource(CXDecl AnonDecl)
-{
+const char *clang_getDeclSource(CXDecl AnonDecl) {
assert(AnonDecl && "Passed null CXDecl");
FileEntry *FEnt = static_cast<FileEntry *>(clang_getDeclSourceFile(AnonDecl));
assert (FEnt && "Cannot find FileEntry for Decl");
@@ -674,8 +661,7 @@ const char *clang_getDeclSource(CXDecl AnonDecl)
}
static const FileEntry *getFileEntryFromSourceLocation(SourceManager &SMgr,
- SourceLocation SLoc)
-{
+ SourceLocation SLoc) {
FileID FID;
if (SLoc.isFileID())
FID = SMgr.getFileID(SLoc);
@@ -684,8 +670,7 @@ static const FileEntry *getFileEntryFromSourceLocation(SourceManager &SMgr,
return SMgr.getFileEntryForID(FID);
}
-CXFile clang_getDeclSourceFile(CXDecl AnonDecl)
-{
+CXFile clang_getDeclSourceFile(CXDecl AnonDecl) {
assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
@@ -704,145 +689,143 @@ time_t clang_getFileTime(CXFile SFile) {
return FEnt->getModificationTime();
}
-CXString clang_getCursorSpelling(CXCursor C)
-{
+CXString clang_getCursorSpelling(CXCursor C) {
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
if (clang_isReference(C.kind)) {
switch (C.kind) {
- case CXCursor_ObjCSuperClassRef: {
- ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
- assert(OID && "clang_getCursorLine(): Missing interface decl");
- return createCXString(OID->getSuperClass()->getIdentifier()
- ->getNameStart());
- }
- case CXCursor_ObjCClassRef: {
- if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND))
- return createCXString(OID->getIdentifier()->getNameStart());
-
- ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(ND);
- assert(OCD && "clang_getCursorLine(): Missing category decl");
- return createCXString(OCD->getClassInterface()->getIdentifier()
- ->getNameStart());
- }
- case CXCursor_ObjCProtocolRef: {
- ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
- assert(OID && "clang_getCursorLine(): Missing protocol decl");
+ case CXCursor_ObjCSuperClassRef: {
+ ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND);
+ assert(OID && "clang_getCursorLine(): Missing interface decl");
+ return createCXString(OID->getSuperClass()->getIdentifier()
+ ->getNameStart());
+ }
+ case CXCursor_ObjCClassRef: {
+ if (ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(ND))
return createCXString(OID->getIdentifier()->getNameStart());
- }
- case CXCursor_ObjCSelectorRef: {
- ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
- static_cast<Stmt *>(C.stmt));
- assert(OME && "clang_getCursorLine(): Missing message expr");
- return createCXString(OME->getSelector().getAsString().c_str(), true);
- }
- case CXCursor_VarRef:
- case CXCursor_FunctionRef:
- case CXCursor_EnumConstantRef: {
- DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
- static_cast<Stmt *>(C.stmt));
- assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
- return createCXString(DRE->getDecl()->getIdentifier()->getNameStart());
- }
- default:
- return createCXString("<not implemented>");
+
+ ObjCCategoryDecl *OCD = dyn_cast<ObjCCategoryDecl>(ND);
+ assert(OCD && "clang_getCursorLine(): Missing category decl");
+ return createCXString(OCD->getClassInterface()->getIdentifier()
+ ->getNameStart());
+ }
+ case CXCursor_ObjCProtocolRef: {
+ ObjCProtocolDecl *OID = dyn_cast<ObjCProtocolDecl>(ND);
+ assert(OID && "clang_getCursorLine(): Missing protocol decl");
+ return createCXString(OID->getIdentifier()->getNameStart());
+ }
+ case CXCursor_ObjCSelectorRef: {
+ ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(
+ static_cast<Stmt *>(C.stmt));
+ assert(OME && "clang_getCursorLine(): Missing message expr");
+ return createCXString(OME->getSelector().getAsString().c_str(), true);
+ }
+ case CXCursor_VarRef:
+ case CXCursor_FunctionRef:
+ case CXCursor_EnumConstantRef: {
+ DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
+ static_cast<Stmt *>(C.stmt));
+ assert(DRE && "clang_getCursorLine(): Missing decl ref expr");
+ return createCXString(DRE->getDecl()->getIdentifier()->getNameStart());
+ }
+ default:
+ return createCXString("<not implemented>");
}
}
return clang_getDeclSpelling(C.decl);
}
-const char *clang_getCursorKindSpelling(enum CXCursorKind Kind)
-{
+const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) {
switch (Kind) {
- case CXCursor_FunctionDecl: return "FunctionDecl";
- case CXCursor_TypedefDecl: return "TypedefDecl";
- case CXCursor_EnumDecl: return "EnumDecl";
- case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
- case CXCursor_StructDecl: return "StructDecl";
- case CXCursor_UnionDecl: return "UnionDecl";
- case CXCursor_ClassDecl: return "ClassDecl";
- case CXCursor_FieldDecl: return "FieldDecl";
- case CXCursor_VarDecl: return "VarDecl";
- case CXCursor_ParmDecl: return "ParmDecl";
- case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
- case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
- case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
- case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
- case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
- case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
- case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
- case CXCursor_FunctionDefn: return "FunctionDefn";
- case CXCursor_ObjCInstanceMethodDefn: return "ObjCInstanceMethodDefn";
- case CXCursor_ObjCClassMethodDefn: return "ObjCClassMethodDefn";
- case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
- case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
- case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
- case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
- case CXCursor_ObjCClassRef: return "ObjCClassRef";
- case CXCursor_ObjCSelectorRef: return "ObjCSelectorRef";
-
- case CXCursor_VarRef: return "VarRef";
- case CXCursor_FunctionRef: return "FunctionRef";
- case CXCursor_EnumConstantRef: return "EnumConstantRef";
- case CXCursor_MemberRef: return "MemberRef";
-
- case CXCursor_InvalidFile: return "InvalidFile";
- case CXCursor_NoDeclFound: return "NoDeclFound";
- case CXCursor_NotImplemented: return "NotImplemented";
- default: return "<not implemented>";
+ case CXCursor_FunctionDecl: return "FunctionDecl";
+ case CXCursor_TypedefDecl: return "TypedefDecl";
+ case CXCursor_EnumDecl: return "EnumDecl";
+ case CXCursor_EnumConstantDecl: return "EnumConstantDecl";
+ case CXCursor_StructDecl: return "StructDecl";
+ case CXCursor_UnionDecl: return "UnionDecl";
+ case CXCursor_ClassDecl: return "ClassDecl";
+ case CXCursor_FieldDecl: return "FieldDecl";
+ case CXCursor_VarDecl: return "VarDecl";
+ case CXCursor_ParmDecl: return "ParmDecl";
+ case CXCursor_ObjCInterfaceDecl: return "ObjCInterfaceDecl";
+ case CXCursor_ObjCCategoryDecl: return "ObjCCategoryDecl";
+ case CXCursor_ObjCProtocolDecl: return "ObjCProtocolDecl";
+ case CXCursor_ObjCPropertyDecl: return "ObjCPropertyDecl";
+ case CXCursor_ObjCIvarDecl: return "ObjCIvarDecl";
+ case CXCursor_ObjCInstanceMethodDecl: return "ObjCInstanceMethodDecl";
+ case CXCursor_ObjCClassMethodDecl: return "ObjCClassMethodDecl";
+ case CXCursor_FunctionDefn: return "FunctionDefn";
+ case CXCursor_ObjCInstanceMethodDefn: return "ObjCInstanceMethodDefn";
+ case CXCursor_ObjCClassMethodDefn: return "ObjCClassMethodDefn";
+ case CXCursor_ObjCClassDefn: return "ObjCClassDefn";
+ case CXCursor_ObjCCategoryDefn: return "ObjCCategoryDefn";
+ case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef";
+ case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef";
+ case CXCursor_ObjCClassRef: return "ObjCClassRef";
+ case CXCursor_ObjCSelectorRef: return "ObjCSelectorRef";
+
+ case CXCursor_VarRef: return "VarRef";
+ case CXCursor_FunctionRef: return "FunctionRef";
+ case CXCursor_EnumConstantRef: return "EnumConstantRef";
+ case CXCursor_MemberRef: return "MemberRef";
+
+ case CXCursor_InvalidFile: return "InvalidFile";
+ case CXCursor_NoDeclFound: return "NoDeclFound";
+ case CXCursor_NotImplemented: return "NotImplemented";
+ default: return "<not implemented>";
}
}
static enum CXCursorKind TranslateKind(Decl *D) {
switch (D->getKind()) {
- case Decl::Function: return CXCursor_FunctionDecl;
- case Decl::Typedef: return CXCursor_TypedefDecl;
- case Decl::Enum: return CXCursor_EnumDecl;
- case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
- case Decl::Record: return CXCursor_StructDecl; // FIXME: union/class
- case Decl::Field: return CXCursor_FieldDecl;
- case Decl::Var: return CXCursor_VarDecl;
- case Decl::ParmVar: return CXCursor_ParmDecl;
- case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
- case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
- case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
- case Decl::ObjCMethod: {
- ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
- if (MD->isInstanceMethod())
- return CXCursor_ObjCInstanceMethodDecl;
- return CXCursor_ObjCClassMethodDecl;
- }
- default: break;
+ case Decl::Function: return CXCursor_FunctionDecl;
+ case Decl::Typedef: return CXCursor_TypedefDecl;
+ case Decl::Enum: return CXCursor_EnumDecl;
+ case Decl::EnumConstant: return CXCursor_EnumConstantDecl;
+ case Decl::Record: return CXCursor_StructDecl; // FIXME: union/class
+ case Decl::Field: return CXCursor_FieldDecl;
+ case Decl::Var: return CXCursor_VarDecl;
+ case Decl::ParmVar: return CXCursor_ParmDecl;
+ case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl;
+ case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl;
+ case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl;
+ case Decl::ObjCMethod: {
+ ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D);
+ if (MD->isInstanceMethod())
+ return CXCursor_ObjCInstanceMethodDecl;
+ return CXCursor_ObjCClassMethodDecl;
+ }
+ default: break;
}
return CXCursor_NotImplemented;
}
//
// CXCursor Operations.
//
-CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
- unsigned line, unsigned column)
-{
+
+CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
+ unsigned line, unsigned column) {
assert(CTUnit && "Passed null CXTranslationUnit");
ASTUnit *CXXUnit = static_cast<ASTUnit *>(CTUnit);
-
+
FileManager &FMgr = CXXUnit->getFileManager();
- const FileEntry *File = FMgr.getFile(source_name,
- source_name+strlen(source_name));
+ const FileEntry *File = FMgr.getFile(source_name,
+ source_name+strlen(source_name));
if (!File) {
CXCursor C = { CXCursor_InvalidFile, 0, 0 };
return C;
}
- SourceLocation SLoc =
+ SourceLocation SLoc =
CXXUnit->getSourceManager().getLocation(File, line, column);
-
+
ASTLocation LastLoc = CXXUnit->getLastASTLocation();
- ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
+ ASTLocation ALoc = ResolveLocationInAST(CXXUnit->getASTContext(), SLoc,
&LastLoc);
if (ALoc.isValid())
CXXUnit->setLastASTLocation(ALoc);
-
+
Decl *Dcl = ALoc.getParentDecl();
if (ALoc.isNamedRef())
Dcl = ALoc.AsNamedRef().ND;
@@ -855,7 +838,7 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
} else if (ObjCMessageExpr *MExp = dyn_cast<ObjCMessageExpr>(Stm)) {
CXCursor C = { CXCursor_ObjCSelectorRef, Dcl, MExp };
return C;
- }
+ }
// Fall through...treat as a decl, not a ref.
}
if (ALoc.isNamedRef()) {
@@ -868,7 +851,7 @@ CXCursor clang_getCursor(CXTranslationUnit CTUnit, const char *source_name,
return C;
}
}
- CXCursor C = { TranslateKind(Dcl), Dcl, 0 };
+ CXCursor C = { TranslateKind(Dcl), Dcl, 0 };
return C;
}
CXCursor C = { CXCursor_NoDeclFound, 0, 0 };
@@ -886,38 +869,32 @@ CXCursor clang_getNullCursor(void) {
unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
return X.kind == Y.kind && X.decl == Y.decl && X.stmt == Y.stmt;
}
-
-CXCursor clang_getCursorFromDecl(CXDecl AnonDecl)
-{
+
+CXCursor clang_getCursorFromDecl(CXDecl AnonDecl) {
assert(AnonDecl && "Passed null CXDecl");
NamedDecl *ND = static_cast<NamedDecl *>(AnonDecl);
-
+
CXCursor C = { TranslateKind(ND), ND, 0 };
return C;
}
-unsigned clang_isInvalid(enum CXCursorKind K)
-{
+unsigned clang_isInvalid(enum CXCursorKind K) {
return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
}
-unsigned clang_isDeclaration(enum CXCursorKind K)
-{
+unsigned clang_isDeclaration(enum CXCursorKind K) {
return K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl;
}
-unsigned clang_isReference(enum CXCursorKind K)
-{
+unsigned clang_isReference(enum CXCursorKind K) {
return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
}
-unsigned clang_isDefinition(enum CXCursorKind K)
-{
+unsigned clang_isDefinition(enum CXCursorKind K) {
return K >= CXCursor_FirstDefn && K <= CXCursor_LastDefn;
}
-CXCursorKind clang_getCursorKind(CXCursor C)
-{
+CXCursorKind clang_getCursorKind(CXCursor C) {
return C.kind;
}
@@ -939,14 +916,13 @@ static Decl *getDeclFromExpr(Stmt *E) {
return 0;
}
-CXDecl clang_getCursorDecl(CXCursor C)
-{
+CXDecl clang_getCursorDecl(CXCursor C) {
if (clang_isDeclaration(C.kind))
return C.decl;
-
+
if (clang_isReference(C.kind)) {
if (C.stmt) {
- if (C.kind == CXCursor_ObjCClassRef ||
+ if (C.kind == CXCursor_ObjCClassRef ||
C.kind == CXCursor_ObjCProtocolRef)
return static_cast<Stmt *>(C.stmt);
else
@@ -957,44 +933,40 @@ CXDecl clang_getCursorDecl(CXCursor C)
return 0;
}
-unsigned clang_getCursorLine(CXCursor C)
-{
+unsigned clang_getCursorLine(CXCursor C) {
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
-
+
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
return SourceMgr.getSpellingLineNumber(SLoc);
}
-// Access string.
const char *clang_getCString(CXString string) {
return string.Spelling;
}
-
-// Free CXString.
+
void clang_disposeString(CXString string) {
if (string.MustFreeString)
free((void*)string.Spelling);
}
-unsigned clang_getCursorColumn(CXCursor C)
-{
+unsigned clang_getCursorColumn(CXCursor C) {
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
-
+
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
return SourceMgr.getSpellingColumnNumber(SLoc);
}
-const char *clang_getCursorSource(CXCursor C)
-{
+
+const char *clang_getCursorSource(CXCursor C) {
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
-
+
SourceLocation SLoc = getLocationFromCursor(C, SourceMgr, ND);
-
+
if (SLoc.isFileID()) {
const char *bufferName = SourceMgr.getBufferName(SLoc);
return bufferName[0] == '<' ? NULL : bufferName;
@@ -1003,7 +975,7 @@ const char *clang_getCursorSource(CXCursor C)
// 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
+ const llvm::MemoryBuffer *Buffer
= SourceMgr.getBuffer(SourceMgr.getDecomposedSpellingLoc(SLoc).first);
if (!Buffer)
return 0;
@@ -1011,29 +983,27 @@ const char *clang_getCursorSource(CXCursor C)
return Buffer->getBufferIdentifier();
}
-CXFile clang_getCursorSourceFile(CXCursor C)
-{
+CXFile clang_getCursorSourceFile(CXCursor C) {
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
SourceManager &SourceMgr = ND->getASTContext().getSourceManager();
-
+
return (void *)getFileEntryFromSourceLocation(SourceMgr,
- getLocationFromCursor(C,SourceMgr, ND));
+ getLocationFromCursor(C,SourceMgr, ND));
}
-void clang_getDefinitionSpellingAndExtent(CXCursor C,
+void clang_getDefinitionSpellingAndExtent(CXCursor C,
const char **startBuf,
const char **endBuf,
unsigned *startLine,
unsigned *startColumn,
unsigned *endLine,
- unsigned *endColumn)
-{
+ unsigned *endColumn) {
assert(C.decl && "CXCursor has null decl");
NamedDecl *ND = static_cast<NamedDecl *>(C.decl);
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());
@@ -1043,20 +1013,20 @@ void clang_getDefinitionSpellingAndExtent(CXCursor C,
*endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
}
-enum CXCompletionChunkKind
+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;
+ return CXCompletionChunk_Optional;
case CodeCompletionString::CK_Placeholder:
return CXCompletionChunk_Placeholder;
case CodeCompletionString::CK_Informative:
@@ -1082,17 +1052,17 @@ clang_getCompletionChunkKind(CXCompletionString completion_string,
case CodeCompletionString::CK_Comma:
return CXCompletionChunk_Comma;
}
-
+
// Should be unreachable, but let's be careful.
return CXCompletionChunk_Text;
}
-
+
const char *clang_getCompletionChunkText(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:
@@ -1109,23 +1079,23 @@ const char *clang_getCompletionChunkText(CXCompletionString completion_string,
case CodeCompletionString::CK_RightAngle:
case CodeCompletionString::CK_Comma:
return (*CCStr)[chunk_number].Text;
-
+
case CodeCompletionString::CK_Optional:
// Note: treated as an empty text block.
return 0;
}
-
+
// Should be unreachable, but let's be careful.
return 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:
@@ -1142,51 +1112,34 @@ clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
case CodeCompletionString::CK_RightAngle:
case CodeCompletionString::CK_Comma:
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 CXCursorKind parseResultKind(llvm::StringRef Str) {
- return llvm::StringSwitch<CXCursorKind>(Str)
- .Case("Typedef", CXCursor_TypedefDecl)
- .Case("Struct", CXCursor_StructDecl)
- .Case("Union", CXCursor_UnionDecl)
- .Case("Class", CXCursor_ClassDecl)
- .Case("Enum", CXCursor_EnumDecl)
- .Case("Field", CXCursor_FieldDecl)
- .Case("EnumConstant", CXCursor_EnumConstantDecl)
- .Case("Function", CXCursor_FunctionDecl)
- // FIXME: Hacks here to make C++ member functions look like C functions
- .Case("CXXMethod", CXCursor_FunctionDecl)
- .Case("CXXConstructor", CXCursor_FunctionDecl)
- .Case("CXXDestructor", CXCursor_FunctionDecl)
- .Case("CXXConversion", CXCursor_FunctionDecl)
- .Case("Var", CXCursor_VarDecl)
- .Case("ParmVar", CXCursor_ParmDecl)
- .Case("ObjCInterface", CXCursor_ObjCInterfaceDecl)
- .Case("ObjCCategory", CXCursor_ObjCCategoryDecl)
- .Case("ObjCProtocol", CXCursor_ObjCProtocolDecl)
- .Case("ObjCProperty", CXCursor_ObjCPropertyDecl)
- .Case("ObjCIvar", CXCursor_ObjCIvarDecl)
- .Case("ObjCInstanceMethod", CXCursor_ObjCInstanceMethodDecl)
- .Case("ObjCClassMethod", CXCursor_ObjCClassMethodDecl)
- .Default(CXCursor_NotImplemented);
+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;
}
-
-void clang_codeComplete(CXIndex CIdx,
+
+void clang_codeComplete(CXIndex CIdx,
const char *source_filename,
- int num_command_line_args,
+ int num_command_line_args,
const char **command_line_args,
const char *complete_filename,
unsigned complete_line,
@@ -1195,15 +1148,15 @@ void clang_codeComplete(CXIndex CIdx,
CXClientData client_data) {
// The indexer, which is mainly used to determine where diagnostics go.
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 = CXXIdx->getClangPath();
argv.push_back(ClangPath.c_str());
-
- // Add the '-fsyntax-only' argument so that we only perform a basic
+
+ // Add the '-fsyntax-only' argument so that we only perform a basic
// syntax check of the code.
argv.push_back("-fsyntax-only");
@@ -1220,12 +1173,12 @@ void clang_codeComplete(CXIndex CIdx,
argv.push_back(code_complete_at.c_str());
argv.push_back("-Xclang");
argv.push_back("-no-code-completion-debug-printer");
-
+
// 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);
-
+ 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]) {
@@ -1238,19 +1191,19 @@ void clang_codeComplete(CXIndex CIdx,
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 AST file.
char tmpFile[L_tmpnam];
char *tmpFileName = tmpnam(tmpFile);
llvm::sys::Path ResultsFile(tmpFileName);
-
+
// Invoke 'clang'.
llvm::sys::Path DevNull; // leave empty, causes redirection to /dev/null
// on Unix or NUL (Windows).
@@ -1258,12 +1211,12 @@ void clang_codeComplete(CXIndex CIdx,
const llvm::sys::Path *Redirects[] = { &DevNull, &ResultsFile, &DevNull, 0 };
llvm::sys::Program::ExecuteAndWait(ClangPath, &argv[0], /* env */ NULL,
/* redirects */ &Redirects[0],
- /* secondsToWait */ 0,
+ /* secondsToWait */ 0,
/* memoryLimits */ 0, &ErrMsg);
-
+
if (CXXIdx->getDisplayDiagnostics() && !ErrMsg.empty()) {
- llvm::errs() << "clang_codeComplete: " << ErrMsg
- << '\n' << "Arguments: \n";
+ llvm::errs() << "clang_codeComplete: " << ErrMsg
+ << '\n' << "Arguments: \n";
for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
I!=E; ++I) {
if (*I)
@@ -1277,84 +1230,32 @@ void clang_codeComplete(CXIndex CIdx,
using llvm::StringRef;
if (MemoryBuffer *F = MemoryBuffer::getFile(ResultsFile.c_str())) {
StringRef Buffer = F->getBuffer();
- do {
- StringRef::size_type CompletionIdx = Buffer.find("COMPLETION:");
- StringRef::size_type OverloadIdx = Buffer.find("OVERLOAD:");
- if (CompletionIdx == StringRef::npos && OverloadIdx == StringRef::npos)
+ for (const char *Str = Buffer.data(), *StrEnd = Str + Buffer.size();
+ Str < StrEnd;) {
+ unsigned KindValue;
+ if (ReadUnsigned(Str, StrEnd, KindValue))
break;
-
- if (OverloadIdx < CompletionIdx) {
- // Parse an overload result.
- Buffer = Buffer.substr(OverloadIdx);
-
- // Skip past the OVERLOAD:
- Buffer = Buffer.substr(Buffer.find(':') + 1);
-
- // Find the entire completion string.
- StringRef::size_type EOL = Buffer.find_first_of("\n\r");
- if (EOL == StringRef::npos)
- continue;
-
- StringRef Line = Buffer.substr(0, EOL);
- Buffer = Buffer.substr(EOL + 1);
- CodeCompletionString *CCStr = CodeCompletionString::Deserialize(Line);
- if (!CCStr || CCStr->empty())
- continue;
-
+
+ CodeCompletionString *CCStr
+ = CodeCompletionString::Deserialize(Str, StrEnd);
+ if (!CCStr)
+ continue;
+
+ if (!CCStr->empty()) {
// Vend the code-completion result to the caller.
CXCompletionResult Result;
- Result.CursorKind = CXCursor_NotImplemented;
+ Result.CursorKind = (CXCursorKind)KindValue;
Result.CompletionString = CCStr;
if (completion_iterator)
completion_iterator(&Result, client_data);
- delete CCStr;
-
- continue;
}
-
- // Parse a completion result.
- Buffer = Buffer.substr(CompletionIdx);
-
- // Skip past the COMPLETION:
- Buffer = Buffer.substr(Buffer.find(':') + 1);
-
- // Get the rank
- unsigned Rank = 0;
- StringRef::size_type AfterRank = Buffer.find(':');
- Buffer.substr(0, AfterRank).getAsInteger(10, Rank);
- Buffer = Buffer.substr(AfterRank + 1);
-
- // Get the kind of result.
- StringRef::size_type AfterKind = Buffer.find(':');
- StringRef Kind = Buffer.substr(0, AfterKind);
- Buffer = Buffer.substr(AfterKind + 1);
-
- // Skip over any whitespace.
- Buffer = Buffer.substr(Buffer.find_first_not_of(" \t"));
-
- // Find the entire completion string.
- StringRef::size_type EOL = Buffer.find_first_of("\n\r");
- if (EOL == StringRef::npos)
- continue;
-
- StringRef Line = Buffer.substr(0, EOL);
- Buffer = Buffer.substr(EOL + 1);
- CodeCompletionString *CCStr = CodeCompletionString::Deserialize(Line);
- if (!CCStr || CCStr->empty())
- continue;
-
- // Vend the code-completion result to the caller.
- CXCompletionResult Result;
- Result.CursorKind = parseResultKind(Kind);
- Result.CompletionString = CCStr;
- if (completion_iterator)
- completion_iterator(&Result, client_data);
+
delete CCStr;
- } while (true);
+ };
delete F;
- }
-
+ }
+
ResultsFile.eraseFromDisk();
}
-
+
} // end extern "C"
OpenPOWER on IntegriCloud