Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@@ -0,0 +1,139 @@
//===- ARCMigrate.cpp - Clang-C ARC Migration 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 ARC Migration library.
//
//===----------------------------------------------------------------------===//
#include "clang-c/Index.h"
#include "CXString.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/Config/config.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "llvm/Support/FileSystem.h"
using namespace clang;
using namespace arcmt;
namespace {
struct Remap {
std::vector<std::pair<std::string, std::string> > Vec;
};
} // anonymous namespace.
//===----------------------------------------------------------------------===//
// libClang public APIs.
//===----------------------------------------------------------------------===//
CXRemapping clang_getRemappings(const char *migrate_dir_path) {
#if !CLANG_ENABLE_ARCMT
llvm::errs() << "error: feature not enabled in this build\n";
return nullptr;
#else
bool Logging = ::getenv("LIBCLANG_LOGGING");
if (!migrate_dir_path) {
if (Logging)
llvm::errs() << "clang_getRemappings was called with NULL parameter\n";
return nullptr;
}
if (!llvm::sys::fs::exists(migrate_dir_path)) {
if (Logging) {
llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path
<< "\")\n";
llvm::errs() << "\"" << migrate_dir_path << "\" does not exist\n";
}
return nullptr;
}
TextDiagnosticBuffer diagBuffer;
std::unique_ptr<Remap> remap(new Remap());
bool err = arcmt::getFileRemappings(remap->Vec, migrate_dir_path,&diagBuffer);
if (err) {
if (Logging) {
llvm::errs() << "Error by clang_getRemappings(\"" << migrate_dir_path
<< "\")\n";
for (TextDiagnosticBuffer::const_iterator
I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
llvm::errs() << I->second << '\n';
}
return nullptr;
}
return remap.release();
#endif
}
CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
unsigned numFiles) {
#if !CLANG_ENABLE_ARCMT
llvm::errs() << "error: feature not enabled in this build\n";
return nullptr;
#else
bool Logging = ::getenv("LIBCLANG_LOGGING");
std::unique_ptr<Remap> remap(new Remap());
if (numFiles == 0) {
if (Logging)
llvm::errs() << "clang_getRemappingsFromFileList was called with "
"numFiles=0\n";
return remap.release();
}
if (!filePaths) {
if (Logging)
llvm::errs() << "clang_getRemappingsFromFileList was called with "
"NULL filePaths\n";
return nullptr;
}
TextDiagnosticBuffer diagBuffer;
SmallVector<StringRef, 32> Files(filePaths, filePaths + numFiles);
bool err = arcmt::getFileRemappingsFromFileList(remap->Vec, Files,
&diagBuffer);
if (err) {
if (Logging) {
llvm::errs() << "Error by clang_getRemappingsFromFileList\n";
for (TextDiagnosticBuffer::const_iterator
I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
llvm::errs() << I->second << '\n';
}
return remap.release();
}
return remap.release();
#endif
}
unsigned clang_remap_getNumFiles(CXRemapping map) {
return static_cast<Remap *>(map)->Vec.size();
}
void clang_remap_getFilenames(CXRemapping map, unsigned index,
CXString *original, CXString *transformed) {
if (original)
*original = cxstring::createDup(
static_cast<Remap *>(map)->Vec[index].first);
if (transformed)
*transformed = cxstring::createDup(
static_cast<Remap *>(map)->Vec[index].second);
}
void clang_remap_dispose(CXRemapping map) {
delete static_cast<Remap *>(map);
}

View File

@@ -0,0 +1,151 @@
//===- BuildSystem.cpp - Utilities for use by build systems ---------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements various utilities for use by build systems.
//
//===----------------------------------------------------------------------===//
#include "clang-c/BuildSystem.h"
#include "CXString.h"
#include "clang/Basic/VirtualFileSystem.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace llvm::sys;
unsigned long long clang_getBuildSessionTimestamp(void) {
return llvm::sys::toTimeT(std::chrono::system_clock::now());
}
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(clang::vfs::YAMLVFSWriter,
CXVirtualFileOverlay)
CXVirtualFileOverlay clang_VirtualFileOverlay_create(unsigned) {
return wrap(new clang::vfs::YAMLVFSWriter());
}
enum CXErrorCode
clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay VFO,
const char *virtualPath,
const char *realPath) {
if (!VFO || !virtualPath || !realPath)
return CXError_InvalidArguments;
if (!path::is_absolute(virtualPath))
return CXError_InvalidArguments;
if (!path::is_absolute(realPath))
return CXError_InvalidArguments;
for (path::const_iterator
PI = path::begin(virtualPath),
PE = path::end(virtualPath); PI != PE; ++PI) {
StringRef Comp = *PI;
if (Comp == "." || Comp == "..")
return CXError_InvalidArguments;
}
unwrap(VFO)->addFileMapping(virtualPath, realPath);
return CXError_Success;
}
enum CXErrorCode
clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay VFO,
int caseSensitive) {
if (!VFO)
return CXError_InvalidArguments;
unwrap(VFO)->setCaseSensitivity(caseSensitive);
return CXError_Success;
}
enum CXErrorCode
clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay VFO, unsigned,
char **out_buffer_ptr,
unsigned *out_buffer_size) {
if (!VFO || !out_buffer_ptr || !out_buffer_size)
return CXError_InvalidArguments;
llvm::SmallString<256> Buf;
llvm::raw_svector_ostream OS(Buf);
unwrap(VFO)->write(OS);
StringRef Data = OS.str();
*out_buffer_ptr = (char*)malloc(Data.size());
*out_buffer_size = Data.size();
memcpy(*out_buffer_ptr, Data.data(), Data.size());
return CXError_Success;
}
void clang_free(void *buffer) {
free(buffer);
}
void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay VFO) {
delete unwrap(VFO);
}
struct CXModuleMapDescriptorImpl {
std::string ModuleName;
std::string UmbrellaHeader;
};
CXModuleMapDescriptor clang_ModuleMapDescriptor_create(unsigned) {
return new CXModuleMapDescriptorImpl();
}
enum CXErrorCode
clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor MMD,
const char *name) {
if (!MMD || !name)
return CXError_InvalidArguments;
MMD->ModuleName = name;
return CXError_Success;
}
enum CXErrorCode
clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor MMD,
const char *name) {
if (!MMD || !name)
return CXError_InvalidArguments;
MMD->UmbrellaHeader = name;
return CXError_Success;
}
enum CXErrorCode
clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor MMD, unsigned,
char **out_buffer_ptr,
unsigned *out_buffer_size) {
if (!MMD || !out_buffer_ptr || !out_buffer_size)
return CXError_InvalidArguments;
llvm::SmallString<256> Buf;
llvm::raw_svector_ostream OS(Buf);
OS << "framework module " << MMD->ModuleName << " {\n";
OS << " umbrella header \"";
OS.write_escaped(MMD->UmbrellaHeader) << "\"\n";
OS << '\n';
OS << " export *\n";
OS << " module * { export * }\n";
OS << "}\n";
StringRef Data = OS.str();
*out_buffer_ptr = (char*)malloc(Data.size());
*out_buffer_size = Data.size();
memcpy(*out_buffer_ptr, Data.data(), Data.size());
return CXError_Success;
}
void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor MMD) {
delete MMD;
}

View File

@@ -0,0 +1 @@
66b6edc8b11f9834865e67579b440cb3723d4fb9

View File

