Index: clang/include/clang-c/Index.h =================================================================== --- clang/include/clang-c/Index.h +++ clang/include/clang-c/Index.h @@ -2574,7 +2574,11 @@ */ CXCursor_OMPParallelMasterDirective = 285, - CXCursor_LastStmt = CXCursor_OMPParallelMasterDirective, + /** Transformation directive. + */ + CXCursor_TransformExecutableDirective = 286, + + CXCursor_LastStmt = CXCursor_TransformExecutableDirective, /** * Cursor that represents the translation unit itself. Index: clang/test/Index/transform.c =================================================================== --- /dev/null +++ clang/test/Index/transform.c @@ -0,0 +1,16 @@ +// RUN: c-index-test -test-load-source local -Xclang -fexperimental-transform-pragma %s | FileCheck %s + +typedef int int_t; +struct foo { long x; }; + +void test() { +#pragma clang transform unroll partial(2*2) + for (int i = 0; i < 8; i += 1) + ; +} + + +// CHECK: transform.c:7:15: TransformExecutableDirective= Extent=[7:15 - 7:44] +// CHECK: transform.c:7:40: BinaryOperator= Extent=[7:40 - 7:43] +// CHECK: transform.c:7:40: IntegerLiteral= Extent=[7:40 - 7:41] +// CHECK: transform.c:7:42: IntegerLiteral= Extent=[7:42 - 7:43] Index: clang/tools/libclang/CIndex.cpp =================================================================== --- clang/tools/libclang/CIndex.cpp +++ clang/tools/libclang/CIndex.cpp @@ -2015,6 +2015,7 @@ void VisitPseudoObjectExpr(const PseudoObjectExpr *E); void VisitOpaqueValueExpr(const OpaqueValueExpr *E); void VisitLambdaExpr(const LambdaExpr *E); + void VisitTransformExecutableDirective(const TransformExecutableDirective *D); void VisitOMPExecutableDirective(const OMPExecutableDirective *D); void VisitOMPLoopDirective(const OMPLoopDirective *D); void VisitOMPParallelDirective(const OMPParallelDirective *D); @@ -2750,6 +2751,19 @@ Visit(E->getSyntacticForm()); } +void EnqueueVisitor::VisitTransformExecutableDirective( + const TransformExecutableDirective *D) { + VisitStmt(D); + + // Visit expressions used in clauses before the loop. + // TODO: Currently, the clauses have no CXCursor representation, such that + // they cannot be visited themselves. Therefore these expressions appear to be + // children of the TransformExecutableDirective. + for (const TransformClause *C : D->clauses()) + for (const Stmt *S : C->children()) + AddStmt(S); +} + void EnqueueVisitor::VisitOMPExecutableDirective( const OMPExecutableDirective *D) { EnqueueChildren(D); @@ -5558,6 +5572,8 @@ return cxstring::createRef("attribute(warn_unused_result)"); case CXCursor_AlignedAttr: return cxstring::createRef("attribute(aligned)"); + case CXCursor_TransformExecutableDirective: + return cxstring::createRef("TransformExecutableDirective"); } llvm_unreachable("Unhandled CXCursorKind"); Index: clang/tools/libclang/CXCursor.cpp =================================================================== --- clang/tools/libclang/CXCursor.cpp +++ clang/tools/libclang/CXCursor.cpp @@ -737,7 +737,8 @@ K = CXCursor_BuiltinBitCastExpr; break; case Stmt::TransformExecutableDirectiveClass: - llvm_unreachable("not implemented"); + K = CXCursor_TransformExecutableDirective; + break; } CXCursor C = { K, 0, { Parent, S, TU } }; Index: clang/tools/libclang/CursorVisitor.h =================================================================== --- clang/tools/libclang/CursorVisitor.h +++ clang/tools/libclang/CursorVisitor.h @@ -37,7 +37,8 @@ MemberRefVisitKind, SizeOfPackExprPartsKind, LambdaExprPartsKind, - PostChildrenVisitKind + PostChildrenVisitKind, + TransformClauseVisitKind }; protected: