1 #include <stdlib.h> 2 #include <string.h> 3 #include <jni.h> 4 #include <clang-c/Index.h> 5 #include <assert.h> 6 7 static jclass clsStructType; 8 static jfieldID dataStructType; 9 10 static jclass clsIndex; 11 static jclass clsCursor; 12 static jclass clsType; 13 static jclass clsjavaLangString; 14 static jclass clsIAE; 15 static jmethodID ctorIndex; 16 static jmethodID ctorCursor; 17 static jmethodID ctorType; 18 static jmethodID visitorID; 19 static jclass clsSourceLocation; 20 static jmethodID ctorSourceLocation; 21 static jclass clsLocation; 22 static jmethodID ctorLocation; 23 static jclass clsSourceRange; 24 static jmethodID ctorSourceRange; 25 26 27 jstring CX2JString(JNIEnv *env, CXString str) { 28 const char* cstr = clang_getCString(str); 29 jstring rv = env->NewStringUTF(cstr); 30 clang_disposeString(str); 31 return rv; 32 } 33 34 struct LocationFactory { 35 CXFile file; 36 unsigned line; 37 unsigned col; 38 unsigned offset; 39 40 jobject get(JNIEnv *env, CXSourceLocation * const loc, 41 void (*func)(CXSourceLocation, CXFile*, unsigned*, unsigned*, unsigned*)) { 42 func(*loc, &file, &line, &col, &offset); 43 return env->NewObject(clsLocation, ctorLocation, 44 CX2JString(env, clang_getFileName(file)), line, col, offset); 45 } 46 }; 47 48 #define J2P(env, pojo) \ 49 (env->GetDirectBufferAddress(env->GetObjectField(pojo, dataStructType))) 50 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 55 jint JNI_OnLoad(JavaVM *vm, void *reserved) { 56 JNIEnv* env; 57 58 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { 59 // force unload 60 return -1; 61 } 62 63 clsjavaLangString = (jclass) env->NewGlobalRef(env->FindClass("java/lang/String")); 64 clsIAE = (jclass) env->NewGlobalRef(env->FindClass("java/lang/IllegalArgumentException")); 65 66 clsIndex = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/Index")); 67 ctorIndex = env->GetMethodID(clsIndex, "<init>", "(J)V"); 68 69 clsStructType = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/StructType")); 70 dataStructType = env->GetFieldID(clsStructType, "data", "Ljava/nio/ByteBuffer;"); 71 assert(dataStructType != NULL); 72 73 clsCursor = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/Cursor")); 74 ctorCursor = env->GetMethodID(clsCursor, "<init>", "(Ljava/nio/ByteBuffer;)V"); 75 visitorID = env->GetStaticMethodID(clsCursor, "visit", 76 "(Ljdk/internal/clang/Cursor$Visitor;Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;Ljava/lang/Object;)I"); 77 assert(visitorID != NULL); 78 79 clsType = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/Type")); 80 ctorType = env->GetMethodID(clsType, "<init>", "(Ljava/nio/ByteBuffer;)V"); 81 82 clsSourceLocation = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/SourceLocation")); 83 ctorSourceLocation = env->GetMethodID(clsSourceLocation, "<init>", "(Ljava/nio/ByteBuffer;)V"); 84 85 clsLocation = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/SourceLocation$Location")); 86 ctorLocation = env->GetMethodID(clsLocation, "<init>", "(Ljava/lang/String;III)V"); 87 assert(ctorLocation != NULL); 88 89 clsSourceRange = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/SourceRange")); 90 ctorSourceRange = env->GetMethodID(clsSourceRange, "<init>", "(Ljava/nio/ByteBuffer;)V"); 91 92 return JNI_VERSION_1_6; 93 } 94 95 void JNI_OnUnload(JavaVM *vm, void *reserved) { 96 JNIEnv* env; 97 98 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { 99 return; 100 } 101 102 env->DeleteGlobalRef(clsIndex); 103 env->DeleteGlobalRef(clsCursor); 104 env->DeleteGlobalRef(clsType); 105 } 106 107 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_LibClang_createIndex 108 (JNIEnv *env, jclass cls) { 109 CXIndex idx = clang_createIndex(0, 0); 110 clang_toggleCrashRecovery(false); 111 // CXIndex is a void* 112 return env->NewObject(clsIndex, ctorIndex, (jlong) idx); 113 } 114 115 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_LibClang_version 116 (JNIEnv *env, jclass cls) { 117 CXString ver = clang_getClangVersion(); 118 return CX2JString(env, ver); 119 } 120 121 JNIEXPORT void JNICALL Java_jdk_internal_clang_Index_disposeIndex 122 (JNIEnv *env, jobject obj, jlong addr) { 123 clang_disposeIndex((CXIndex) addr); 124 } 125 126 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Index_parseFile 127 (JNIEnv *env, jobject obj, jlong addr, jstring path, jboolean detailed, jobjectArray args) { 128 const char *filename = env->GetStringUTFChars(path, NULL); 129 jsize argCnt = env->GetArrayLength(args); 130 const char** cargs = (const char**) calloc(argCnt, sizeof(char*)); 131 jsize i; 132 jstring arg; 133 for (i = 0; i < argCnt; i++) { 134 arg = (jstring) env->GetObjectArrayElement(args, i); 135 cargs[i] = env->GetStringUTFChars(arg, NULL); 136 } 137 CXTranslationUnit tu = clang_parseTranslationUnit((CXIndex) addr, 138 filename, cargs, argCnt, NULL, 0, detailed ? CXTranslationUnit_DetailedPreprocessingRecord : CXTranslationUnit_None); 139 env->ReleaseStringUTFChars(path, filename); 140 for (i = 0; i < argCnt; i++) { 141 arg = (jstring) env->GetObjectArrayElement(args, i); 142 env->ReleaseStringUTFChars(arg, cargs[i]); 143 } 144 free(cargs); 145 return (jlong) tu; 146 } 147 148 JNIEXPORT void JNICALL Java_jdk_internal_clang_Index_disposeTranslationUnit 149 (JNIEnv *env, jobject obj, jlong tu) { 150 clang_disposeTranslationUnit((CXTranslationUnit) tu); 151 } 152 153 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Index_getTranslationUnitCursor 154 (JNIEnv *env, jobject obj, jlong tu) { 155 CXCursor cursor = clang_getTranslationUnitCursor((CXTranslationUnit) tu); 156 jobject buffer = env->NewDirectByteBuffer(&cursor, sizeof(CXCursor)); 157 return env->NewObject(clsCursor, ctorCursor, buffer); 158 } 159 160 JNIEXPORT jobjectArray JNICALL Java_jdk_internal_clang_Index_getTranslationUnitDiagnostics 161 (JNIEnv *env, jobject obj, jlong jtu) { 162 CXTranslationUnit tu = (CXTranslationUnit) jtu; 163 unsigned cnt = clang_getNumDiagnostics(tu); 164 unsigned i; 165 166 if (cnt == 0) { 167 return NULL; 168 } 169 170 jclass clsDiagnostic = (jclass) env->NewGlobalRef(env->FindClass("jdk/internal/clang/Diagnostic")); 171 jmethodID ctorDiagnostic = env->GetMethodID(clsDiagnostic, "<init>", "(J)V"); 172 173 jobjectArray rv = env->NewObjectArray(cnt, clsDiagnostic, NULL); 174 jobject jdiag; 175 176 for (i = 0; i < cnt; i++) { 177 CXDiagnostic diag = clang_getDiagnostic(tu, i); 178 jdiag = env->NewObject(clsDiagnostic, ctorDiagnostic, (jlong) diag); 179 env->SetObjectArrayElement(rv, i, jdiag); 180 } 181 182 return rv; 183 } 184 185 static int 186 compareSourceLocation(JNIEnv *env, CXSourceLocation loc1, CXSourceLocation loc2) { 187 struct { 188 CXFile file; 189 unsigned line; 190 unsigned column; 191 unsigned offset; 192 } info1, info2; 193 194 clang_getSpellingLocation(loc1, &info1.file, &info1.line, &info1.column, &info1.offset); 195 clang_getSpellingLocation(loc2, &info2.file, &info2.line, &info2.column, &info2.offset); 196 197 CXString fileName1 = clang_getFileName(info1.file); 198 CXString fileName2 = clang_getFileName(info2.file); 199 200 int cmp = strcmp(clang_getCString(fileName1), clang_getCString(fileName2)); 201 202 clang_disposeString(fileName1); 203 clang_disposeString(fileName2); 204 205 if (cmp != 0) { 206 env->ThrowNew(clsIAE, "Source locations must be in same file"); 207 return 0; 208 } 209 210 if (info1.line != info2.line) { 211 return info1.line - info2.line; 212 } else if (info1.column != info2.column) { 213 return info1.column - info2.column; 214 } else if (info1.offset != info2.offset) { 215 return info1.offset - info2.offset; 216 } 217 218 return 0; 219 } 220 221 static jboolean 222 locationInRange(JNIEnv *env, CXSourceLocation loc, CXSourceRange range) { 223 CXSourceLocation start = clang_getRangeStart(range); 224 CXSourceLocation end = clang_getRangeEnd(range); 225 226 return 227 compareSourceLocation(env, loc, start) >= 0 && 228 compareSourceLocation(env, loc, end) <= 0; 229 } 230 231 JNIEXPORT jobjectArray JNICALL Java_jdk_internal_clang_Index_tokenize 232 (JNIEnv *env, jobject obj, jlong jtu, jobject range) { 233 CXTranslationUnit tu = (CXTranslationUnit) jtu; 234 CXSourceRange *ptr = (CXSourceRange*) J2P(env, range); 235 236 CXToken *tokens; 237 unsigned nTokens, i; 238 239 clang_tokenize(tu, *ptr, &tokens, &nTokens); 240 241 242 // This filtering stuff is to ork-around a bug in libclang which 243 // includes tokens outside of the range (off-by-one) 244 // see: https://llvm.org/bugs/show_bug.cgi?id=9069 245 CXToken* filteredTokens = (CXToken*)alloca(nTokens * sizeof(CXToken)); 246 unsigned nFilteredTokens = 0; 247 jobjectArray jtokens = NULL; 248 249 for (unsigned i = 0; i < nTokens; i++) { 250 CXToken token = tokens[i]; 251 CXSourceLocation tokenLocation = clang_getTokenLocation(tu, token); 252 if (!locationInRange(env, tokenLocation, *ptr)) { 253 continue; 254 } 255 if (env->ExceptionCheck()) { 256 goto out; 257 } 258 259 filteredTokens[nFilteredTokens++] = token; 260 } 261 262 jtokens = env->NewObjectArray(nFilteredTokens, clsjavaLangString, NULL); 263 264 for (unsigned i = 0; i < nFilteredTokens; i++) { 265 CXString tokenString = clang_getTokenSpelling(tu, filteredTokens[i]); 266 jstring str = env->NewStringUTF(clang_getCString(tokenString)); 267 env->SetObjectArrayElement(jtokens, i, str); 268 clang_disposeString(tokenString); 269 } 270 271 out: 272 clang_disposeTokens(tu, tokens, nTokens); 273 274 return jtokens; 275 } 276 277 /************************************* 278 * Diagnostic/CXDiagnostic functions 279 *************************************/ 280 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Diagnostic_severity 281 (JNIEnv *env, jobject obj, jlong diag) { 282 return clang_getDiagnosticSeverity((CXDiagnostic) diag); 283 } 284 285 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Diagnostic_location 286 (JNIEnv *env, jobject obj, jlong diag) { 287 CXSourceLocation loc = clang_getDiagnosticLocation((CXDiagnostic) diag); 288 if (clang_equalLocations(loc, clang_getNullLocation())) { 289 return NULL; 290 } 291 292 jobject buffer = env->NewDirectByteBuffer(&loc, sizeof(CXSourceLocation)); 293 return env->NewObject(clsSourceLocation, ctorSourceLocation, buffer); 294 } 295 296 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_Diagnostic_spelling 297 (JNIEnv *env, jobject obj, jlong diag) { 298 CXString str = clang_getDiagnosticSpelling((CXDiagnostic) diag); 299 return CX2JString(env, str); 300 } 301 302 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_Diagnostic_format 303 (JNIEnv *env, jobject obj, jlong diag) { 304 CXString str = clang_formatDiagnostic((CXDiagnostic) diag, 305 clang_defaultDiagnosticDisplayOptions()); 306 return CX2JString(env, str); 307 } 308 309 JNIEXPORT void JNICALL Java_jdk_internal_clang_Diagnostic_dispose 310 (JNIEnv *env, jobject obj, jlong diag) { 311 clang_disposeDiagnostic((CXDiagnostic) diag); 312 } 313 314 /************************************* 315 * Cursor/CXCursor functions 316 *************************************/ 317 318 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_isDeclaration 319 (JNIEnv *env, jobject cursor) { 320 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 321 return clang_isDeclaration(clang_getCursorKind(*ptr)); 322 } 323 324 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_isPreprocessing 325 (JNIEnv *env, jobject cursor) { 326 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 327 return clang_isPreprocessing(clang_getCursorKind(*ptr)); 328 } 329 330 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_isInvalid 331 (JNIEnv *env, jobject cursor) { 332 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 333 return clang_isInvalid(clang_getCursorKind(*ptr)); 334 } 335 336 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_isDefinition 337 (JNIEnv *env, jobject cursor) { 338 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 339 return clang_isCursorDefinition(*ptr); 340 } 341 342 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_isMacroFunctionLike 343 (JNIEnv *env, jobject cursor) { 344 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 345 return clang_Cursor_isMacroFunctionLike(*ptr); 346 } 347 348 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_isAnonymousStruct 349 (JNIEnv *env, jobject cursor) { 350 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 351 return clang_Cursor_isAnonymous(*ptr); 352 } 353 354 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_Cursor_spelling 355 (JNIEnv *env, jobject cursor) { 356 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 357 CXString spelling = clang_getCursorSpelling(*ptr); 358 return CX2JString(env, spelling); 359 } 360 361 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_Cursor_USR 362 (JNIEnv *env, jobject cursor) { 363 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 364 CXString usr = clang_getCursorUSR(*ptr); 365 return CX2JString(env, usr); 366 } 367 368 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Cursor_kind1 369 (JNIEnv *env, jobject cursor) { 370 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 371 return clang_getCursorKind(*ptr); 372 } 373 374 struct visitor_data { 375 JavaVM *jvm; 376 jobject visitor; 377 jobject data; 378 }; 379 380 enum CXChildVisitResult visitorFunc(CXCursor cursor, 381 CXCursor parent, 382 CXClientData data) { 383 struct visitor_data *pCtx = (struct visitor_data*) data; 384 // Just to be cautious in case callback from different thread 385 // although this is likely not the case 386 JNIEnv *env; 387 if (JNI_OK != pCtx->jvm->AttachCurrentThread(reinterpret_cast<void**>(&env), NULL)) { 388 printf("Failed to attach JVM\n"); 389 return CXChildVisit_Break; 390 }; 391 392 jobject jC = env->NewDirectByteBuffer(&cursor, sizeof(CXCursor)); 393 jobject jP = env->NewDirectByteBuffer(&parent, sizeof(CXCursor)); 394 return (CXChildVisitResult) env->CallStaticIntMethod(clsCursor, 395 visitorID, 396 pCtx->visitor, 397 jC, jP, 398 pCtx->data); 399 } 400 401 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Cursor_visitChildren 402 (JNIEnv *env, jobject cursor, jobject visitor, jobject data) { 403 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 404 struct visitor_data ctx; 405 env->GetJavaVM(&(ctx.jvm)); 406 ctx.visitor = visitor; 407 ctx.data = data; 408 return clang_visitChildren(*ptr, visitorFunc, &ctx); 409 } 410 411 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Cursor_equalCursor 412 (JNIEnv *env, jobject cursor, jobject other) { 413 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 414 CXCursor *ptrOther = (CXCursor*) J2P(env, other); 415 return clang_equalCursors(*ptr, *ptrOther); 416 } 417 418 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Cursor_type 419 (JNIEnv *env, jobject cursor) { 420 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 421 CXType type = clang_getCursorType(*ptr); 422 jobject buffer = env->NewDirectByteBuffer(&type, sizeof(CXType)); 423 return env->NewObject(clsType, ctorType, buffer); 424 } 425 426 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Cursor_getEnumDeclIntegerType 427 (JNIEnv *env, jobject cursor) { 428 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 429 CXType type = clang_getEnumDeclIntegerType(*ptr); 430 jobject buffer = env->NewDirectByteBuffer(&type, sizeof(CXType)); 431 return env->NewObject(clsType, ctorType, buffer); 432 } 433 434 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Cursor_getDefinition 435 (JNIEnv *env, jobject cursor) { 436 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 437 CXCursor def = clang_getCursorDefinition(*ptr); 438 jobject buffer = env->NewDirectByteBuffer(&def, sizeof(CXCursor)); 439 return env->NewObject(clsCursor, ctorCursor, buffer); 440 } 441 442 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Cursor_getSourceLocation 443 (JNIEnv *env, jobject cursor) { 444 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 445 446 // Some CXCursor has no valid location, such as the one from TranslationUnit 447 CXSourceLocation loc = clang_getCursorLocation(*ptr); 448 if (clang_equalLocations(loc, clang_getNullLocation())) { 449 return NULL; 450 } 451 452 jobject buffer = env->NewDirectByteBuffer(&loc, sizeof(CXSourceLocation)); 453 return env->NewObject(clsSourceLocation, ctorSourceLocation, buffer); 454 } 455 456 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Cursor_getExtent 457 (JNIEnv *env, jobject cursor) { 458 CXCursor *ptr = (CXCursor*) J2P(env, cursor); 459 460 CXSourceRange range = clang_getCursorExtent(*ptr); 461 if (clang_Range_isNull(range)) { 462 return NULL; 463 } 464 465 jobject buffer = env->NewDirectByteBuffer(&range, sizeof(CXSourceRange)); 466 return env->NewObject(clsSourceRange, ctorSourceRange, buffer); 467 } 468 469 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Cursor_getArgument 470 (JNIEnv *env, jobject _self, jint idx) { 471 CXCursor *ptr = (CXCursor*) J2P(env, _self); 472 CXCursor result = clang_Cursor_getArgument(*ptr, idx); 473 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXCursor)); 474 return env->NewObject(clsCursor, ctorCursor, buffer); 475 } 476 477 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Cursor_numberOfArgs 478 (JNIEnv *env, jobject _self) { 479 CXCursor *ptr = (CXCursor*) J2P(env, _self); 480 return clang_Cursor_getNumArguments(*ptr); 481 } 482 483 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Cursor_getEnumConstantValue 484 (JNIEnv *env, jobject _self) { 485 CXCursor *ptr = (CXCursor*) J2P(env, _self); 486 return clang_getEnumConstantDeclValue(*ptr); 487 } 488 489 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Cursor_getEnumConstantUnsignedValue 490 (JNIEnv *env, jobject _self) { 491 CXCursor *ptr = (CXCursor*) J2P(env, _self); 492 return clang_getEnumConstantDeclUnsignedValue(*ptr); 493 } 494 495 JNIEXPORT bool JNICALL Java_jdk_internal_clang_Cursor_isBitField 496 (JNIEnv *env, jobject _self) { 497 CXCursor *ptr = (CXCursor*) J2P(env, _self); 498 return clang_Cursor_isBitField(*ptr); 499 } 500 501 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Cursor_getBitFieldWidth 502 (JNIEnv *env, jobject _self) { 503 CXCursor *ptr = (CXCursor*) J2P(env, _self); 504 return clang_getFieldDeclBitWidth(*ptr); 505 } 506 507 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Cursor_getTranslationUnit0 508 (JNIEnv *env, jobject _self) { 509 CXCursor *ptr = (CXCursor*) J2P(env, _self); 510 return (jlong) clang_Cursor_getTranslationUnit(*ptr); 511 } 512 513 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_Cursor_getMangling 514 (JNIEnv *env, jobject _self) { 515 CXCursor *ptr = (CXCursor*) J2P(env, _self); 516 CXString mangled = clang_Cursor_getMangling(*ptr); 517 return CX2JString(env, mangled); 518 } 519 520 /************************************* 521 * Type <-> CXType related functions 522 *************************************/ 523 524 JNIEXPORT jboolean JNICALL Java_jdk_internal_clang_Type_isVariadic 525 (JNIEnv *env, jobject type) { 526 CXType *ptr = (CXType*) J2P(env, type); 527 return clang_isFunctionTypeVariadic(*ptr); 528 } 529 530 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Type_resultType 531 (JNIEnv *env, jobject type) { 532 CXType *ptr = (CXType*) J2P(env, type); 533 CXType result = clang_getResultType(*ptr); 534 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXType)); 535 return env->NewObject(clsType, ctorType, buffer); 536 } 537 538 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Type_numberOfArgs 539 (JNIEnv *env, jobject type) { 540 CXType *ptr = (CXType*) J2P(env, type); 541 return clang_getNumArgTypes(*ptr); 542 } 543 544 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Type_argType 545 (JNIEnv *env, jobject type, jint idx) { 546 CXType *ptr = (CXType*) J2P(env, type); 547 CXType result = clang_getArgType(*ptr, idx); 548 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXType)); 549 return env->NewObject(clsType, ctorType, buffer); 550 } 551 552 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Type_getCallingConvention1 553 (JNIEnv *env, jobject type) { 554 CXType *ptr = (CXType*) J2P(env, type); 555 return clang_getFunctionTypeCallingConv(*ptr); 556 } 557 558 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Type_getPointeeType 559 (JNIEnv *env, jobject type) { 560 CXType *ptr = (CXType*) J2P(env, type); 561 CXType result = clang_getPointeeType(*ptr); 562 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXType)); 563 return env->NewObject(clsType, ctorType, buffer); 564 } 565 566 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Type_getElementType 567 (JNIEnv *env, jobject type) { 568 CXType *ptr = (CXType*) J2P(env, type); 569 CXType result = clang_getElementType(*ptr); 570 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXType)); 571 return env->NewObject(clsType, ctorType, buffer); 572 } 573 574 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Type_getNumberOfElements 575 (JNIEnv *env, jobject type) { 576 CXType *ptr = (CXType*) J2P(env, type); 577 return clang_getNumElements(*ptr); 578 } 579 580 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Type_canonicalType 581 (JNIEnv *env, jobject type) { 582 CXType *ptr = (CXType*) J2P(env, type); 583 CXType result = clang_getCanonicalType(*ptr); 584 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXType)); 585 return env->NewObject(clsType, ctorType, buffer); 586 } 587 588 JNIEXPORT jstring JNICALL Java_jdk_internal_clang_Type_spelling 589 (JNIEnv *env, jobject type) { 590 CXType *ptr = (CXType*) J2P(env, type); 591 CXString spelling = clang_getTypeSpelling(*ptr); 592 return CX2JString(env, spelling); 593 } 594 595 JNIEXPORT jint JNICALL Java_jdk_internal_clang_Type_kind1 596 (JNIEnv *env, jobject type) { 597 CXType *ptr = (CXType*) J2P(env, type); 598 return ptr->kind; 599 } 600 601 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Type_size 602 (JNIEnv *env, jobject type) { 603 CXType *ptr = (CXType*) J2P(env, type); 604 return clang_Type_getSizeOf(*ptr); 605 } 606 607 JNIEXPORT jlong JNICALL Java_jdk_internal_clang_Type_getOffsetOf 608 (JNIEnv *env, jobject type, jstring field_name) { 609 CXType *ptr = (CXType*) J2P(env, type); 610 const char *name = env->GetStringUTFChars(field_name, NULL); 611 long long offset = clang_Type_getOffsetOf(*ptr, name); 612 env->ReleaseStringUTFChars(field_name, name); 613 return offset; 614 } 615 616 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_Type_getDeclarationCursor 617 (JNIEnv *env, jobject type) { 618 CXType *ptr = (CXType*) J2P(env, type); 619 CXCursor result = clang_getTypeDeclaration(*ptr); 620 jobject buffer = env->NewDirectByteBuffer(&result, sizeof(CXCursor)); 621 return env->NewObject(clsCursor, ctorCursor, buffer); 622 } 623 624 /************************************* 625 * Location related functions 626 *************************************/ 627 628 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_SourceLocation_getFileLocation 629 (JNIEnv *env, jobject loc) { 630 CXSourceLocation *ptr = (CXSourceLocation*) J2P(env, loc); 631 struct LocationFactory f; 632 return f.get(env, ptr, clang_getFileLocation); 633 } 634 635 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_SourceLocation_getExpansionLocation 636 (JNIEnv *env, jobject loc) { 637 CXSourceLocation *ptr = (CXSourceLocation*) J2P(env, loc); 638 struct LocationFactory f; 639 return f.get(env, ptr, clang_getExpansionLocation); 640 } 641 642 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_SourceLocation_getSpellingLocation 643 (JNIEnv *env, jobject loc) { 644 CXSourceLocation *ptr = (CXSourceLocation*) J2P(env, loc); 645 struct LocationFactory f; 646 return f.get(env, ptr, clang_getSpellingLocation); 647 } 648 649 JNIEXPORT bool JNICALL Java_jdk_internal_clang_SourceLocation_isInSystemHeader 650 (JNIEnv *env, jobject loc) { 651 CXSourceLocation *ptr = (CXSourceLocation*) J2P(env, loc); 652 return clang_Location_isInSystemHeader(*ptr); 653 } 654 655 JNIEXPORT bool JNICALL Java_jdk_internal_clang_SourceLocation_isFromMainFile 656 (JNIEnv *env, jobject loc) { 657 CXSourceLocation *ptr = (CXSourceLocation*) J2P(env, loc); 658 return clang_Location_isFromMainFile(*ptr); 659 } 660 661 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_SourceRange_getBegin 662 (JNIEnv *env, jobject range) { 663 CXSourceRange *ptr = (CXSourceRange*) J2P(env, range); 664 665 // Some CXCursor has no valid location, such as the one from TranslationUnit 666 CXSourceLocation loc = clang_getRangeStart(*ptr); 667 if (clang_equalLocations(loc, clang_getNullLocation())) { 668 return NULL; 669 } 670 671 jobject buffer = env->NewDirectByteBuffer(&loc, sizeof(CXSourceLocation)); 672 return env->NewObject(clsSourceLocation, ctorSourceLocation, buffer); 673 } 674 675 JNIEXPORT jobject JNICALL Java_jdk_internal_clang_SourceRange_getEnd 676 (JNIEnv *env, jobject range) { 677 CXSourceRange *ptr = (CXSourceRange*) J2P(env, range); 678 679 // Some CXCursor has no valid location, such as the one from TranslationUnit 680 CXSourceLocation loc = clang_getRangeEnd(*ptr); 681 if (clang_equalLocations(loc, clang_getNullLocation())) { 682 return NULL; 683 } 684 685 jobject buffer = env->NewDirectByteBuffer(&loc, sizeof(CXSourceLocation)); 686 return env->NewObject(clsSourceLocation, ctorSourceLocation, buffer); 687 } 688 689 #ifdef __cplusplus 690 } 691 #endif