https://github.com/dingxiangfei2009 updated https://github.com/llvm/llvm-project/pull/143424
>From cbfed6b195083d07330694ae497f59f4007e6a1f Mon Sep 17 00:00:00 2001 From: Xiangfei Ding <dingxiangfei2...@protonmail.ch> Date: Mon, 9 Jun 2025 13:57:18 +0000 Subject: [PATCH 1/2] [clang-c] introduce queries on GCC-style inline assembly statements We strive for exposing such information using existing stable ABIs. In doing so, queries are limited to what the original source holds or the LLVM IR `asm` block would expose in connection with attributes that the queries are concerned. Signed-off-by: Xiangfei Ding <dingxiangfei2...@protonmail.ch> --- clang/include/clang-c/Index.h | 94 +++++++++++++++++++- clang/test/Index/inline-assembly.c | 48 ++++++++++ clang/tools/c-index-test/c-index-test.c | 52 +++++++++++ clang/tools/libclang/CIndex.cpp | 112 ++++++++++++++++++++++++ clang/tools/libclang/libclang.map | 10 +++ 5 files changed, 315 insertions(+), 1 deletion(-) create mode 100644 clang/test/Index/inline-assembly.c diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index e4cb4327fbaac..06732f5942843 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -36,7 +36,7 @@ #define CINDEX_VERSION_MAJOR 0 #define CINDEX_VERSION_MINOR 64 -#define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1)) +#define CINDEX_VERSION_ENCODE(major, minor) (((major) * 10000) + ((minor) * 1)) #define CINDEX_VERSION \ CINDEX_VERSION_ENCODE(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR) @@ -4495,6 +4495,98 @@ CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor); */ CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor); +/** + * @} + */ + +/** + * \defgroup CINDEX_MODULE Inline Assembly introspection + * + * The functions in this group provide access to information about GCC-style + * inline assembly statements. + * + * @{ + */ + +/** + * Given a CXCursor_GCCAsmStmt cursor, return the assembly template string. + * As per LLVM IR Assembly Template language, template placeholders for + * inputs and outputs are either of the form $N where N is a decimal number + * as an index into the input-output specification, + * or ${N:M} where N is a decimal number also as an index into the + * input-output specification and M is the template argument modifier. + * The index N in both cases points into the the total inputs and outputs, + * or more specifically, into the list of outputs followed by the inputs, + * starting from index 0 as the first available template argument. + */ + +CINDEX_LINKAGE CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor); + +/** + * Given a CXCursor_GCCAsmStmt cursor, check if the assembly block has goto + * labels. + */ + +CINDEX_LINKAGE unsigned clang_Cursor_isGCCAssemblyHasGoto(CXCursor); + +/** + * Given a CXCursor_GCCAsmStmt cursor, count the number of outputs + */ + +CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumOutputs(CXCursor); + +/** + * Given a CXCursor_GCCAsmStmt cursor, count the number of inputs + */ + +CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumInputs(CXCursor); + +/** + * Given a CXCursor_GCCAsmStmt cursor, get the constraint and expression cursor + * to the Index-th input. + */ + +CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, + unsigned Index, + CXString *Constraint, + CXCursor *Expr); + +/** + * Given a CXCursor_GCCAsmStmt cursor, get the constraint and expression cursor + * to the Index-th output. + */ + +CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, + unsigned Index, + CXString *Constraint, + CXCursor *Expr); + +/** + * Given a CXCursor_GCCAsmStmt cursor, count the clobbers in it. + */ + +CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumClobbers(CXCursor Cursor); + +/** + * Given a CXCursor_GCCAsmStmt cursor, get the Index-th clobber of it. + */ + +CINDEX_LINKAGE CXString clang_Cursor_getGCCAssemblyClobber(CXCursor Cursor, + unsigned Index); + +/** + * Given a CXCursor_GCCAsmStmt cursor, check if the inline assembly is simple. + */ + +CINDEX_LINKAGE unsigned clang_Cursor_isGCCAssemblySimple(CXCursor Cursor); + +/** + * Given a CXCursor_GCCAsmStmt cursor, check if the inline assembly is + * `volatile`. + */ + +CINDEX_LINKAGE unsigned clang_Cursor_isGCCAssemblyVolatile(CXCursor Cursor); + /** * @} */ diff --git a/clang/test/Index/inline-assembly.c b/clang/test/Index/inline-assembly.c new file mode 100644 index 0000000000000..2223dd2985f51 --- /dev/null +++ b/clang/test/Index/inline-assembly.c @@ -0,0 +1,48 @@ +static void inline_assembly_template_regardless_of_target_machine() { + int tmp; + asm volatile ( + "nop\n" + "a_value %w[v]\n" + "o_value %w[o]" + : [v] "=&r" (tmp) + : [o] "r" (tmp) + : "cc", "memory" + ); +} + +// RUN: c-index-test -test-inline-assembly %s 2>&1 | FileCheck %s +// CHECK: ===ASM TEMPLATE=== +// CHECK: nop +// CHECK: a_value ${0:w} +// CHECK: o_value ${1:w} +// CHECK: ===ASM TEMPLATE END=== +// CHECK: volatile: true +// CHECK: simple: false +// CHECK: Output #0 Constraint (=&r): DeclRefExpr=tmp:2:9 +// CHECK: Input #0 Constraint (r): UnexposedExpr=tmp:2:9 +// CHECK: Clobber #0: cc +// CHECK: Clobber #1: memory +// CHECK: ===ASM END=== + +static void inline_assembly_valid_x86_example() { + int tmp; + asm ( + "nop\n" + "mov %w[o], %w[v]" + : [v] "=&r" (tmp) + : [o] "r" (tmp) + : "cc", "memory" + ); +} + +// CHECK: ===ASM TEMPLATE=== +// CHECK: nop +// CHECK: mov ${1:w}, ${0:w} +// CHECK: ===ASM TEMPLATE END=== +// CHECK: volatile: false +// CHECK: simple: false +// CHECK: Output #0 Constraint (=&r): DeclRefExpr=tmp:28:9 +// CHECK: Input #0 Constraint (r): UnexposedExpr=tmp:28:9 +// CHECK: Clobber #0: cc +// CHECK: Clobber #1: memory +// CHECK: ===ASM END=== diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 4a887cd0c1e2e..0917439898f98 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -1988,6 +1988,53 @@ static enum CXChildVisitResult PrintDeclAttributes(CXCursor cursor, CXCursor p, return CXChildVisit_Continue; } +/******************************************************************************/ +/* Inline assembly cursor testing */ +/******************************************************************************/ + +static enum CXChildVisitResult +PrintGCCInlineAssembly(CXCursor cursor, CXCursor p, CXClientData d) { + CXString Constraint, Template, Clobber; + CXCursor Expr; + unsigned hasGoto, i, e; + if (clang_getCursorKind(cursor) != CXCursor_AsmStmt) { + return CXChildVisit_Recurse; + } + hasGoto = clang_Cursor_isGCCAssemblyHasGoto(cursor); + printf("===ASM TEMPLATE%s===\n", hasGoto ? " (WITH GOTO)" : ""); + Template = clang_Cursor_getGCCAssemblyTemplate(cursor); + printf("%s", clang_getCString(Template)); + clang_disposeString(Template); + printf("\n===ASM TEMPLATE END===\n"); + + printf("volatile: %s\n", + clang_Cursor_isGCCAssemblyVolatile(cursor) ? "true" : "false"); + printf("simple: %s\n", + clang_Cursor_isGCCAssemblySimple(cursor) ? "true" : "false"); + + for (i = 0, e = clang_Cursor_getGCCAssemblyNumOutputs(cursor); i < e; ++i) { + clang_Cursor_getGCCAssemblyOutput(cursor, i, &Constraint, &Expr); + printf("Output #%d Constraint (%s): ", i, clang_getCString(Constraint)); + PrintCursor(Expr, NULL); + printf("\n"); + clang_disposeString(Constraint); + } + for (i = 0, e = clang_Cursor_getGCCAssemblyNumInputs(cursor); i < e; ++i) { + clang_Cursor_getGCCAssemblyInput(cursor, i, &Constraint, &Expr); + printf("Input #%d Constraint (%s): ", i, clang_getCString(Constraint)); + PrintCursor(Expr, NULL); + printf("\n"); + clang_disposeString(Constraint); + } + for (i = 0, e = clang_Cursor_getGCCAssemblyNumClobbers(cursor); i < e; ++i) { + Clobber = clang_Cursor_getGCCAssemblyClobber(cursor, i); + printf("Clobber #%d: %s\n", i, clang_getCString(Clobber)); + clang_disposeString(Constraint); + } + printf("===ASM END===\n"); + return CXChildVisit_Recurse; +} + /******************************************************************************/ /* Target information testing. */ /******************************************************************************/ @@ -5010,6 +5057,7 @@ static void print_usage(void) { " c-index-test -test-annotate-tokens=<range> {<args>}*\n" " c-index-test -test-inclusion-stack-source {<args>}*\n" " c-index-test -test-inclusion-stack-tu <AST file>\n"); + fprintf(stderr, " c-index-test -test-inline-assembly <AST file>\n"); fprintf(stderr, " c-index-test -test-print-linkage-source {<args>}*\n" " c-index-test -test-print-visibility {<args>}*\n" @@ -5167,6 +5215,10 @@ int cindextest_main(int argc, const char **argv) { else if (argc > 2 && strstr(argv[1], "-single-symbol-sgf-for=") == argv[1]) return perform_test_single_symbol_sgf(argv[1], argc - 2, argv + 2); + if (argc > 2 && strstr(argv[1], "-test-inline-assembly") == argv[1]) + return perform_test_load_source(argc - 2, argv + 2, "all", + PrintGCCInlineAssembly, NULL); + print_usage(); return 1; } diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 3068621d9c004..909e57f4e84f1 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -8648,6 +8648,118 @@ void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens, } } +//===----------------------------------------------------------------------===// +// Operations for querying information of a GCC inline assembly block under a +// cursor. +//===----------------------------------------------------------------------===// +CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return cxstring::createEmpty(); + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + auto const &C = getCursorContext(Cursor); + auto AsmTemplate = Stmt->generateAsmString(C); + return cxstring::createDup(AsmTemplate); + } + return cxstring::createEmpty(); +} + +unsigned clang_Cursor_isGCCAssemblyHasGoto(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + return Stmt->isAsmGoto(); + } + return 0; +} + +unsigned clang_Cursor_getGCCAssemblyNumOutputs(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + return Stmt->getNumOutputs(); + } + return 0; +} + +unsigned clang_Cursor_getGCCAssemblyNumInputs(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + return Stmt->getNumInputs(); + } + return 0; +} + +unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, unsigned Index, + CXString *Constraint, + CXCursor *Expr) { + if (!clang_isStatement(Cursor.kind) || !Constraint || !Expr) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); + Stmt && Index < Stmt->getNumInputs()) { + auto Constraint_ = Stmt->getInputConstraint(Index); + auto const *Expr_ = Stmt->getInputExpr(Index); + *Constraint = cxstring::createDup(Constraint_); + *Expr = MakeCXCursor(Expr_, getCursorDecl(Cursor), + cxcursor::getCursorTU(Cursor)); + return 1; + } + return 0; +} + +unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, unsigned Index, + CXString *Constraint, + CXCursor *Expr) { + if (!clang_isStatement(Cursor.kind) || !Constraint || !Expr) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); + Stmt && Index < Stmt->getNumOutputs()) { + auto Constraint_ = Stmt->getOutputConstraint(Index); + auto const *Expr_ = Stmt->getOutputExpr(Index); + *Constraint = cxstring::createDup(Constraint_); + *Expr = MakeCXCursor(Expr_, getCursorDecl(Cursor), + cxcursor::getCursorTU(Cursor)); + return 1; + } + return 0; +} + +unsigned clang_Cursor_getGCCAssemblyNumClobbers(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + return Stmt->getNumClobbers(); + } + return 0; +} + +CXString clang_Cursor_getGCCAssemblyClobber(CXCursor Cursor, unsigned Index) { + if (!clang_isStatement(Cursor.kind)) + return cxstring::createEmpty(); + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); + S && Index < S->getNumClobbers()) + return cxstring::createDup(S->getClobber(Index)); + return cxstring::createEmpty(); +} + +unsigned clang_Cursor_isGCCAssemblySimple(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + return Stmt->isSimple(); + } + return 0; +} + +unsigned clang_Cursor_isGCCAssemblyVolatile(CXCursor Cursor) { + if (!clang_isStatement(Cursor.kind)) + return 0; + if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + return Stmt->isVolatile(); + } + return 0; +} + //===----------------------------------------------------------------------===// // Operations for querying linkage of a cursor. //===----------------------------------------------------------------------===// diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map index f08d13c3da9e1..b3a12e9e9834b 100644 --- a/clang/tools/libclang/libclang.map +++ b/clang/tools/libclang/libclang.map @@ -441,6 +441,16 @@ LLVM_20 { LLVM_21 { global: clang_getFullyQualifiedName; + clang_Cursor_getGCCAssemblyTemplate; + clang_Cursor_isGCCAssemblyHasGoto; + clang_Cursor_getGCCAssemblyNumOutputs; + clang_Cursor_getGCCAssemblyNumInputs; + clang_Cursor_getGCCAssemblyInput; + clang_Cursor_getGCCAssemblyOutput; + clang_Cursor_getGCCAssemblyNumClobbers; + clang_Cursor_getGCCAssemblyClobber; + clang_Cursor_isGCCAssemblySimple; + clang_Cursor_isGCCAssemblyVolatile; }; # Example of how to add a new symbol version entry. If you do add a new symbol >From c08988ae88e6126b8d78a4e364480df04ab9ad73 Mon Sep 17 00:00:00 2001 From: Xiangfei Ding <dingxiangfei2...@protonmail.ch> Date: Fri, 20 Jun 2025 08:38:23 +0000 Subject: [PATCH 2/2] apply suggestions --- clang/docs/ReleaseNotes.rst | 3 ++ clang/include/clang-c/Index.h | 35 +++++++++--- clang/test/Index/inline-assembly.c | 6 +-- clang/tools/c-index-test/c-index-test.c | 6 +-- clang/tools/libclang/CIndex.cpp | 72 ++++++++++--------------- clang/tools/libclang/libclang.map | 1 - 6 files changed, 61 insertions(+), 62 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 96477ef6ddc9a..239ecd02a14f1 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -327,6 +327,9 @@ Non-comprehensive list of changes in this release ``__reference_constructs_from_temporary`` should be used instead. (#GH44056) - Added `__builtin_get_vtable_pointer` to directly load the primary vtable pointer from a polymorphic object. +- `libclang` receives a family of new bindings to query basic facts about + GCC-style inline assembly blocks, including whether the block is `volatile` + and its template string following the LLVM IR `asm` format. (#GH143424) - Clang no longer rejects reinterpret_cast conversions between indirect ARC-managed pointers and other pointer types. The prior behavior was overly strict and inconsistent with the ARC specification. diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 06732f5942843..b04d2b6767e00 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -4518,6 +4518,9 @@ CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor); * The index N in both cases points into the the total inputs and outputs, * or more specifically, into the list of outputs followed by the inputs, * starting from index 0 as the first available template argument. + * + * This function also returns a valid empty string if the cursor does not point + * at a GCC inline assembly block. */ CINDEX_LINKAGE CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor); @@ -4525,18 +4528,24 @@ CINDEX_LINKAGE CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor); /** * Given a CXCursor_GCCAsmStmt cursor, check if the assembly block has goto * labels. + * This function also returns FALSE if the cursor does not point at a GCC inline + * assembly block. */ CINDEX_LINKAGE unsigned clang_Cursor_isGCCAssemblyHasGoto(CXCursor); /** - * Given a CXCursor_GCCAsmStmt cursor, count the number of outputs + * Given a CXCursor_GCCAsmStmt cursor, count the number of outputs. + * This function also returns 0 if the cursor does not point at a GCC inline + * assembly block. */ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumOutputs(CXCursor); /** - * Given a CXCursor_GCCAsmStmt cursor, count the number of inputs + * Given a CXCursor_GCCAsmStmt cursor, count the number of inputs. + * This function also returns 0 if the cursor does not point at a GCC inline + * assembly block. */ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumInputs(CXCursor); @@ -4544,6 +4553,11 @@ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumInputs(CXCursor); /** * Given a CXCursor_GCCAsmStmt cursor, get the constraint and expression cursor * to the Index-th input. + * This function returns TRUE when the cursor points at a GCC inline assembly + * statement, `Index` is within bounds and both the `Constraint` and `Expr` are + * not NULL. + * Otherwise, this function returns FALSE but leaves `Constraint` and `Expr` + * intact. */ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, @@ -4554,6 +4568,11 @@ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, /** * Given a CXCursor_GCCAsmStmt cursor, get the constraint and expression cursor * to the Index-th output. + * This function returns TRUE when the cursor points at a GCC inline assembly + * statement, `Index` is within bounds and both the `Constraint` and `Expr` are + * not NULL. + * Otherwise, this function returns FALSE but leaves `Constraint` and `Expr` + * intact. */ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, @@ -4563,26 +4582,26 @@ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, /** * Given a CXCursor_GCCAsmStmt cursor, count the clobbers in it. + * This function also returns 0 if the cursor does not point at a GCC inline + * assembly block. */ CINDEX_LINKAGE unsigned clang_Cursor_getGCCAssemblyNumClobbers(CXCursor Cursor); /** * Given a CXCursor_GCCAsmStmt cursor, get the Index-th clobber of it. + * This function returns a valid empty string if the cursor does not point + * at a GCC inline assembly block or `Index` is out of bounds. */ CINDEX_LINKAGE CXString clang_Cursor_getGCCAssemblyClobber(CXCursor Cursor, unsigned Index); -/** - * Given a CXCursor_GCCAsmStmt cursor, check if the inline assembly is simple. - */ - -CINDEX_LINKAGE unsigned clang_Cursor_isGCCAssemblySimple(CXCursor Cursor); - /** * Given a CXCursor_GCCAsmStmt cursor, check if the inline assembly is * `volatile`. + * This function returns FALSE if the cursor does not point at a GCC inline + * assembly block. */ CINDEX_LINKAGE unsigned clang_Cursor_isGCCAssemblyVolatile(CXCursor Cursor); diff --git a/clang/test/Index/inline-assembly.c b/clang/test/Index/inline-assembly.c index 2223dd2985f51..64a7ce03852c9 100644 --- a/clang/test/Index/inline-assembly.c +++ b/clang/test/Index/inline-assembly.c @@ -17,7 +17,6 @@ static void inline_assembly_template_regardless_of_target_machine() { // CHECK: o_value ${1:w} // CHECK: ===ASM TEMPLATE END=== // CHECK: volatile: true -// CHECK: simple: false // CHECK: Output #0 Constraint (=&r): DeclRefExpr=tmp:2:9 // CHECK: Input #0 Constraint (r): UnexposedExpr=tmp:2:9 // CHECK: Clobber #0: cc @@ -40,9 +39,8 @@ static void inline_assembly_valid_x86_example() { // CHECK: mov ${1:w}, ${0:w} // CHECK: ===ASM TEMPLATE END=== // CHECK: volatile: false -// CHECK: simple: false -// CHECK: Output #0 Constraint (=&r): DeclRefExpr=tmp:28:9 -// CHECK: Input #0 Constraint (r): UnexposedExpr=tmp:28:9 +// CHECK: Output #0 Constraint (=&r): DeclRefExpr=tmp:27:9 +// CHECK: Input #0 Constraint (r): UnexposedExpr=tmp:27:9 // CHECK: Clobber #0: cc // CHECK: Clobber #1: memory // CHECK: ===ASM END=== diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c index 0917439898f98..07566ff77158f 100644 --- a/clang/tools/c-index-test/c-index-test.c +++ b/clang/tools/c-index-test/c-index-test.c @@ -1997,9 +1997,9 @@ PrintGCCInlineAssembly(CXCursor cursor, CXCursor p, CXClientData d) { CXString Constraint, Template, Clobber; CXCursor Expr; unsigned hasGoto, i, e; - if (clang_getCursorKind(cursor) != CXCursor_AsmStmt) { + if (clang_getCursorKind(cursor) != CXCursor_AsmStmt) return CXChildVisit_Recurse; - } + hasGoto = clang_Cursor_isGCCAssemblyHasGoto(cursor); printf("===ASM TEMPLATE%s===\n", hasGoto ? " (WITH GOTO)" : ""); Template = clang_Cursor_getGCCAssemblyTemplate(cursor); @@ -2009,8 +2009,6 @@ PrintGCCInlineAssembly(CXCursor cursor, CXCursor p, CXClientData d) { printf("volatile: %s\n", clang_Cursor_isGCCAssemblyVolatile(cursor) ? "true" : "false"); - printf("simple: %s\n", - clang_Cursor_isGCCAssemblySimple(cursor) ? "true" : "false"); for (i = 0, e = clang_Cursor_getGCCAssemblyNumOutputs(cursor); i < e; ++i) { clang_Cursor_getGCCAssemblyOutput(cursor, i, &Constraint, &Expr); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 909e57f4e84f1..e239ffae547aa 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -8655,9 +8655,9 @@ void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens, CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor Cursor) { if (!clang_isStatement(Cursor.kind)) return cxstring::createEmpty(); - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - auto const &C = getCursorContext(Cursor); - auto AsmTemplate = Stmt->generateAsmString(C); + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { + ASTContext const &C = getCursorContext(Cursor); + std::string AsmTemplate = S->generateAsmString(C); return cxstring::createDup(AsmTemplate); } return cxstring::createEmpty(); @@ -8666,42 +8666,37 @@ CXString clang_Cursor_getGCCAssemblyTemplate(CXCursor Cursor) { unsigned clang_Cursor_isGCCAssemblyHasGoto(CXCursor Cursor) { if (!clang_isStatement(Cursor.kind)) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - return Stmt->isAsmGoto(); - } + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) + return S->isAsmGoto(); return 0; } unsigned clang_Cursor_getGCCAssemblyNumOutputs(CXCursor Cursor) { if (!clang_isStatement(Cursor.kind)) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - return Stmt->getNumOutputs(); - } + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) + return S->getNumOutputs(); return 0; } unsigned clang_Cursor_getGCCAssemblyNumInputs(CXCursor Cursor) { if (!clang_isStatement(Cursor.kind)) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - return Stmt->getNumInputs(); - } + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) + return S->getNumInputs(); return 0; } unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, unsigned Index, CXString *Constraint, - CXCursor *Expr) { - if (!clang_isStatement(Cursor.kind) || !Constraint || !Expr) + CXCursor *ExprCursor) { + if (!clang_isStatement(Cursor.kind) || !Constraint || !ExprCursor) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); - Stmt && Index < Stmt->getNumInputs()) { - auto Constraint_ = Stmt->getInputConstraint(Index); - auto const *Expr_ = Stmt->getInputExpr(Index); - *Constraint = cxstring::createDup(Constraint_); - *Expr = MakeCXCursor(Expr_, getCursorDecl(Cursor), - cxcursor::getCursorTU(Cursor)); + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); + S && Index < S->getNumInputs()) { + *Constraint = cxstring::createDup(S->getInputConstraint(Index)); + *ExprCursor = MakeCXCursor(S->getInputExpr(Index), getCursorDecl(Cursor), + cxcursor::getCursorTU(Cursor)); return 1; } return 0; @@ -8709,16 +8704,14 @@ unsigned clang_Cursor_getGCCAssemblyInput(CXCursor Cursor, unsigned Index, unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, unsigned Index, CXString *Constraint, - CXCursor *Expr) { - if (!clang_isStatement(Cursor.kind) || !Constraint || !Expr) + CXCursor *ExprCursor) { + if (!clang_isStatement(Cursor.kind) || !Constraint || !ExprCursor) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); - Stmt && Index < Stmt->getNumOutputs()) { - auto Constraint_ = Stmt->getOutputConstraint(Index); - auto const *Expr_ = Stmt->getOutputExpr(Index); - *Constraint = cxstring::createDup(Constraint_); - *Expr = MakeCXCursor(Expr_, getCursorDecl(Cursor), - cxcursor::getCursorTU(Cursor)); + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor)); + S && Index < S->getNumOutputs()) { + *Constraint = cxstring::createDup(S->getOutputConstraint(Index)); + *ExprCursor = MakeCXCursor(S->getOutputExpr(Index), getCursorDecl(Cursor), + cxcursor::getCursorTU(Cursor)); return 1; } return 0; @@ -8727,9 +8720,8 @@ unsigned clang_Cursor_getGCCAssemblyOutput(CXCursor Cursor, unsigned Index, unsigned clang_Cursor_getGCCAssemblyNumClobbers(CXCursor Cursor) { if (!clang_isStatement(Cursor.kind)) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - return Stmt->getNumClobbers(); - } + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) + return S->getNumClobbers(); return 0; } @@ -8742,21 +8734,11 @@ CXString clang_Cursor_getGCCAssemblyClobber(CXCursor Cursor, unsigned Index) { return cxstring::createEmpty(); } -unsigned clang_Cursor_isGCCAssemblySimple(CXCursor Cursor) { - if (!clang_isStatement(Cursor.kind)) - return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - return Stmt->isSimple(); - } - return 0; -} - unsigned clang_Cursor_isGCCAssemblyVolatile(CXCursor Cursor) { if (!clang_isStatement(Cursor.kind)) return 0; - if (auto const *Stmt = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) { - return Stmt->isVolatile(); - } + if (auto const *S = dyn_cast_or_null<GCCAsmStmt>(getCursorStmt(Cursor))) + return S->isVolatile(); return 0; } diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map index b3a12e9e9834b..d140a71e771a0 100644 --- a/clang/tools/libclang/libclang.map +++ b/clang/tools/libclang/libclang.map @@ -449,7 +449,6 @@ LLVM_21 { clang_Cursor_getGCCAssemblyOutput; clang_Cursor_getGCCAssemblyNumClobbers; clang_Cursor_getGCCAssemblyClobber; - clang_Cursor_isGCCAssemblySimple; clang_Cursor_isGCCAssemblyVolatile; }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits