Extend libclang API
This commit is contained in:
committed by
SvyatoslavScherbina
parent
ab41017e58
commit
a38835cb46
@@ -23,6 +23,45 @@ apply plugin: org.jetbrains.kotlin.NativeInteropPlugin
|
||||
|
||||
apply plugin: 'c'
|
||||
|
||||
final Project libclangextProject = project(":libclangext")
|
||||
final String libclangextTask = libclangextProject.path + ":build"
|
||||
File libclangextDir = new File(libclangextProject.buildDir, "libs/clangext/static")
|
||||
final boolean libclangextIsEnabled = libclangextProject.isEnabled
|
||||
|
||||
final String libclang
|
||||
if (isWindows()) {
|
||||
libclang = "bin/libclang.dll"
|
||||
} else {
|
||||
libclang = "lib/${System.mapLibraryName("clang")}"
|
||||
}
|
||||
|
||||
List<String> cflags = [
|
||||
"-I$llvmDir/include",
|
||||
"-I${project(":libclangext").projectDir.absolutePath + "/src/main/include"}"
|
||||
]*.toString()
|
||||
|
||||
List<String> ldflags = ["$llvmDir/$libclang", "-L$libclangextDir.absolutePath", "-lclangext"]*.toString()
|
||||
|
||||
if (libclangextIsEnabled) {
|
||||
assert(isMac())
|
||||
ldflags.addAll(['-Wl,--no-demangle', '-Wl,-search_paths_first', '-Wl,-headerpad_max_install_names'])
|
||||
|
||||
List<String> llvmLibs = [
|
||||
"clangAST", "clangASTMatchers", "clangAnalysis", "clangBasic", "clangDriver", "clangEdit",
|
||||
"clangFrontend", "clangFrontendTool", "clangLex", "clangParse", "clangSema", "clangEdit",
|
||||
"clangRewrite", "clangRewriteFrontend", "clangStaticAnalyzerFrontend",
|
||||
"clangStaticAnalyzerCheckers", "clangStaticAnalyzerCore", "clangSerialization",
|
||||
"clangToolingCore",
|
||||
"clangTooling", "clangFormat", "LLVMTarget", "LLVMMC", "LLVMLinker", "LLVMTransformUtils",
|
||||
"LLVMBitWriter", "LLVMBitReader", "LLVMAnalysis", "LLVMProfileData", "LLVMCore",
|
||||
"LLVMSupport"
|
||||
].collect { "$llvmDir/lib/lib${it}.a".toString() }
|
||||
|
||||
ldflags.addAll(llvmLibs)
|
||||
ldflags.addAll(['-lpthread', '-lz', '-lm', '-lcurses'])
|
||||
}
|
||||
|
||||
|
||||
model {
|
||||
components {
|
||||
clangstubs(NativeLibrarySpec) {
|
||||
@@ -32,17 +71,11 @@ model {
|
||||
|
||||
binaries.all {
|
||||
cCompiler.args hostCompilerArgsForJni
|
||||
cCompiler.args "-I$llvmDir/include"
|
||||
cCompiler.args.addAll(cflags)
|
||||
}
|
||||
|
||||
binaries.withType(SharedLibraryBinarySpec) {
|
||||
final String libclang
|
||||
if (isWindows()) {
|
||||
libclang = "bin/libclang.dll"
|
||||
} else {
|
||||
libclang = "lib/${System.mapLibraryName("clang")}"
|
||||
}
|
||||
linker.args "$llvmDir/$libclang"
|
||||
linker.args.addAll(ldflags)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,12 +107,19 @@ classes.dependsOn nativelibs
|
||||
kotlinNativeInterop {
|
||||
clang {
|
||||
defFile 'clang.def'
|
||||
compilerOpts "-I$llvmDir/include"
|
||||
linkerOpts "-L$llvmDir/lib"
|
||||
compilerOpts cflags
|
||||
linkerOpts ldflags
|
||||
genTask.args '-keepcstubs', 'true'
|
||||
genTask.dependsOn libclangextTask
|
||||
genTask.inputs.dir libclangextDir
|
||||
}
|
||||
}
|
||||
|
||||
tasks.matching { it.name == 'linkClangstubsSharedLibrary' }.all {
|
||||
it.dependsOn libclangextTask
|
||||
it.inputs.dir libclangextDir
|
||||
}
|
||||
|
||||
task updatePrebuilt {
|
||||
dependsOn genClangInteropStubs
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
headers = clang-c/Index.h
|
||||
headers = clang-c/Index.h clang-c/ext.h
|
||||
|
||||
headerFilter = clang-c/**
|
||||
|
||||
@@ -7,10 +7,9 @@ compiler = clang
|
||||
compilerOpts = -std=c99 -fPIC
|
||||
linkerOpts.linux = -Wl,-z,noexecstack
|
||||
|
||||
linker = clang
|
||||
linker = clang++
|
||||
|
||||
linkerOpts = -fPIC \
|
||||
-lclang
|
||||
linkerOpts = -fPIC
|
||||
|
||||
strictEnums = CXErrorCode CXCursorKind CXTypeKind CXDiagnosticSeverity CXLoadDiag_Error CXSaveError \
|
||||
CXTUResourceUsageKind CXLinkageKind CXVisibilityKind CXLanguageKind CXCallingConv CXChildVisitResult \
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include <jni.h>
|
||||
#include <clang-c/Index.h>
|
||||
#include <clang-c/ext.h>
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_clang_clang_kni_1clang_1getCString (JNIEnv *jniEnv, jclass jclss, jlong string) {
|
||||
return (jlong) (clang_getCString(*(CXString*)string));
|
||||
@@ -1239,3 +1240,39 @@ JNIEXPORT jint JNICALL Java_clang_clang_kni_1clang_1Type_1visitFields (JNIEnv *j
|
||||
return (jint) (clang_Type_visitFields(*(CXType*)T, (CXFieldVisitor)visitor, (CXClientData)client_data));
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_clang_clang_kni_1clang_1Cursor_1getAttributeSpelling (JNIEnv *jniEnv, jclass jclss, jlong cursor) {
|
||||
return (jlong) (clang_Cursor_getAttributeSpelling(*(CXCursor*)cursor));
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_clang_clang_kni_1clang_1getDeclTypeAttributes (JNIEnv *jniEnv, jclass jclss, jlong cursor, jlong retValPlacement) {
|
||||
*(CXTypeAttributes*)retValPlacement = clang_getDeclTypeAttributes(*(CXCursor*)cursor);
|
||||
return (jlong) retValPlacement;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_clang_clang_kni_1clang_1getResultTypeAttributes (JNIEnv *jniEnv, jclass jclss, jlong typeAttributes, jlong retValPlacement) {
|
||||
*(CXTypeAttributes*)retValPlacement = clang_getResultTypeAttributes(*(CXTypeAttributes*)typeAttributes);
|
||||
return (jlong) retValPlacement;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_clang_clang_kni_1clang_1getCursorResultTypeAttributes (JNIEnv *jniEnv, jclass jclss, jlong cursor, jlong retValPlacement) {
|
||||
*(CXTypeAttributes*)retValPlacement = clang_getCursorResultTypeAttributes(*(CXCursor*)cursor);
|
||||
return (jlong) retValPlacement;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_clang_clang_kni_1clang_1Type_1getNullabilityKind (JNIEnv *jniEnv, jclass jclss, jlong type, jlong attributes) {
|
||||
return (jint) (clang_Type_getNullabilityKind(*(CXType*)type, *(CXTypeAttributes*)attributes));
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_clang_clang_kni_1clang_1Type_1getNumProtocols (JNIEnv *jniEnv, jclass jclss, jlong type) {
|
||||
return (jint) (clang_Type_getNumProtocols(*(CXType*)type));
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_clang_clang_kni_1clang_1Type_1getProtocol (JNIEnv *jniEnv, jclass jclss, jlong type, jint index, jlong retValPlacement) {
|
||||
*(CXCursor*)retValPlacement = clang_Type_getProtocol(*(CXType*)type, (unsigned int)index);
|
||||
return (jlong) retValPlacement;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_clang_clang_kni_1clang_1Cursor_1isObjCInitMethod (JNIEnv *jniEnv, jclass jclss, jlong cursor) {
|
||||
return (jint) (clang_Cursor_isObjCInitMethod(*(CXCursor*)cursor));
|
||||
}
|
||||
|
||||
|
||||
@@ -2962,6 +2962,88 @@ fun clang_Type_visitFields(T: CValue<CXType>, visitor: CXFieldVisitor?, client_d
|
||||
|
||||
private external fun kni_clang_Type_visitFields(T: NativePtr, visitor: NativePtr, client_data: NativePtr): Int
|
||||
|
||||
fun clang_Cursor_getAttributeSpelling(cursor: CValue<CXCursor>): CPointer<ByteVar>? {
|
||||
return memScoped {
|
||||
val _cursor = cursor.getPointer(memScope).rawValue
|
||||
val res = kni_clang_Cursor_getAttributeSpelling(_cursor)
|
||||
interpretCPointer<ByteVar>(res)
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_Cursor_getAttributeSpelling(cursor: NativePtr): NativePtr
|
||||
|
||||
fun clang_getDeclTypeAttributes(cursor: CValue<CXCursor>): CValue<CXTypeAttributes> {
|
||||
return memScoped {
|
||||
val _cursor = cursor.getPointer(memScope).rawValue
|
||||
val res = kni_clang_getDeclTypeAttributes(_cursor, alloc<CXTypeAttributes>().rawPtr)
|
||||
interpretPointed<CXTypeAttributes>(res).readValue()
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_getDeclTypeAttributes(cursor: NativePtr, retValPlacement: NativePtr): NativePtr
|
||||
|
||||
fun clang_getResultTypeAttributes(typeAttributes: CValue<CXTypeAttributes>): CValue<CXTypeAttributes> {
|
||||
return memScoped {
|
||||
val _typeAttributes = typeAttributes.getPointer(memScope).rawValue
|
||||
val res = kni_clang_getResultTypeAttributes(_typeAttributes, alloc<CXTypeAttributes>().rawPtr)
|
||||
interpretPointed<CXTypeAttributes>(res).readValue()
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_getResultTypeAttributes(typeAttributes: NativePtr, retValPlacement: NativePtr): NativePtr
|
||||
|
||||
fun clang_getCursorResultTypeAttributes(cursor: CValue<CXCursor>): CValue<CXTypeAttributes> {
|
||||
return memScoped {
|
||||
val _cursor = cursor.getPointer(memScope).rawValue
|
||||
val res = kni_clang_getCursorResultTypeAttributes(_cursor, alloc<CXTypeAttributes>().rawPtr)
|
||||
interpretPointed<CXTypeAttributes>(res).readValue()
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_getCursorResultTypeAttributes(cursor: NativePtr, retValPlacement: NativePtr): NativePtr
|
||||
|
||||
fun clang_Type_getNullabilityKind(type: CValue<CXType>, attributes: CValue<CXTypeAttributes>): CXNullabilityKind {
|
||||
return memScoped {
|
||||
val _type = type.getPointer(memScope).rawValue
|
||||
val _attributes = attributes.getPointer(memScope).rawValue
|
||||
val res = kni_clang_Type_getNullabilityKind(_type, _attributes)
|
||||
CXNullabilityKind.byValue(res)
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_Type_getNullabilityKind(type: NativePtr, attributes: NativePtr): Int
|
||||
|
||||
fun clang_Type_getNumProtocols(type: CValue<CXType>): Int {
|
||||
return memScoped {
|
||||
val _type = type.getPointer(memScope).rawValue
|
||||
val res = kni_clang_Type_getNumProtocols(_type)
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_Type_getNumProtocols(type: NativePtr): Int
|
||||
|
||||
fun clang_Type_getProtocol(type: CValue<CXType>, index: Int): CValue<CXCursor> {
|
||||
return memScoped {
|
||||
val _type = type.getPointer(memScope).rawValue
|
||||
val _index = index
|
||||
val res = kni_clang_Type_getProtocol(_type, _index, alloc<CXCursor>().rawPtr)
|
||||
interpretPointed<CXCursor>(res).readValue()
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_Type_getProtocol(type: NativePtr, index: Int, retValPlacement: NativePtr): NativePtr
|
||||
|
||||
fun clang_Cursor_isObjCInitMethod(cursor: CValue<CXCursor>): Int {
|
||||
return memScoped {
|
||||
val _cursor = cursor.getPointer(memScope).rawValue
|
||||
val res = kni_clang_Cursor_isObjCInitMethod(_cursor)
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
private external fun kni_clang_Cursor_isObjCInitMethod(cursor: NativePtr): Int
|
||||
|
||||
val CINDEX_VERSION_MAJOR: Int = 0
|
||||
|
||||
val CINDEX_VERSION_MINOR: Int = 35
|
||||
@@ -3682,6 +3764,17 @@ class IndexerCallbacks(override val rawPtr: NativePtr) : CStructVar() {
|
||||
|
||||
}
|
||||
|
||||
@CNaturalStruct("typeOpaquePtr")
|
||||
class CXTypeAttributes(override val rawPtr: NativePtr) : CStructVar() {
|
||||
|
||||
companion object : Type(8, 8)
|
||||
|
||||
var typeOpaquePtr: COpaquePointer?
|
||||
get() = memberAt<COpaquePointerVar>(0).value
|
||||
set(value) { memberAt<COpaquePointerVar>(0).value = value }
|
||||
|
||||
}
|
||||
|
||||
enum class CXErrorCode(override val value: Int) : CEnum {
|
||||
CXError_Success(0),
|
||||
CXError_Failure(1),
|
||||
@@ -4630,6 +4723,24 @@ val CXIndexOpt_IndexImplicitTemplateInstantiations: CXIndexOptFlags = 4
|
||||
val CXIndexOpt_SuppressWarnings: CXIndexOptFlags = 8
|
||||
val CXIndexOpt_SkipParsedBodiesInSession: CXIndexOptFlags = 16
|
||||
|
||||
enum class CXNullabilityKind(override val value: Int) : CEnum {
|
||||
CXNullabilityKind_Nullable(0),
|
||||
CXNullabilityKind_NonNull(1),
|
||||
CXNullabilityKind_Unspecified(2),
|
||||
;
|
||||
|
||||
companion object {
|
||||
fun byValue(value: Int) = CXNullabilityKind.values().find { it.value == value }!!
|
||||
}
|
||||
|
||||
class Var(override val rawPtr: NativePtr) : CEnumVar() {
|
||||
companion object : Type(IntVar.size.toInt())
|
||||
var value: CXNullabilityKind
|
||||
get() = byValue(this.reinterpret<IntVar>().value)
|
||||
set(value) { this.reinterpret<IntVar>().value = value.value }
|
||||
}
|
||||
}
|
||||
|
||||
typealias CXVirtualFileOverlayVar = CPointerVarOf<CXVirtualFileOverlay>
|
||||
typealias CXVirtualFileOverlay = CPointer<CXVirtualFileOverlayImpl>
|
||||
|
||||
|
||||
@@ -72,6 +72,10 @@ class NamedNativeInteropConfig implements Named {
|
||||
pkg = value
|
||||
}
|
||||
|
||||
void compilerOpts(List<String> values) {
|
||||
compilerOpts.addAll(values)
|
||||
}
|
||||
|
||||
void compilerOpts(String... values) {
|
||||
compilerOpts.addAll(values)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
apply plugin: "cpp"
|
||||
apply plugin: "c"
|
||||
|
||||
ext.isEnabled = isMac()
|
||||
|
||||
model {
|
||||
components {
|
||||
clangext(NativeLibrarySpec) {
|
||||
sources {
|
||||
cpp {
|
||||
source.srcDirs "src/main/cpp"
|
||||
exportedHeaders.srcDirs "src/main/include"
|
||||
}
|
||||
}
|
||||
binaries.withType(StaticLibraryBinarySpec) { binary ->
|
||||
cppCompiler.args "--std=c++11", "-g", "-fPIC", "-I${llvmDir}/include"
|
||||
if (isEnabled) {
|
||||
cppCompiler.args '-DLIBCLANGEXT_ENABLE=1'
|
||||
}
|
||||
}
|
||||
binaries.withType(SharedLibraryBinarySpec) { binary ->
|
||||
buildable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <clang/AST/Attr.h>
|
||||
#include <clang/AST/DeclObjC.h>
|
||||
#include <clang/Frontend/ASTUnit.h>
|
||||
#include "clang-c/ext.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
|
||||
static CXCursor makeObjCProtocolDeclCXCursor(const ObjCProtocolDecl* decl, CXTranslationUnit translationUnit) {
|
||||
auto kind = CXCursor_ObjCProtocolDecl;
|
||||
CXCursor result = { kind, 0, { decl, (void*)(intptr_t) 1, translationUnit } };
|
||||
return result;
|
||||
}
|
||||
|
||||
static const Attr* getCursorAttr(CXCursor cursor) {
|
||||
return static_cast<const Attr *>(cursor.data[1]);
|
||||
}
|
||||
|
||||
static const Decl *getCursorDecl(CXCursor Cursor) {
|
||||
return static_cast<const Decl *>(Cursor.data[0]);
|
||||
}
|
||||
|
||||
static const QualType unwrapCXType(CXType type) {
|
||||
return QualType::getFromOpaquePtr(type.data[0]);
|
||||
}
|
||||
|
||||
static CXTranslationUnit getTranslationUnit(CXType type) {
|
||||
return static_cast<CXTranslationUnit>(type.data[1]);
|
||||
}
|
||||
|
||||
static ASTUnit* getASTUnit(CXTranslationUnit translationUnit) {
|
||||
return reinterpret_cast<ASTUnit**>(translationUnit)[1];
|
||||
}
|
||||
|
||||
// The functions above are totally libclang-implementation-specific and thus version-dependent.
|
||||
|
||||
static CXTypeAttributes makeCXTypeAttributes(QualType qualType) {
|
||||
CXTypeAttributes result = { qualType.getAsOpaquePtr() };
|
||||
return result;
|
||||
}
|
||||
|
||||
static QualType unwrapCXTypeAttributes(CXTypeAttributes attributes) {
|
||||
return QualType::getFromOpaquePtr(attributes.typeOpaquePtr);
|
||||
}
|
||||
|
||||
#else // LIBCLANGEXT_ENABLE
|
||||
|
||||
static CXTypeAttributes makeCXTypeAttributes() {
|
||||
CXTypeAttributes result = { nullptr };
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // LIBCLANGEXT_ENABLE
|
||||
|
||||
extern "C" {
|
||||
|
||||
const char* clang_Cursor_getAttributeSpelling(CXCursor cursor) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
if (clang_isAttribute(cursor.kind) == 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return getCursorAttr(cursor)->getSpelling();
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
CXTypeAttributes clang_getDeclTypeAttributes(CXCursor cursor) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
CXType cxType = clang_getCursorType(cursor);
|
||||
if (clang_isDeclaration(cursor.kind)) {
|
||||
const Decl *D = getCursorDecl(cursor);
|
||||
if (D) {
|
||||
if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
|
||||
return makeCXTypeAttributes(DD->getType());
|
||||
}
|
||||
}
|
||||
return makeCXTypeAttributes(QualType());
|
||||
#else
|
||||
return makeCXTypeAttributes();
|
||||
#endif
|
||||
}
|
||||
|
||||
CXTypeAttributes clang_getResultTypeAttributes(CXTypeAttributes typeAttributes) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
QualType qualType = unwrapCXTypeAttributes(typeAttributes);
|
||||
if (qualType.isNull())
|
||||
return makeCXTypeAttributes(qualType);
|
||||
|
||||
if (const FunctionType *functionType = qualType->getAs<FunctionType>())
|
||||
return makeCXTypeAttributes(functionType->getReturnType());
|
||||
|
||||
return makeCXTypeAttributes(QualType());
|
||||
#else
|
||||
return makeCXTypeAttributes();
|
||||
#endif
|
||||
}
|
||||
|
||||
CXTypeAttributes clang_getCursorResultTypeAttributes(CXCursor cursor) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
if (clang_isDeclaration(cursor.kind)) {
|
||||
const Decl *decl = getCursorDecl(cursor);
|
||||
if (const ObjCMethodDecl *methodDecl = dyn_cast_or_null<ObjCMethodDecl>(decl))
|
||||
return makeCXTypeAttributes(methodDecl->getReturnType());
|
||||
|
||||
return clang_getResultTypeAttributes(clang_getDeclTypeAttributes(cursor));
|
||||
}
|
||||
|
||||
return makeCXTypeAttributes(QualType());
|
||||
#else
|
||||
return makeCXTypeAttributes();
|
||||
#endif
|
||||
}
|
||||
|
||||
enum CXNullabilityKind clang_Type_getNullabilityKind(CXType type, CXTypeAttributes attributes) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
CXTranslationUnit translationUnit = getTranslationUnit(type);
|
||||
ASTContext& astContext = getASTUnit(translationUnit)->getASTContext();
|
||||
|
||||
QualType qualType = unwrapCXTypeAttributes(attributes);
|
||||
|
||||
auto kind = qualType->getNullability(astContext);
|
||||
if (!kind.hasValue()) {
|
||||
return CXNullabilityKind_Unspecified;
|
||||
}
|
||||
|
||||
switch (*kind) {
|
||||
case NullabilityKind::NonNull: return CXNullabilityKind_NonNull;
|
||||
case NullabilityKind::Nullable: return CXNullabilityKind_Nullable;
|
||||
case NullabilityKind::Unspecified: return CXNullabilityKind_Unspecified;
|
||||
default: assert(false);
|
||||
}
|
||||
#else
|
||||
return CXNullabilityKind_Unspecified;
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned clang_Type_getNumProtocols(CXType type) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
QualType qualType = unwrapCXType(type);
|
||||
if (auto objCObjectPointerType = qualType->getAs<ObjCObjectPointerType>()) {
|
||||
return objCObjectPointerType->getObjectType()->getNumProtocols();
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
CXCursor clang_Type_getProtocol(CXType type, unsigned index) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
QualType qualType = unwrapCXType(type);
|
||||
if (auto objCObjectPointerType = qualType->getAs<ObjCObjectPointerType>()) {
|
||||
auto objectType = objCObjectPointerType->getObjectType();
|
||||
unsigned n = objectType->getNumProtocols();
|
||||
if (index < n) {
|
||||
auto protocolDecl = objectType->getProtocol(index);
|
||||
auto kind = CXCursor_ObjCProtocolDecl;
|
||||
return makeObjCProtocolDeclCXCursor(protocolDecl, getTranslationUnit(type));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return clang_getNullCursor();
|
||||
}
|
||||
|
||||
unsigned clang_Cursor_isObjCInitMethod(CXCursor cursor) {
|
||||
#if LIBCLANGEXT_ENABLE
|
||||
if (cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
|
||||
const Decl *decl = getCursorDecl(cursor);
|
||||
if (const ObjCMethodDecl *methodDecl = dyn_cast_or_null<ObjCMethodDecl>(decl)) {
|
||||
return methodDecl->getMethodFamily() == OMF_init;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
// TODO: the API declared below should eventually be refined and contributed to libclang.
|
||||
|
||||
|
||||
// libclang doesn't include the type attributes when constructing `CXType`,
|
||||
// so attributes have to be represented separately:
|
||||
typedef struct {
|
||||
const void* typeOpaquePtr;
|
||||
} CXTypeAttributes;
|
||||
|
||||
enum CXNullabilityKind {
|
||||
CXNullabilityKind_Nullable,
|
||||
CXNullabilityKind_NonNull,
|
||||
CXNullabilityKind_Unspecified
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const char* clang_Cursor_getAttributeSpelling(CXCursor cursor);
|
||||
|
||||
CXTypeAttributes clang_getDeclTypeAttributes(CXCursor cursor);
|
||||
|
||||
CXTypeAttributes clang_getResultTypeAttributes(CXTypeAttributes typeAttributes);
|
||||
|
||||
CXTypeAttributes clang_getCursorResultTypeAttributes(CXCursor cursor);
|
||||
|
||||
enum CXNullabilityKind clang_Type_getNullabilityKind(CXType type, CXTypeAttributes attributes);
|
||||
|
||||
unsigned clang_Type_getNumProtocols(CXType type);
|
||||
|
||||
CXCursor clang_Type_getProtocol(CXType type, unsigned index);
|
||||
|
||||
unsigned clang_Cursor_isObjCInitMethod(CXCursor cursor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@ include ':Interop:Indexer'
|
||||
include ':Interop:StubGenerator'
|
||||
include ':Interop:Runtime'
|
||||
include ':llvmDebugInfoC'
|
||||
include ':libclangext'
|
||||
include ':klib'
|
||||
include ':backend.native'
|
||||
include ':runtime'
|
||||
|
||||
Reference in New Issue
Block a user