@@ -0,0 +1,123 @@
//===- CIndexCXX.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 libclang support for C++ cursors.
//
//===----------------------------------------------------------------------===//
#include "CIndexer.h"
#include "CXCursor.h"
#include "CXType.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
using namespace clang;
using namespace clang::cxcursor;
unsigned clang_isVirtualBase(CXCursor C) {
if (C.kind != CXCursor_CXXBaseSpecifier)
return 0;
const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
return B->isVirtual();
}
enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor C) {
AccessSpecifier spec = AS_none;
if (C.kind == CXCursor_CXXAccessSpecifier || clang_isDeclaration(C.kind))
spec = getCursorDecl(C)->getAccess();
else if (C.kind == CXCursor_CXXBaseSpecifier)
spec = getCursorCXXBaseSpecifier(C)->getAccessSpecifier();
else
return CX_CXXInvalidAccessSpecifier;
switch (spec) {
case AS_public: return CX_CXXPublic;
case AS_protected: return CX_CXXProtected;
case AS_private: return CX_CXXPrivate;
case AS_none: return CX_CXXInvalidAccessSpecifier;
}
llvm_unreachable("Invalid AccessSpecifier!");
}
enum CXCursorKind clang_getTemplateCursorKind(CXCursor C) {
using namespace clang::cxcursor;
switch (C.kind) {
case CXCursor_ClassTemplate:
case CXCursor_FunctionTemplate:
if (const TemplateDecl *Template
= dyn_cast_or_null<TemplateDecl>(getCursorDecl(C)))
return MakeCXCursor(Template->getTemplatedDecl(), getCursorTU(C)).kind;
break;
case CXCursor_ClassTemplatePartialSpecialization:
if (const ClassTemplateSpecializationDecl *PartialSpec
= dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(
getCursorDecl(C))) {
switch (PartialSpec->getTagKind()) {
case TTK_Interface:
case TTK_Struct: return CXCursor_StructDecl;
case TTK_Class: return CXCursor_ClassDecl;
case TTK_Union: return CXCursor_UnionDecl;
case TTK_Enum: return CXCursor_NoDeclFound;
}
}
break;
default:
break;
}
return CXCursor_NoDeclFound;
}
CXCursor clang_getSpecializedCursorTemplate(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullCursor();
const Decl *D = getCursorDecl(C);
if (!D)
return clang_getNullCursor();
Decl *Template = nullptr;
if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
if (const ClassTemplatePartialSpecializationDecl *PartialSpec
= dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord))
Template = PartialSpec->getSpecializedTemplate();
else if (const ClassTemplateSpecializationDecl *ClassSpec
= dyn_cast<ClassTemplateSpecializationDecl>(CXXRecord)) {
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *> Result
= ClassSpec->getSpecializedTemplateOrPartial();
if (Result.is<ClassTemplateDecl *>())
Template = Result.get<ClassTemplateDecl *>();
else
Template = Result.get<ClassTemplatePartialSpecializationDecl *>();
} else
Template = CXXRecord->getInstantiatedFromMemberClass();
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Template = Function->getPrimaryTemplate();
if (!Template)
Template = Function->getInstantiatedFromMemberFunction();
} else if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->isStaticDataMember())
Template = Var->getInstantiatedFromStaticDataMember();
} else if (const RedeclarableTemplateDecl *Tmpl
= dyn_cast<RedeclarableTemplateDecl>(D))
Template = Tmpl->getInstantiatedFromMemberTemplate();
if (!Template)
return clang_getNullCursor();
return MakeCXCursor(Template, getCursorTU(C));
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,471 @@
/*===-- 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 "CXTranslationUnit.h"
#include "CXSourceLocation.h"
#include "CXString.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/DiagnosticRenderer.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace clang::cxloc;
using namespace clang::cxdiag;
using namespace llvm;
CXDiagnosticSetImpl::~CXDiagnosticSetImpl() {}
void
CXDiagnosticSetImpl::appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D) {
Diagnostics.push_back(std::move(D));
}
CXDiagnosticImpl::~CXDiagnosticImpl() {}
namespace {
class CXDiagnosticCustomNoteImpl : public CXDiagnosticImpl {
std::string Message;
CXSourceLocation Loc;
public:
CXDiagnosticCustomNoteImpl(StringRef Msg, CXSourceLocation L)
: CXDiagnosticImpl(CustomNoteDiagnosticKind),
Message(Msg), Loc(L) {}
~CXDiagnosticCustomNoteImpl() override {}
CXDiagnosticSeverity getSeverity() const override {
return CXDiagnostic_Note;
}
CXSourceLocation getLocation() const override {
return Loc;
}
CXString getSpelling() const override {
return cxstring::createRef(Message.c_str());
}
CXString getDiagnosticOption(CXString *Disable) const override {
if (Disable)
*Disable = cxstring::createEmpty();
return cxstring::createEmpty();
}
unsigned getCategory() const override { return 0; }
CXString getCategoryText() const override { return cxstring::createEmpty(); }
unsigned getNumRanges() const override { return 0; }
CXSourceRange getRange(unsigned Range) const override {
return clang_getNullRange();
}
unsigned getNumFixIts() const override { return 0; }
CXString getFixIt(unsigned FixIt,
CXSourceRange *ReplacementRange) const override {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
return cxstring::createEmpty();
}
};
class CXDiagnosticRenderer : public DiagnosticNoteRenderer {
public:
CXDiagnosticRenderer(const LangOptions &LangOpts,
DiagnosticOptions *DiagOpts,
CXDiagnosticSetImpl *mainSet)
: DiagnosticNoteRenderer(LangOpts, DiagOpts),
CurrentSet(mainSet), MainSet(mainSet) {}
~CXDiagnosticRenderer() override {}
void beginDiagnostic(DiagOrStoredDiag D,
DiagnosticsEngine::Level Level) override {
const StoredDiagnostic *SD = D.dyn_cast<const StoredDiagnostic*>();
if (!SD)
return;
if (Level != DiagnosticsEngine::Note)
CurrentSet = MainSet;
auto Owner = llvm::make_unique<CXStoredDiagnostic>(*SD, LangOpts);
CXStoredDiagnostic &CD = *Owner;
CurrentSet->appendDiagnostic(std::move(Owner));
if (Level != DiagnosticsEngine::Note)
CurrentSet = &CD.getChildDiagnostics();
}
void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level, StringRef Message,
ArrayRef<CharSourceRange> Ranges,
DiagOrStoredDiag D) override {
if (!D.isNull())
return;
CXSourceLocation L;
if (Loc.hasManager())
L = translateSourceLocation(Loc.getManager(), LangOpts, Loc);
else
L = clang_getNullLocation();
CurrentSet->appendDiagnostic(
llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
}
void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
DiagnosticsEngine::Level Level,
ArrayRef<CharSourceRange> Ranges) override {}
void emitCodeContext(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
SmallVectorImpl<CharSourceRange> &Ranges,
ArrayRef<FixItHint> Hints) override {}
void emitNote(FullSourceLoc Loc, StringRef Message) override {
CXSourceLocation L;
if (Loc.hasManager())
L = translateSourceLocation(Loc.getManager(), LangOpts, Loc);
else
L = clang_getNullLocation();
CurrentSet->appendDiagnostic(
llvm::make_unique<CXDiagnosticCustomNoteImpl>(Message, L));
}
CXDiagnosticSetImpl *CurrentSet;
CXDiagnosticSetImpl *MainSet;
};
}
CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
bool checkIfChanged) {
ASTUnit *AU = cxtu::getASTUnit(TU);
if (TU->Diagnostics && checkIfChanged) {
// In normal use, ASTUnit's diagnostics should not change unless we reparse.
// Currently they can only change by using the internal testing flag
// '-error-on-deserialized-decl' which will error during deserialization of
// a declaration. What will happen is:
//
// -c-index-test gets a CXTranslationUnit
// -checks the diagnostics, the diagnostics set is lazily created,
// no errors are reported
// -later does an operation, like annotation of tokens, that triggers
// -error-on-deserialized-decl, that will emit a diagnostic error,
// that ASTUnit will catch and add to its stored diagnostics vector.
// -c-index-test wants to check whether an error occurred after performing
// the operation but can only query the lazily created set.
//
// We check here if a new diagnostic was appended since the last time the
// diagnostic set was created, in which case we reset it.
CXDiagnosticSetImpl *
Set = static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
if (AU->stored_diag_size() != Set->getNumDiagnostics()) {
// Diagnostics in the ASTUnit were updated, reset the associated
// diagnostics.
delete Set;
TU->Diagnostics = nullptr;
}
}
if (!TU->Diagnostics) {
CXDiagnosticSetImpl *Set = new CXDiagnosticSetImpl();
TU->Diagnostics = Set;
IntrusiveRefCntPtr<DiagnosticOptions> DOpts = new DiagnosticOptions;
CXDiagnosticRenderer Renderer(AU->getASTContext().getLangOpts(),
&*DOpts, Set);
for (ASTUnit::stored_diag_iterator it = AU->stored_diag_begin(),
ei = AU->stored_diag_end(); it != ei; ++it) {
Renderer.emitStoredDiagnostic(*it);
}
}
return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
}
//-----------------------------------------------------------------------------
// C Interface Routines
//-----------------------------------------------------------------------------
unsigned clang_getNumDiagnostics(CXTranslationUnit Unit) {
if (cxtu::isNotUsableTU(Unit)) {
LOG_BAD_TU(Unit);
return 0;
}
if (!cxtu::getASTUnit(Unit))
return 0;
return lazyCreateDiags(Unit, /*checkIfChanged=*/true)->getNumDiagnostics();
}
CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index) {
if (cxtu::isNotUsableTU(Unit)) {
LOG_BAD_TU(Unit);
return nullptr;
}
CXDiagnosticSet D = clang_getDiagnosticSetFromTU(Unit);
if (!D)
return nullptr;
CXDiagnosticSetImpl *Diags = static_cast<CXDiagnosticSetImpl*>(D);
if (Index >= Diags->getNumDiagnostics())
return nullptr;
return Diags->getDiagnostic(Index);
}
CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit) {
if (cxtu::isNotUsableTU(Unit)) {
LOG_BAD_TU(Unit);
return nullptr;
}
if (!cxtu::getASTUnit(Unit))
return nullptr;
return static_cast<CXDiagnostic>(lazyCreateDiags(Unit));
}
void clang_disposeDiagnostic(CXDiagnostic Diagnostic) {
// No-op. Kept as a legacy API. CXDiagnostics are now managed
// by the enclosing CXDiagnosticSet.
}
CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options) {
if (!Diagnostic)
return cxstring::createEmpty();
CXDiagnosticSeverity Severity = clang_getDiagnosticSeverity(Diagnostic);
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_getSpellingLocation(clang_getDiagnosticLocation(Diagnostic),
&File, &Line, &Column, nullptr);
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_getSpellingLocation(clang_getRangeStart(Range),
&StartFile, &StartLine, &StartColumn,
nullptr);
clang_getSpellingLocation(clang_getRangeEnd(Range),
&EndFile, &EndLine, &EndColumn, nullptr);
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: llvm_unreachable("impossible");
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);
if (Options & (CXDiagnostic_DisplayOption | CXDiagnostic_DisplayCategoryId |
CXDiagnostic_DisplayCategoryName)) {
bool NeedBracket = true;
bool NeedComma = false;
if (Options & CXDiagnostic_DisplayOption) {
CXString OptionName = clang_getDiagnosticOption(Diagnostic, nullptr);
if (const char *OptionText = clang_getCString(OptionName)) {
if (OptionText[0]) {
Out << " [" << OptionText;
NeedBracket = false;
NeedComma = true;
}
}
clang_disposeString(OptionName);
}
if (Options & (CXDiagnostic_DisplayCategoryId |
CXDiagnostic_DisplayCategoryName)) {
if (unsigned CategoryID = clang_getDiagnosticCategory(Diagnostic)) {
if (Options & CXDiagnostic_DisplayCategoryId) {
if (NeedBracket)
Out << " [";
if (NeedComma)
Out << ", ";
Out << CategoryID;
NeedBracket = false;
NeedComma = true;
}
if (Options & CXDiagnostic_DisplayCategoryName) {
CXString CategoryName = clang_getDiagnosticCategoryText(Diagnostic);
if (NeedBracket)
Out << " [";
if (NeedComma)
Out << ", ";
Out << clang_getCString(CategoryName);
NeedBracket = false;
NeedComma = true;
clang_disposeString(CategoryName);
}
}
}
(void) NeedComma; // Silence dead store warning.
if (!NeedBracket)
Out << "]";
}
return cxstring::createDup(Out.str());
}
unsigned clang_defaultDiagnosticDisplayOptions() {
return CXDiagnostic_DisplaySourceLocation | CXDiagnostic_DisplayColumn |
CXDiagnostic_DisplayOption;
}
enum CXDiagnosticSeverity clang_getDiagnosticSeverity(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
return D->getSeverity();
return CXDiagnostic_Ignored;
}
CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl*>(Diag))
return D->getLocation();
return clang_getNullLocation();
}
CXString clang_getDiagnosticSpelling(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getSpelling();
return cxstring::createEmpty();
}
CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable) {
if (Disable)
*Disable = cxstring::createEmpty();
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getDiagnosticOption(Disable);
return cxstring::createEmpty();
}
unsigned clang_getDiagnosticCategory(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getCategory();
return 0;
}
CXString clang_getDiagnosticCategoryName(unsigned Category) {
// Kept for backward compatibility.
return cxstring::createRef(DiagnosticIDs::getCategoryNameFromID(Category));
}
CXString clang_getDiagnosticCategoryText(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getCategoryText();
return cxstring::createEmpty();
}
unsigned clang_getDiagnosticNumRanges(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getNumRanges();
return 0;
}
CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diag, unsigned Range) {
CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
if (!D || Range >= D->getNumRanges())
return clang_getNullRange();
return D->getRange(Range);
}
unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag))
return D->getNumFixIts();
return 0;
}
CXString clang_getDiagnosticFixIt(CXDiagnostic Diag, unsigned FixIt,
CXSourceRange *ReplacementRange) {
CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag);
if (!D || FixIt >= D->getNumFixIts()) {
if (ReplacementRange)
*ReplacementRange = clang_getNullRange();
return cxstring::createEmpty();
}
return D->getFixIt(FixIt, ReplacementRange);
}
void clang_disposeDiagnosticSet(CXDiagnosticSet Diags) {
if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl *>(Diags)) {
if (D->isExternallyManaged())
delete D;
}
}
CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags,
unsigned Index) {
if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
if (Index < D->getNumDiagnostics())
return D->getDiagnostic(Index);
return nullptr;
}
CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic Diag) {
if (CXDiagnosticImpl *D = static_cast<CXDiagnosticImpl *>(Diag)) {
CXDiagnosticSetImpl &ChildDiags = D->getChildDiagnostics();
return ChildDiags.empty() ? nullptr : (CXDiagnosticSet) &ChildDiags;
}
return nullptr;
}
unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags) {
if (CXDiagnosticSetImpl *D = static_cast<CXDiagnosticSetImpl*>(Diags))
return D->getNumDiagnostics();
return 0;
}

View File

@@ -0,0 +1,165 @@
/*===-- 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_TOOLS_LIBCLANG_CINDEXDIAGNOSTIC_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXDIAGNOSTIC_H
#include "clang-c/Index.h"
#include <memory>
#include <vector>
#include <assert.h>
namespace clang {
class LangOptions;
class StoredDiagnostic;
class CXDiagnosticImpl;
class CXDiagnosticSetImpl {
std::vector<std::unique_ptr<CXDiagnosticImpl>> Diagnostics;
const bool IsExternallyManaged;
public:
CXDiagnosticSetImpl(bool isManaged = false)
: IsExternallyManaged(isManaged) {}
virtual ~CXDiagnosticSetImpl();
size_t getNumDiagnostics() const {
return Diagnostics.size();
}
CXDiagnosticImpl *getDiagnostic(unsigned i) const {
assert(i < getNumDiagnostics());
return Diagnostics[i].get();
}
void appendDiagnostic(std::unique_ptr<CXDiagnosticImpl> D);
bool empty() const {
return Diagnostics.empty();
}
bool isExternallyManaged() const { return IsExternallyManaged; }
};
class CXDiagnosticImpl {
public:
enum Kind { StoredDiagnosticKind, LoadedDiagnosticKind,
CustomNoteDiagnosticKind };
virtual ~CXDiagnosticImpl();
/// \brief Return the severity of the diagnostic.
virtual CXDiagnosticSeverity getSeverity() const = 0;
/// \brief Return the location of the diagnostic.
virtual CXSourceLocation getLocation() const = 0;
/// \brief Return the spelling of the diagnostic.
virtual CXString getSpelling() const = 0;
/// \brief Return the text for the diagnostic option.
virtual CXString getDiagnosticOption(CXString *Disable) const = 0;
/// \brief Return the category of the diagnostic.
virtual unsigned getCategory() const = 0;
/// \brief Return the category string of the diagnostic.
virtual CXString getCategoryText() const = 0;
/// \brief Return the number of source ranges for the diagnostic.
virtual unsigned getNumRanges() const = 0;
/// \brief Return the source ranges for the diagnostic.
virtual CXSourceRange getRange(unsigned Range) const = 0;
/// \brief Return the number of FixIts.
virtual unsigned getNumFixIts() const = 0;
/// \brief Return the FixIt information (source range and inserted text).
virtual CXString getFixIt(unsigned FixIt,
CXSourceRange *ReplacementRange) const = 0;
Kind getKind() const { return K; }
CXDiagnosticSetImpl &getChildDiagnostics() {
return ChildDiags;
}
protected:
CXDiagnosticImpl(Kind k) : K(k) {}
CXDiagnosticSetImpl ChildDiags;
void append(std::unique_ptr<CXDiagnosticImpl> D) {
ChildDiags.appendDiagnostic(std::move(D));
}
private:
Kind K;
};
/// \brief The storage behind a CXDiagnostic
struct CXStoredDiagnostic : public CXDiagnosticImpl {
const StoredDiagnostic &Diag;
const LangOptions &LangOpts;
CXStoredDiagnostic(const StoredDiagnostic &Diag,
const LangOptions &LangOpts)
: CXDiagnosticImpl(StoredDiagnosticKind),
Diag(Diag), LangOpts(LangOpts) { }
~CXStoredDiagnostic() override {}
/// \brief Return the severity of the diagnostic.
CXDiagnosticSeverity getSeverity() const override;
/// \brief Return the location of the diagnostic.
CXSourceLocation getLocation() const override;
/// \brief Return the spelling of the diagnostic.
CXString getSpelling() const override;
/// \brief Return the text for the diagnostic option.
CXString getDiagnosticOption(CXString *Disable) const override;
/// \brief Return the category of the diagnostic.
unsigned getCategory() const override;
/// \brief Return the category string of the diagnostic.
CXString getCategoryText() const override;
/// \brief Return the number of source ranges for the diagnostic.
unsigned getNumRanges() const override;
/// \brief Return the source ranges for the diagnostic.
CXSourceRange getRange(unsigned Range) const override;
/// \brief Return the number of FixIts.
unsigned getNumFixIts() const override;
/// \brief Return the FixIt information (source range and inserted text).
CXString getFixIt(unsigned FixIt,
CXSourceRange *ReplacementRange) const override;
static bool classof(const CXDiagnosticImpl *D) {
return D->getKind() == StoredDiagnosticKind;
}
};
namespace cxdiag {
CXDiagnosticSetImpl *lazyCreateDiags(CXTranslationUnit TU,
bool checkIfChanged = false);
} // end namespace cxdiag
} // end namespace clang
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
//===- 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 "CXTranslationUnit.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/Frontend/ASTUnit.h"
using namespace clang;
static void getInclusions(const SrcMgr::SLocEntry &(SourceManager::*Getter)(unsigned, bool*) const, unsigned n,
CXTranslationUnit TU, CXInclusionVisitor CB,
CXClientData clientData)
{
ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
SourceManager &SM = CXXUnit->getSourceManager();
ASTContext &Ctx = CXXUnit->getASTContext();
SmallVector<CXSourceLocation, 10> InclusionStack;
const bool HasPreamble = SM.getPreambleFileID().isValid();
for (unsigned i = 0 ; i < n ; ++i) {
bool Invalid = false;
const SrcMgr::SLocEntry &SL = (SM.*Getter)(i, &Invalid);
if (!SL.isFile() || Invalid)
continue;
const SrcMgr::FileInfo &FI = SL.getFile();
if (!FI.getContentCache()->OrigEntry)
continue;
// If this is the main file, and there is a preamble, skip this SLoc. The
// inclusions of the preamble already showed it.
SourceLocation L = FI.getIncludeLoc();
if (HasPreamble && CXXUnit->isInMainFileID(L))
continue;
// Build the inclusion stack.
InclusionStack.clear();
while (L.isValid()) {
PresumedLoc PLoc = SM.getPresumedLoc(L);
InclusionStack.push_back(cxloc::translateSourceLocation(Ctx, L));
L = PLoc.isValid()? PLoc.getIncludeLoc() : SourceLocation();
}
// If there is a preamble, the last entry is the "inclusion" of that
// preamble into the main file, which has the bogus entry of main.c:1:1
if (HasPreamble && !InclusionStack.empty())
InclusionStack.pop_back();
// Callback to the client.
// FIXME: We should have a function to construct CXFiles.
CB(static_cast<CXFile>(
const_cast<FileEntry *>(FI.getContentCache()->OrigEntry)),
InclusionStack.data(), InclusionStack.size(), clientData);
}
}
void clang_getInclusions(CXTranslationUnit TU, CXInclusionVisitor CB,
CXClientData clientData) {
if (cxtu::isNotUsableTU(TU)) {
LOG_BAD_TU(TU);
return;
}
SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
const unsigned n = SM.local_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. Also, if we are not looking at
// a AST/PCH file, but this file has a pre-compiled preamble, we also need
// to look in that file.
if (n == 1 || SM.getPreambleFileID().isValid()) {
getInclusions(&SourceManager::getLoadedSLocEntry,
SM.loaded_sloc_entry_size(), TU, CB, clientData);
}
// Not a PCH/AST file. Note, if there is a preamble, it could still be that
// there are #includes in this file (e.g. for any include after the first
// declaration).
if (n != 1)
getInclusions(&SourceManager::getLocalSLocEntry, n, TU, CB, clientData);
}

View File

@@ -0,0 +1,140 @@
//===- 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 "CXString.h"
#include "CXTranslationUnit.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace clang::index;
//===----------------------------------------------------------------------===//
// API hooks.
//===----------------------------------------------------------------------===//
static inline StringRef extractUSRSuffix(StringRef s) {
return s.startswith("c:") ? s.substr(2) : "";
}
bool cxcursor::getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf) {
return generateUSRForDecl(D, Buf);
}
CXString clang_getCursorUSR(CXCursor C) {
const CXCursorKind &K = clang_getCursorKind(C);
if (clang_isDeclaration(K)) {
const Decl *D = cxcursor::getCursorDecl(C);
if (!D)
return cxstring::createEmpty();
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
return cxstring::createEmpty();
cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
if (!buf)
return cxstring::createEmpty();
bool Ignore = cxcursor::getDeclCursorUSR(D, buf->Data);
if (Ignore) {
buf->dispose();
return cxstring::createEmpty();
}
// Return the C-string, but don't make a copy since it is already in
// the string buffer.
buf->Data.push_back('\0');
return createCXString(buf);
}
if (K == CXCursor_MacroDefinition) {
CXTranslationUnit TU = cxcursor::getCursorTU(C);
if (!TU)
return cxstring::createEmpty();
cxstring::CXStringBuf *buf = cxstring::getCXStringBuf(TU);
if (!buf)
return cxstring::createEmpty();
bool Ignore = generateUSRForMacro(cxcursor::getCursorMacroDefinition(C),
cxtu::getASTUnit(TU)->getSourceManager(),
buf->Data);
if (Ignore) {
buf->dispose();
return cxstring::createEmpty();
}
// Return the C-string, but don't make a copy since it is already in
// the string buffer.
buf->Data.push_back('\0');
return createCXString(buf);
}
return cxstring::createEmpty();
}
CXString clang_constructUSR_ObjCIvar(const char *name, CXString classUSR) {
SmallString<128> Buf(getUSRSpacePrefix());
llvm::raw_svector_ostream OS(Buf);
OS << extractUSRSuffix(clang_getCString(classUSR));
generateUSRForObjCIvar(name, OS);
return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCMethod(const char *name,
unsigned isInstanceMethod,
CXString classUSR) {
SmallString<128> Buf(getUSRSpacePrefix());
llvm::raw_svector_ostream OS(Buf);
OS << extractUSRSuffix(clang_getCString(classUSR));
generateUSRForObjCMethod(name, isInstanceMethod, OS);
return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCClass(const char *name) {
SmallString<128> Buf(getUSRSpacePrefix());
llvm::raw_svector_ostream OS(Buf);
generateUSRForObjCClass(name, OS);
return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCProtocol(const char *name) {
SmallString<128> Buf(getUSRSpacePrefix());
llvm::raw_svector_ostream OS(Buf);
generateUSRForObjCProtocol(name, OS);
return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCCategory(const char *class_name,
const char *category_name) {
SmallString<128> Buf(getUSRSpacePrefix());
llvm::raw_svector_ostream OS(Buf);
generateUSRForObjCCategory(class_name, category_name, OS);
return cxstring::createDup(OS.str());
}
CXString clang_constructUSR_ObjCProperty(const char *property,
CXString classUSR) {
SmallString<128> Buf(getUSRSpacePrefix());
llvm::raw_svector_ostream OS(Buf);
OS << extractUSRSuffix(clang_getCString(classUSR));
generateUSRForObjCProperty(property, /*isClassProp=*/false, OS);
return cxstring::createDup(OS.str());
}

View File

@@ -0,0 +1,162 @@
//===- 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 "CXString.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/Version.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/MD5.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include <cstdio>
#ifdef __CYGWIN__
#include <cygwin/version.h>
#include <sys/cygwin.h>
#define LLVM_ON_WIN32 1
#endif
#ifdef LLVM_ON_WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif
using namespace clang;
const std::string &CIndexer::getClangResourcesPath() {
// Did we already compute the path?
if (!ResourcesPath.empty())
return ResourcesPath;
SmallString<128> LibClangPath;
// Find the location where this library lives (libclang.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);
#ifdef __CYGWIN__
char w32path[MAX_PATH];
strcpy(w32path, path);
#if CYGWIN_VERSION_API_MAJOR > 0 || CYGWIN_VERSION_API_MINOR >= 181
cygwin_conv_path(CCP_WIN_A_TO_POSIX, w32path, path, MAX_PATH);
#else
cygwin_conv_to_full_posix_path(w32path, path);
#endif
#endif
LibClangPath += llvm::sys::path::parent_path(path);
#else
// This silly cast below avoids a C++ warning.
Dl_info info;
if (dladdr((void *)(uintptr_t)clang_createTranslationUnit, &info) == 0)
llvm_unreachable("Call to dladdr() failed");
// We now have the CIndex directory, locate clang relative to it.
LibClangPath += llvm::sys::path::parent_path(info.dli_fname);
#endif
llvm::sys::path::append(LibClangPath, "clang", CLANG_VERSION_STRING);
// Cache our result.
ResourcesPath = LibClangPath.str();
return ResourcesPath;
}
StringRef CIndexer::getClangToolchainPath() {
if (!ToolchainPath.empty())
return ToolchainPath;
StringRef ResourcePath = getClangResourcesPath();
ToolchainPath = llvm::sys::path::parent_path(
llvm::sys::path::parent_path(llvm::sys::path::parent_path(ResourcePath)));
return ToolchainPath;
}
LibclangInvocationReporter::LibclangInvocationReporter(
CIndexer &Idx, OperationKind Op, unsigned ParseOptions,
llvm::ArrayRef<const char *> Args,
llvm::ArrayRef<std::string> InvocationArgs,
llvm::ArrayRef<CXUnsavedFile> UnsavedFiles) {
StringRef Path = Idx.getInvocationEmissionPath();
if (Path.empty())
return;
// Create a temporary file for the invocation log.
SmallString<256> TempPath;
TempPath = Path;
llvm::sys::path::append(TempPath, "libclang-%%%%%%%%%%%%");
int FD;
if (llvm::sys::fs::createUniqueFile(TempPath, FD, TempPath))
return;
File = std::string(TempPath.begin(), TempPath.end());
llvm::raw_fd_ostream OS(FD, /*ShouldClose=*/true);
// Write out the information about the invocation to it.
auto WriteStringKey = [&OS](StringRef Key, StringRef Value) {
OS << R"(")" << Key << R"(":")";
OS << Value << '"';
};
OS << '{';
WriteStringKey("toolchain", Idx.getClangToolchainPath());
OS << ',';
WriteStringKey("libclang.operation",
Op == OperationKind::ParseOperation ? "parse" : "complete");
OS << ',';
OS << R"("libclang.opts":)" << ParseOptions;
OS << ',';
OS << R"("args":[)";
for (const auto &I : llvm::enumerate(Args)) {
if (I.index())
OS << ',';
OS << '"' << I.value() << '"';
}
if (!InvocationArgs.empty()) {
OS << R"(],"invocation-args":[)";
for (const auto &I : llvm::enumerate(InvocationArgs)) {
if (I.index())
OS << ',';
OS << '"' << I.value() << '"';
}
}
if (!UnsavedFiles.empty()) {
OS << R"(],"unsaved_file_hashes":[)";
for (const auto &UF : llvm::enumerate(UnsavedFiles)) {
if (UF.index())
OS << ',';
OS << '{';
WriteStringKey("name", UF.value().Filename);
OS << ',';
llvm::MD5 Hash;
Hash.update(getContents(UF.value()));
llvm::MD5::MD5Result Result;
Hash.final(Result);
SmallString<32> Digest = Result.digest();
WriteStringKey("md5", Digest);
OS << '}';
}
}
OS << "]}";
}
LibclangInvocationReporter::~LibclangInvocationReporter() {
if (!File.empty())
llvm::sys::fs::remove(File);
}

View File

@@ -0,0 +1,155 @@
//===- CIndexer.h - Clang-C Source Indexing Library -------------*- 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 CIndexer, a subclass of Indexer that provides extra
// functionality needed by the CIndex library.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H
#include "clang-c/Index.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Mutex.h"
#include <utility>
namespace llvm {
class CrashRecoveryContext;
}
namespace clang {
class ASTUnit;
class MacroInfo;
class MacroDefinitionRecord;
class SourceLocation;
class Token;
class IdentifierInfo;
class CIndexer {
bool OnlyLocalDecls;
bool DisplayDiagnostics;
unsigned Options; // CXGlobalOptFlags.
std::string ResourcesPath;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
std::string ToolchainPath;
std::string InvocationEmissionPath;
public:
CIndexer(std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>())
: OnlyLocalDecls(false), DisplayDiagnostics(false),
Options(CXGlobalOpt_None), PCHContainerOps(std::move(PCHContainerOps)) {
}
/// \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;
}
std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
return PCHContainerOps;
}
unsigned getCXGlobalOptFlags() const { return Options; }
void setCXGlobalOptFlags(unsigned options) { Options = options; }
bool isOptEnabled(CXGlobalOptFlags opt) const {
return Options & opt;
}
/// \brief Get the path of the clang resource files.
const std::string &getClangResourcesPath();
StringRef getClangToolchainPath();
void setInvocationEmissionPath(StringRef Str) {
InvocationEmissionPath = Str;
}
StringRef getInvocationEmissionPath() const { return InvocationEmissionPath; }
};
/// Logs information about a particular libclang operation like parsing to
/// a new file in the invocation emission path.
class LibclangInvocationReporter {
public:
enum class OperationKind { ParseOperation, CompletionOperation };
LibclangInvocationReporter(CIndexer &Idx, OperationKind Op,
unsigned ParseOptions,
llvm::ArrayRef<const char *> Args,
llvm::ArrayRef<std::string> InvocationArgs,
llvm::ArrayRef<CXUnsavedFile> UnsavedFiles);
~LibclangInvocationReporter();
private:
std::string File;
};
/// \brief Return the current size to request for "safety".
unsigned GetSafetyThreadStackSize();
/// \brief Set the current size to request for "safety" (or 0, if safety
/// threads should not be used).
void SetSafetyThreadStackSize(unsigned Value);
/// \brief Execution the given code "safely", using crash recovery or safety
/// threads when possible.
///
/// \return False if a crash was detected.
bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
unsigned Size = 0);
/// \brief Set the thread priority to background.
/// FIXME: Move to llvm/Support.
void setThreadBackgroundPriority();
/// \brief Print libclang's resource usage to standard error.
void PrintLibclangResourceUsage(CXTranslationUnit TU);
namespace cxindex {
void printDiagsToStderr(ASTUnit *Unit);
/// \brief If \c MacroDefLoc points at a macro definition with \c II as
/// its name, this retrieves its MacroInfo.
MacroInfo *getMacroInfo(const IdentifierInfo &II,
SourceLocation MacroDefLoc, CXTranslationUnit TU);
/// \brief Retrieves the corresponding MacroInfo of a MacroDefinitionRecord.
const MacroInfo *getMacroInfo(const MacroDefinitionRecord *MacroDef,
CXTranslationUnit TU);
/// \brief If \c Loc resides inside the definition of \c MI and it points at
/// an identifier that has ever been a macro name, this returns the latest
/// MacroDefinitionRecord for that name, otherwise it returns NULL.
MacroDefinitionRecord *checkForMacroInMacroDefinition(const MacroInfo *MI,
SourceLocation Loc,
CXTranslationUnit TU);
/// \brief If \c Tok resides inside the definition of \c MI and it points at
/// an identifier that has ever been a macro name, this returns the latest
/// MacroDefinitionRecord for that name, otherwise it returns NULL.
MacroDefinitionRecord *checkForMacroInMacroDefinition(const MacroInfo *MI,
const Token &Tok,
CXTranslationUnit TU);
}
}
#endif

View File

@@ -0,0 +1,103 @@
//===- CLog.h - Logging Interface -------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CLOG_H
#include "clang-c/Index.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
namespace llvm {
class format_object_base;
}
namespace clang {
class FileEntry;
namespace cxindex {
class Logger;
typedef IntrusiveRefCntPtr<Logger> LogRef;
/// \brief Collects logging output and writes it to stderr when it's destructed.
/// Common use case:
/// \code
/// if (LogRef Log = Logger::make(__func__)) {
/// *Log << "stuff";
/// }
/// \endcode
class Logger : public RefCountedBase<Logger> {
std::string Name;
bool Trace;
SmallString<64> Msg;
llvm::raw_svector_ostream LogOS;
public:
static const char *getEnvVar() {
static const char *sCachedVar = ::getenv("LIBCLANG_LOGGING");
return sCachedVar;
}
static bool isLoggingEnabled() { return getEnvVar() != nullptr; }
static bool isStackTracingEnabled() {
if (const char *EnvOpt = Logger::getEnvVar())
return llvm::StringRef(EnvOpt) == "2";
return false;
}
static LogRef make(llvm::StringRef name,
bool trace = isStackTracingEnabled()) {
if (isLoggingEnabled())
return new Logger(name, trace);
return nullptr;
}
explicit Logger(llvm::StringRef name, bool trace)
: Name(name), Trace(trace), LogOS(Msg) { }
~Logger();
Logger &operator<<(CXTranslationUnit);
Logger &operator<<(const FileEntry *FE);
Logger &operator<<(CXCursor cursor);
Logger &operator<<(CXSourceLocation);
Logger &operator<<(CXSourceRange);
Logger &operator<<(CXString);
Logger &operator<<(llvm::StringRef Str) { LogOS << Str; return *this; }
Logger &operator<<(const char *Str) {
if (Str)
LogOS << Str;
return *this;
}
Logger &operator<<(unsigned long N) { LogOS << N; return *this; }
Logger &operator<<(long N) { LogOS << N ; return *this; }
Logger &operator<<(unsigned int N) { LogOS << N; return *this; }
Logger &operator<<(int N) { LogOS << N; return *this; }
Logger &operator<<(char C) { LogOS << C; return *this; }
Logger &operator<<(unsigned char C) { LogOS << C; return *this; }
Logger &operator<<(signed char C) { LogOS << C; return *this; }
Logger &operator<<(const llvm::format_object_base &Fmt);
};
}
}
/// \brief Macros to automate common uses of Logger. Like this:
/// \code
/// LOG_FUNC_SECTION {
/// *Log << "blah";
/// }
/// \endcode
#define LOG_SECTION(NAME) \
if (clang::cxindex::LogRef Log = clang::cxindex::Logger::make(NAME))
#define LOG_FUNC_SECTION LOG_SECTION(__func__)
#endif

View File

@@ -0,0 +1,153 @@
set(SOURCES
ARCMigrate.cpp
BuildSystem.cpp
CIndex.cpp
CIndexCXX.cpp
CIndexCodeCompletion.cpp
CIndexDiagnostic.cpp
CIndexHigh.cpp
CIndexInclusionStack.cpp
CIndexUSRs.cpp
CIndexer.cpp
CXComment.cpp
CXCursor.cpp
CXIndexDataConsumer.cpp
CXCompilationDatabase.cpp
CXLoadedDiagnostic.cpp
CXSourceLocation.cpp
CXStoredDiagnostic.cpp
CXString.cpp
CXType.cpp
Indexing.cpp
ADDITIONAL_HEADERS
CIndexDiagnostic.h
CIndexer.h
CXCursor.h
CXLoadedDiagnostic.h
CXSourceLocation.h
CXString.h
CXTranslationUnit.h
CXType.h
Index_Internal.h
../../include/clang-c/Index.h
)
set(LIBS
clangAST
clangBasic
clangFrontend
clangIndex
clangLex
clangSema
clangTooling
)
if (CLANG_ENABLE_ARCMT)
list(APPEND LIBS clangARCMigrate)
endif ()
if (TARGET clangTidyPlugin)
add_definitions(-DCLANG_TOOL_EXTRA_BUILD)
list(APPEND LIBS clangTidyPlugin)
list(APPEND LIBS clangIncludeFixerPlugin)
if(LLVM_ENABLE_MODULES)
list(APPEND LLVM_COMPILE_FLAGS "-fmodules-ignore-macro=CLANG_TOOL_EXTRA_BUILD")
endif()
endif ()
find_library(DL_LIBRARY_PATH dl)
if (DL_LIBRARY_PATH)
list(APPEND LIBS dl)
endif()
option(LIBCLANG_BUILD_STATIC
"Build libclang as a static library (in addition to a shared one)" OFF)
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libclang.exports)
if(MSVC)
# Avoid LNK4197 not to spceify libclang.def here.
# Each functions is exported as "dllexport" in include/clang-c.
# KB835326
set(LLVM_EXPORTED_SYMBOL_FILE)
endif()
if( LLVM_ENABLE_PIC )
set(ENABLE_SHARED SHARED)
endif()
if((NOT LLVM_ENABLE_PIC OR LIBCLANG_BUILD_STATIC) AND NOT WIN32)
set(ENABLE_STATIC STATIC)
endif()
if(WIN32)
set(output_name "libclang")
else()
set(output_name "clang")
endif()
add_clang_library(libclang ${ENABLE_SHARED} ${ENABLE_STATIC}
OUTPUT_NAME ${output_name}
${SOURCES}
DEPENDS clang-headers
LINK_LIBS
${LIBS}
LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
Core
Support
)
if(ENABLE_SHARED)
if(WIN32)
set_target_properties(libclang
PROPERTIES
VERSION ${LIBCLANG_LIBRARY_VERSION}
DEFINE_SYMBOL _CINDEX_LIB_)
elseif(APPLE)
set(LIBCLANG_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
set(LIBCLANG_LINK_FLAGS "${LIBCLANG_LINK_FLAGS} -Wl,-current_version -Wl,${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
set_property(TARGET libclang APPEND_STRING PROPERTY
LINK_FLAGS ${LIBCLANG_LINK_FLAGS})
else()
set_target_properties(libclang
PROPERTIES
VERSION ${LIBCLANG_LIBRARY_VERSION}
DEFINE_SYMBOL _CINDEX_LIB_)
# FIXME: _CINDEX_LIB_ affects dllexport/dllimport on Win32.
if(LLVM_ENABLE_MODULES AND NOT WIN32)
target_compile_options(libclang PRIVATE
"-fmodules-ignore-macro=_CINDEX_LIB_"
)
endif()
endif()
endif()
if(INTERNAL_INSTALL_PREFIX)
set(LIBCLANG_HEADERS_INSTALL_DESTINATION "${INTERNAL_INSTALL_PREFIX}/include")
else()
set(LIBCLANG_HEADERS_INSTALL_DESTINATION include)
endif()
install(DIRECTORY ../../include/clang-c
COMPONENT libclang-headers
DESTINATION "${LIBCLANG_HEADERS_INSTALL_DESTINATION}"
FILES_MATCHING
PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
# LLVM_DISTRIBUTION_COMPONENTS requires that each component have both a
# component and an install-component target, so add a dummy libclang-headers
# target to allow using it in LLVM_DISTRIBUTION_COMPONENTS.
add_custom_target(libclang-headers)
set_target_properties(libclang-headers PROPERTIES FOLDER "Misc")
if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's.
add_llvm_install_targets(install-libclang-headers
COMPONENT libclang-headers)
endif()

View File

@@ -0,0 +1,406 @@
//===- CXComment.cpp - libclang APIs for manipulating CXComments ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines all libclang APIs related to walking comment AST.
//
//===----------------------------------------------------------------------===//
#include "CXComment.h"
#include "CXCursor.h"
#include "CXString.h"
#include "clang-c/Documentation.h"
#include "clang-c/Index.h"
#include "clang/AST/Decl.h"
#include "clang/Index/CommentToXML.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include <climits>
using namespace clang;
using namespace clang::comments;
using namespace clang::cxcomment;
CXComment clang_Cursor_getParsedComment(CXCursor C) {
using namespace clang::cxcursor;
if (!clang_isDeclaration(C.kind))
return createCXComment(nullptr, nullptr);
const Decl *D = getCursorDecl(C);
const ASTContext &Context = getCursorContext(C);
const FullComment *FC = Context.getCommentForDecl(D, /*PP=*/nullptr);
return createCXComment(FC, getCursorTU(C));
}
enum CXCommentKind clang_Comment_getKind(CXComment CXC) {
const Comment *C = getASTNode(CXC);
if (!C)
return CXComment_Null;
switch (C->getCommentKind()) {
case Comment::NoCommentKind:
return CXComment_Null;
case Comment::TextCommentKind:
return CXComment_Text;
case Comment::InlineCommandCommentKind:
return CXComment_InlineCommand;
case Comment::HTMLStartTagCommentKind:
return CXComment_HTMLStartTag;
case Comment::HTMLEndTagCommentKind:
return CXComment_HTMLEndTag;
case Comment::ParagraphCommentKind:
return CXComment_Paragraph;
case Comment::BlockCommandCommentKind:
return CXComment_BlockCommand;
case Comment::ParamCommandCommentKind:
return CXComment_ParamCommand;
case Comment::TParamCommandCommentKind:
return CXComment_TParamCommand;
case Comment::VerbatimBlockCommentKind:
return CXComment_VerbatimBlockCommand;
case Comment::VerbatimBlockLineCommentKind:
return CXComment_VerbatimBlockLine;
case Comment::VerbatimLineCommentKind:
return CXComment_VerbatimLine;
case Comment::FullCommentKind:
return CXComment_FullComment;
}
llvm_unreachable("unknown CommentKind");
}
unsigned clang_Comment_getNumChildren(CXComment CXC) {
const Comment *C = getASTNode(CXC);
if (!C)
return 0;
return C->child_count();
}
CXComment clang_Comment_getChild(CXComment CXC, unsigned ChildIdx) {
const Comment *C = getASTNode(CXC);
if (!C || ChildIdx >= C->child_count())
return createCXComment(nullptr, nullptr);
return createCXComment(*(C->child_begin() + ChildIdx), CXC.TranslationUnit);
}
unsigned clang_Comment_isWhitespace(CXComment CXC) {
const Comment *C = getASTNode(CXC);
if (!C)
return false;
if (const TextComment *TC = dyn_cast<TextComment>(C))
return TC->isWhitespace();
if (const ParagraphComment *PC = dyn_cast<ParagraphComment>(C))
return PC->isWhitespace();
return false;
}
unsigned clang_InlineContentComment_hasTrailingNewline(CXComment CXC) {
const InlineContentComment *ICC = getASTNodeAs<InlineContentComment>(CXC);
if (!ICC)
return false;
return ICC->hasTrailingNewline();
}
CXString clang_TextComment_getText(CXComment CXC) {
const TextComment *TC = getASTNodeAs<TextComment>(CXC);
if (!TC)
return cxstring::createNull();
return cxstring::createRef(TC->getText());
}
CXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC)
return cxstring::createNull();
const CommandTraits &Traits = getCommandTraits(CXC);
return cxstring::createRef(ICC->getCommandName(Traits));
}
enum CXCommentInlineCommandRenderKind
clang_InlineCommandComment_getRenderKind(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC)
return CXCommentInlineCommandRenderKind_Normal;
switch (ICC->getRenderKind()) {
case InlineCommandComment::RenderNormal:
return CXCommentInlineCommandRenderKind_Normal;
case InlineCommandComment::RenderBold:
return CXCommentInlineCommandRenderKind_Bold;
case InlineCommandComment::RenderMonospaced:
return CXCommentInlineCommandRenderKind_Monospaced;
case InlineCommandComment::RenderEmphasized:
return CXCommentInlineCommandRenderKind_Emphasized;
}
llvm_unreachable("unknown InlineCommandComment::RenderKind");
}
unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC)
return 0;
return ICC->getNumArgs();
}
CXString clang_InlineCommandComment_getArgText(CXComment CXC,
unsigned ArgIdx) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC || ArgIdx >= ICC->getNumArgs())
return cxstring::createNull();
return cxstring::createRef(ICC->getArgText(ArgIdx));
}
CXString clang_HTMLTagComment_getTagName(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
return cxstring::createNull();
return cxstring::createRef(HTC->getTagName());
}
unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment CXC) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST)
return false;
return HST->isSelfClosing();
}
unsigned clang_HTMLStartTag_getNumAttrs(CXComment CXC) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST)
return 0;
return HST->getNumAttrs();
}
CXString clang_HTMLStartTag_getAttrName(CXComment CXC, unsigned AttrIdx) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST || AttrIdx >= HST->getNumAttrs())
return cxstring::createNull();
return cxstring::createRef(HST->getAttr(AttrIdx).Name);
}
CXString clang_HTMLStartTag_getAttrValue(CXComment CXC, unsigned AttrIdx) {
const HTMLStartTagComment *HST = getASTNodeAs<HTMLStartTagComment>(CXC);
if (!HST || AttrIdx >= HST->getNumAttrs())
return cxstring::createNull();
return cxstring::createRef(HST->getAttr(AttrIdx).Value);
}
CXString clang_BlockCommandComment_getCommandName(CXComment CXC) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC)
return cxstring::createNull();
const CommandTraits &Traits = getCommandTraits(CXC);
return cxstring::createRef(BCC->getCommandName(Traits));
}
unsigned clang_BlockCommandComment_getNumArgs(CXComment CXC) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC)
return 0;
return BCC->getNumArgs();
}
CXString clang_BlockCommandComment_getArgText(CXComment CXC,
unsigned ArgIdx) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC || ArgIdx >= BCC->getNumArgs())
return cxstring::createNull();
return cxstring::createRef(BCC->getArgText(ArgIdx));
}
CXComment clang_BlockCommandComment_getParagraph(CXComment CXC) {
const BlockCommandComment *BCC = getASTNodeAs<BlockCommandComment>(CXC);
if (!BCC)
return createCXComment(nullptr, nullptr);
return createCXComment(BCC->getParagraph(), CXC.TranslationUnit);
}
CXString clang_ParamCommandComment_getParamName(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC || !PCC->hasParamName())
return cxstring::createNull();
return cxstring::createRef(PCC->getParamNameAsWritten());
}
unsigned clang_ParamCommandComment_isParamIndexValid(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC)
return false;
return PCC->isParamIndexValid();
}
unsigned clang_ParamCommandComment_getParamIndex(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC || !PCC->isParamIndexValid() || PCC->isVarArgParam())
return ParamCommandComment::InvalidParamIndex;
return PCC->getParamIndex();
}
unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC)
return false;
return PCC->isDirectionExplicit();
}
enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(
CXComment CXC) {
const ParamCommandComment *PCC = getASTNodeAs<ParamCommandComment>(CXC);
if (!PCC)
return CXCommentParamPassDirection_In;
switch (PCC->getDirection()) {
case ParamCommandComment::In:
return CXCommentParamPassDirection_In;
case ParamCommandComment::Out:
return CXCommentParamPassDirection_Out;
case ParamCommandComment::InOut:
return CXCommentParamPassDirection_InOut;
}
llvm_unreachable("unknown ParamCommandComment::PassDirection");
}
CXString clang_TParamCommandComment_getParamName(CXComment CXC) {
const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
if (!TPCC || !TPCC->hasParamName())
return cxstring::createNull();
return cxstring::createRef(TPCC->getParamNameAsWritten());
}
unsigned clang_TParamCommandComment_isParamPositionValid(CXComment CXC) {
const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
if (!TPCC)
return false;
return TPCC->isPositionValid();
}
unsigned clang_TParamCommandComment_getDepth(CXComment CXC) {
const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
if (!TPCC || !TPCC->isPositionValid())
return 0;
return TPCC->getDepth();
}
unsigned clang_TParamCommandComment_getIndex(CXComment CXC, unsigned Depth) {
const TParamCommandComment *TPCC = getASTNodeAs<TParamCommandComment>(CXC);
if (!TPCC || !TPCC->isPositionValid() || Depth >= TPCC->getDepth())
return 0;
return TPCC->getIndex(Depth);
}
CXString clang_VerbatimBlockLineComment_getText(CXComment CXC) {
const VerbatimBlockLineComment *VBL =
getASTNodeAs<VerbatimBlockLineComment>(CXC);
if (!VBL)
return cxstring::createNull();
return cxstring::createRef(VBL->getText());
}
CXString clang_VerbatimLineComment_getText(CXComment CXC) {
const VerbatimLineComment *VLC = getASTNodeAs<VerbatimLineComment>(CXC);
if (!VLC)
return cxstring::createNull();
return cxstring::createRef(VLC->getText());
}
//===----------------------------------------------------------------------===//
// Converting comments to XML.
//===----------------------------------------------------------------------===//
CXString clang_HTMLTagComment_getAsString(CXComment CXC) {
const HTMLTagComment *HTC = getASTNodeAs<HTMLTagComment>(CXC);
if (!HTC)
return cxstring::createNull();
CXTranslationUnit TU = CXC.TranslationUnit;
if (!TU->CommentToXML)
TU->CommentToXML = new clang::index::CommentToXMLConverter();
SmallString<128> Text;
TU->CommentToXML->convertHTMLTagNodeToText(
HTC, Text, cxtu::getASTUnit(TU)->getASTContext());
return cxstring::createDup(Text.str());
}
CXString clang_FullComment_getAsHTML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
return cxstring::createNull();
CXTranslationUnit TU = CXC.TranslationUnit;
if (!TU->CommentToXML)
TU->CommentToXML = new clang::index::CommentToXMLConverter();
SmallString<1024> HTML;
TU->CommentToXML
->convertCommentToHTML(FC, HTML, cxtu::getASTUnit(TU)->getASTContext());
return cxstring::createDup(HTML.str());
}
CXString clang_FullComment_getAsXML(CXComment CXC) {
const FullComment *FC = getASTNodeAs<FullComment>(CXC);
if (!FC)
return cxstring::createNull();
CXTranslationUnit TU = CXC.TranslationUnit;
if (!TU->CommentToXML)
TU->CommentToXML = new clang::index::CommentToXMLConverter();
SmallString<1024> XML;
TU->CommentToXML
->convertCommentToXML(FC, XML, cxtu::getASTUnit(TU)->getASTContext());
return cxstring::createDup(XML.str());
}

View File

@@ -0,0 +1,64 @@
//===- CXComment.h - Routines for manipulating CXComments -----------------===//
//
// 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 CXComments.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_LIBCLANG_CXCOMMENT_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CXCOMMENT_H
#include "CXTranslationUnit.h"
#include "clang-c/Documentation.h"
#include "clang-c/Index.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Comment.h"
#include "clang/Frontend/ASTUnit.h"
namespace clang {
namespace comments {
class CommandTraits;
}
namespace cxcomment {
static inline CXComment createCXComment(const comments::Comment *C,
CXTranslationUnit TU) {
CXComment Result;
Result.ASTNode = C;
Result.TranslationUnit = TU;
return Result;
}
static inline const comments::Comment *getASTNode(CXComment CXC) {
return static_cast<const comments::Comment *>(CXC.ASTNode);
}
template<typename T>
static inline const T *getASTNodeAs(CXComment CXC) {
const comments::Comment *C = getASTNode(CXC);
if (!C)
return nullptr;
return dyn_cast<T>(C);
}
static inline ASTContext &getASTContext(CXComment CXC) {
return cxtu::getASTUnit(CXC.TranslationUnit)->getASTContext();
}
static inline comments::CommandTraits &getCommandTraits(CXComment CXC) {
return getASTContext(CXC).getCommentCommandTraits();
}
} // end namespace cxcomment
} // end namespace clang
#endif

View File

