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