@@ -0,0 +1,167 @@
#include "clang-c/CXCompilationDatabase.h"
#include "CXString.h"
#include "clang/Tooling/CompilationDatabase.h"
#include <cstdio>
using namespace clang;
using namespace clang::tooling;
// FIXME: do something more useful with the error message
CXCompilationDatabase
clang_CompilationDatabase_fromDirectory(const char *BuildDir,
CXCompilationDatabase_Error *ErrorCode)
{
std::string ErrorMsg;
CXCompilationDatabase_Error Err = CXCompilationDatabase_NoError;
std::unique_ptr<CompilationDatabase> db =
CompilationDatabase::loadFromDirectory(BuildDir, ErrorMsg);
if (!db) {
fprintf(stderr, "LIBCLANG TOOLING ERROR: %s\n", ErrorMsg.c_str());
Err = CXCompilationDatabase_CanNotLoadDatabase;
}
if (ErrorCode)
*ErrorCode = Err;
return db.release();
}
void
clang_CompilationDatabase_dispose(CXCompilationDatabase CDb)
{
delete static_cast<CompilationDatabase *>(CDb);
}
struct AllocatedCXCompileCommands
{
std::vector<CompileCommand> CCmd;
AllocatedCXCompileCommands(std::vector<CompileCommand> Cmd)
: CCmd(std::move(Cmd)) {}
};
CXCompileCommands
clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase CDb,
const char *CompleteFileName)
{
if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
std::vector<CompileCommand> CCmd(db->getCompileCommands(CompleteFileName));
if (!CCmd.empty())
return new AllocatedCXCompileCommands(std::move(CCmd));
}
return nullptr;
}
CXCompileCommands
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase CDb) {
if (CompilationDatabase *db = static_cast<CompilationDatabase *>(CDb)) {
std::vector<CompileCommand> CCmd(db->getAllCompileCommands());
if (!CCmd.empty())
return new AllocatedCXCompileCommands(std::move(CCmd));
}
return nullptr;
}
void
clang_CompileCommands_dispose(CXCompileCommands Cmds)
{
delete static_cast<AllocatedCXCompileCommands *>(Cmds);
}
unsigned
clang_CompileCommands_getSize(CXCompileCommands Cmds)
{
if (!Cmds)
return 0;
AllocatedCXCompileCommands *ACC =
static_cast<AllocatedCXCompileCommands *>(Cmds);
return ACC->CCmd.size();
}
CXCompileCommand
clang_CompileCommands_getCommand(CXCompileCommands Cmds, unsigned I)
{
if (!Cmds)
return nullptr;
AllocatedCXCompileCommands *ACC =
static_cast<AllocatedCXCompileCommands *>(Cmds);
if (I >= ACC->CCmd.size())
return nullptr;
return &ACC->CCmd[I];
}
CXString
clang_CompileCommand_getDirectory(CXCompileCommand CCmd)
{
if (!CCmd)
return cxstring::createNull();
CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
return cxstring::createRef(cmd->Directory.c_str());
}
CXString
clang_CompileCommand_getFilename(CXCompileCommand CCmd)
{
if (!CCmd)
return cxstring::createNull();
CompileCommand *cmd = static_cast<CompileCommand *>(CCmd);
return cxstring::createRef(cmd->Filename.c_str());
}
unsigned
clang_CompileCommand_getNumArgs(CXCompileCommand CCmd)
{
if (!CCmd)
return 0;
return static_cast<CompileCommand *>(CCmd)->CommandLine.size();
}
CXString
clang_CompileCommand_getArg(CXCompileCommand CCmd, unsigned Arg)
{
if (!CCmd)
return cxstring::createNull();
CompileCommand *Cmd = static_cast<CompileCommand *>(CCmd);
if (Arg >= Cmd->CommandLine.size())
return cxstring::createNull();
return cxstring::createRef(Cmd->CommandLine[Arg].c_str());
}
unsigned
clang_CompileCommand_getNumMappedSources(CXCompileCommand CCmd)
{
// Left here for backward compatibility. No mapped sources exists in the C++
// backend anymore.
return 0;
}
CXString
clang_CompileCommand_getMappedSourcePath(CXCompileCommand CCmd, unsigned I)
{
// Left here for backward compatibility. No mapped sources exists in the C++
// backend anymore.
return cxstring::createNull();
}
CXString
clang_CompileCommand_getMappedSourceContent(CXCompileCommand CCmd, unsigned I)
{
// Left here for backward compatibility. No mapped sources exists in the C++
// backend anymore.
return cxstring::createNull();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
//===- 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_TOOLS_LIBCLANG_CXCURSOR_H
#define LLVM_CLANG_TOOLS_LIBCLANG_CXCURSOR_H
#include "clang-c/Index.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/PointerUnion.h"
#include <utility>
namespace clang {
class ASTContext;
class ASTUnit;
class Attr;
class CXXBaseSpecifier;
class Decl;
class Expr;
class FieldDecl;
class InclusionDirective;
class LabelStmt;
class MacroDefinitionRecord;
class MacroExpansion;
class NamedDecl;
class ObjCInterfaceDecl;
class ObjCProtocolDecl;
class OverloadedTemplateStorage;
class OverloadExpr;
class Stmt;
class TemplateDecl;
class TemplateName;
class TypeDecl;
class VarDecl;
class IdentifierInfo;
namespace cxcursor {
CXCursor getCursor(CXTranslationUnit, SourceLocation);
CXCursor MakeCXCursor(const clang::Attr *A, const clang::Decl *Parent,
CXTranslationUnit TU);
CXCursor MakeCXCursor(const clang::Decl *D, CXTranslationUnit TU,
SourceRange RegionOfInterest = SourceRange(),
bool FirstInDeclGroup = true);
CXCursor MakeCXCursor(const clang::Stmt *S, const clang::Decl *Parent,
CXTranslationUnit TU,
SourceRange RegionOfInterest = SourceRange());
CXCursor MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU = nullptr);
/// \brief Create an Objective-C superclass reference at the given location.
CXCursor MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack an ObjCSuperClassRef cursor into the interface it references
/// and optionally the location where the reference occurred.
std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCSuperClassRef(CXCursor C);
/// \brief Create an Objective-C protocol reference at the given location.
CXCursor MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack an ObjCProtocolRef cursor into the protocol it references
/// and optionally the location where the reference occurred.
std::pair<const ObjCProtocolDecl *, SourceLocation>
getCursorObjCProtocolRef(CXCursor C);
/// \brief Create an Objective-C class reference at the given location.
CXCursor MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack an ObjCClassRef cursor into the class it references
/// and optionally the location where the reference occurred.
std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCClassRef(CXCursor C);
/// \brief Create a type reference at the given location.
CXCursor MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack a TypeRef cursor into the class it references
/// and optionally the location where the reference occurred.
std::pair<const TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C);
/// \brief Create a reference to a template at the given location.
CXCursor MakeCursorTemplateRef(const TemplateDecl *Template, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack a TemplateRef cursor into the template it references and
/// the location where the reference occurred.
std::pair<const TemplateDecl *, SourceLocation>
getCursorTemplateRef(CXCursor C);
/// \brief Create a reference to a namespace or namespace alias at the given
/// location.
CXCursor MakeCursorNamespaceRef(const NamedDecl *NS, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack a NamespaceRef cursor into the namespace or namespace alias
/// it references and the location where the reference occurred.
std::pair<const NamedDecl *, SourceLocation> getCursorNamespaceRef(CXCursor C);
/// \brief Create a reference to a variable at the given location.
CXCursor MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack a VariableRef cursor into the variable it references and the
/// location where the where the reference occurred.
std::pair<const VarDecl *, SourceLocation> getCursorVariableRef(CXCursor C);
/// \brief Create a reference to a field at the given location.
CXCursor MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack a MemberRef cursor into the field it references and the
/// location where the reference occurred.
std::pair<const FieldDecl *, SourceLocation> getCursorMemberRef(CXCursor C);
/// \brief Create a CXX base specifier cursor.
CXCursor MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
CXTranslationUnit TU);
/// \brief Unpack a CXXBaseSpecifier cursor into a CXXBaseSpecifier.
const CXXBaseSpecifier *getCursorCXXBaseSpecifier(CXCursor C);
/// \brief Create a preprocessing directive cursor.
CXCursor MakePreprocessingDirectiveCursor(SourceRange Range,
CXTranslationUnit TU);
/// \brief Unpack a given preprocessing directive to retrieve its source range.
SourceRange getCursorPreprocessingDirective(CXCursor C);
/// \brief Create a macro definition cursor.
CXCursor MakeMacroDefinitionCursor(const MacroDefinitionRecord *,
CXTranslationUnit TU);
/// \brief Unpack a given macro definition cursor to retrieve its
/// source range.
const MacroDefinitionRecord *getCursorMacroDefinition(CXCursor C);
/// \brief Create a macro expansion cursor.
CXCursor MakeMacroExpansionCursor(MacroExpansion *, CXTranslationUnit TU);
/// \brief Create a "pseudo" macro expansion cursor, using a macro definition
/// and a source location.
CXCursor MakeMacroExpansionCursor(MacroDefinitionRecord *, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Wraps a macro expansion cursor and provides a common interface
/// for a normal macro expansion cursor or a "pseudo" one.
///
/// "Pseudo" macro expansion cursors (essentially a macro definition along with
/// a source location) are created in special cases, for example they can be
/// created for identifiers inside macro definitions, if these identifiers are
/// macro names.
class MacroExpansionCursor {
CXCursor C;
bool isPseudo() const { return C.data[1] != nullptr; }
const MacroDefinitionRecord *getAsMacroDefinition() const {
assert(isPseudo());
return static_cast<const MacroDefinitionRecord *>(C.data[0]);
}
const MacroExpansion *getAsMacroExpansion() const {
assert(!isPseudo());
return static_cast<const MacroExpansion *>(C.data[0]);
}
SourceLocation getPseudoLoc() const {
assert(isPseudo());
return SourceLocation::getFromPtrEncoding(C.data[1]);
}
public:
MacroExpansionCursor(CXCursor C) : C(C) {
assert(C.kind == CXCursor_MacroExpansion);
}
const IdentifierInfo *getName() const;
const MacroDefinitionRecord *getDefinition() const;
SourceRange getSourceRange() const;
};
/// \brief Unpack a given macro expansion cursor to retrieve its info.
static inline MacroExpansionCursor getCursorMacroExpansion(CXCursor C) {
return C;
}
/// \brief Create an inclusion directive cursor.
CXCursor MakeInclusionDirectiveCursor(InclusionDirective *,
CXTranslationUnit TU);
/// \brief Unpack a given inclusion directive cursor to retrieve its
/// source range.
const InclusionDirective *getCursorInclusionDirective(CXCursor C);
/// \brief Create a label reference at the given location.
CXCursor MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
CXTranslationUnit TU);
/// \brief Unpack a label reference into the label statement it refers to and
/// the location of the reference.
std::pair<const LabelStmt *, SourceLocation> getCursorLabelRef(CXCursor C);
/// \brief Create a overloaded declaration reference cursor for an expression.
CXCursor MakeCursorOverloadedDeclRef(const OverloadExpr *E,
CXTranslationUnit TU);
/// \brief Create a overloaded declaration reference cursor for a declaration.
CXCursor MakeCursorOverloadedDeclRef(const Decl *D, SourceLocation Location,
CXTranslationUnit TU);
/// \brief Create a overloaded declaration reference cursor for a template name.
CXCursor MakeCursorOverloadedDeclRef(TemplateName Template,
SourceLocation Location,
CXTranslationUnit TU);
/// \brief Internal storage for an overloaded declaration reference cursor;
typedef llvm::PointerUnion3<const OverloadExpr *, const Decl *,
OverloadedTemplateStorage *>
OverloadedDeclRefStorage;
/// \brief Unpack an overloaded declaration reference into an expression,
/// declaration, or template name along with the source location.
std::pair<OverloadedDeclRefStorage, SourceLocation>
getCursorOverloadedDeclRef(CXCursor C);
const Decl *getCursorDecl(CXCursor Cursor);
const Expr *getCursorExpr(CXCursor Cursor);
const Stmt *getCursorStmt(CXCursor Cursor);
const Attr *getCursorAttr(CXCursor Cursor);
const Decl *getCursorParentDecl(CXCursor Cursor);
ASTContext &getCursorContext(CXCursor Cursor);
ASTUnit *getCursorASTUnit(CXCursor Cursor);
CXTranslationUnit getCursorTU(CXCursor Cursor);
void getOverriddenCursors(CXCursor cursor,
SmallVectorImpl<CXCursor> &overridden);
/// \brief Create an opaque pool used for fast generation of overriden
/// CXCursor arrays.
void *createOverridenCXCursorsPool();
/// \brief Dispose of the overriden CXCursors pool.
void disposeOverridenCXCursorsPool(void *pool);
/// \brief Returns a index/location pair for a selector identifier if the cursor
/// points to one.
std::pair<int, SourceLocation> getSelectorIdentifierIndexAndLoc(CXCursor);
static inline int getSelectorIdentifierIndex(CXCursor cursor) {
return getSelectorIdentifierIndexAndLoc(cursor).first;
}
static inline SourceLocation getSelectorIdentifierLoc(CXCursor cursor) {
return getSelectorIdentifierIndexAndLoc(cursor).second;
}
CXCursor getSelectorIdentifierCursor(int SelIdx, CXCursor cursor);
static inline CXCursor getTypeRefedCallExprCursor(CXCursor cursor) {
CXCursor newCursor = cursor;
if (cursor.kind == CXCursor_CallExpr)
newCursor.xdata = 1;
return newCursor;
}
CXCursor getTypeRefCursor(CXCursor cursor);
/// \brief Generate a USR for \arg D and put it in \arg Buf.
/// \returns true if no USR was computed or the result should be ignored,
/// false otherwise.
bool getDeclCursorUSR(const Decl *D, SmallVectorImpl<char> &Buf);
bool operator==(CXCursor X, CXCursor Y);
inline bool operator!=(CXCursor X, CXCursor Y) {
return !(X == Y);
}
/// \brief Return true if the cursor represents a declaration that is the
/// first in a declaration group.
bool isFirstInDeclGroup(CXCursor C);
}} // end namespace: clang::cxcursor
#endif

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More