Skip to content

Commit

Permalink
Testbed and skeleton of a new expression parser
Browse files Browse the repository at this point in the history
LLVM's JIT is now the foundation of dynamic-compilation features for many languages. Clang also has low-level support for dynamic compilation (ASTImporter and ExternalASTSource, notably). How the compiler is set up for dynamic parsing is generally left up to individual clients, for example LLDB's C/C++/Objective-C expression parser and the ROOT project.

Although this arrangement offers external clients the flexibility to implement dynamic features as they see fit, the lack of an in-tree client means that subtle bugs can be introduced that cause regressions in the external clients but aren't caught by tests (or users) until much later. LLDB for example regularly encounters complicated ODR violation scenarios where it is not immediately clear who is at fault.

Other external clients (notably, Cling) rely on similar functionality, and another goal is to break this functionality up into composable parts so that any client can be built easily on top of Clang without requiring extensive additional code.

I propose that the parts required to build a simple expression parser be added to Clang.  Initially, I aim to have the following features:

- A piece that looks up external declarations from a variety of sources (e.g., from previous dynamic compilations, from modules, or from DWARF) and uses clear conflict resolution rules to reconcile differences, with easily understood errors. This functionality will be supported by in-tree tests.

- A piece that works hand in hand with the LLVM JIT to resolve the locations of external declarations so that e.g. variables can be redeclared and (for high-performance applications like DTrace) external variables can be accessed directly from the registers where they reside.

This commit adds a tester that parses a sequence of source files and then uses them as source data for an expression. External references are resolved using an ExternalASTSource that responds to name queries using an ASTImporter. This is the setup that LLDB uses, and the motivating reason for MinimalImport in ASTImporter.  When complete, this tester will implement the first of the above goals.

Differential Revision: https://reviews.llvm.org/D27180

llvm-svn: 290004
  • Loading branch information
scallanan committed Dec 16, 2016
1 parent 3b8011f commit fe929aa
Show file tree
Hide file tree
Showing 13 changed files with 381 additions and 0 deletions.
1 change: 1 addition & 0 deletions clang/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ list(APPEND CLANG_TEST_DEPS
c-index-test diagtool
clang-tblgen
clang-offload-bundler
clang-import-test
)

if(CLANG_ENABLE_STATIC_ANALYZER)
Expand Down
2 changes: 2 additions & 0 deletions clang/test/Import/clang-flags/Inputs/S.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
STRUCT S {
};
5 changes: 5 additions & 0 deletions clang/test/Import/clang-flags/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: clang-import-test -import %S/Inputs/S.c -expression %s -Xcc -DSTRUCT=struct
void expr() {
STRUCT S MyS;
void *MyPtr = &MyS;
}
2 changes: 2 additions & 0 deletions clang/test/Import/empty-struct/Inputs/S.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
struct S {
};
5 changes: 5 additions & 0 deletions clang/test/Import/empty-struct/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: clang-import-test -import %S/Inputs/S.c -expression %s
void expr() {
struct S MyS;
void *MyPtr = &MyS;
}
2 changes: 2 additions & 0 deletions clang/test/Import/error-in-expression/Inputs/S.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
struct S {
};
6 changes: 6 additions & 0 deletions clang/test/Import/error-in-expression/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: not clang-import-test -import %S/Inputs/S.c -expression %s 2>&1 | FileCheck %s
// CHECK: {{.*}}no viable conversion{{.*}}
void expr() {
struct S MyS;
void *MyPtr = MyS;
}
2 changes: 2 additions & 0 deletions clang/test/Import/error-in-import/Inputs/S.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
struct S [
];
6 changes: 6 additions & 0 deletions clang/test/Import/error-in-import/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: not clang-import-test -import %S/Inputs/S.c -expression %s 2>&1 | FileCheck %s
// CHECK: {{.*}}expected unqualified-id{{.*}}
void expr() {
struct S MyS;
void *MyPtr = &MyS;
}
6 changes: 6 additions & 0 deletions clang/test/Import/missing-import/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// RUN: not clang-import-test -import %S/Inputs/S.c -expression %s 2>&1 | FileCheck %s
// CHECK: {{.*}}Couldn't open{{.*}}Inputs/S.c{{.*}}
void expr() {
struct S MyS;
void *MyPtr = &MyS;
}
1 change: 1 addition & 0 deletions clang/tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ add_clang_subdirectory(driver)
add_clang_subdirectory(clang-format)
add_clang_subdirectory(clang-format-vs)
add_clang_subdirectory(clang-fuzzer)
add_clang_subdirectory(clang-import-test)
add_clang_subdirectory(clang-offload-bundler)

add_clang_subdirectory(c-index-test)
Expand Down
24 changes: 24 additions & 0 deletions clang/tools/clang-import-test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
set(LLVM_LINK_COMPONENTS
support
)

if(NOT CLANG_BUILT_STANDALONE)
set(tablegen_deps intrinsics_gen)
endif()

add_clang_tool(clang-import-test
clang-import-test.cpp
DEPENDS
${tablegen_deps}
)

set(CLANG_IMPORT_TEST_LIB_DEPS
clangAST
clangBasic
clangCodeGen
clangFrontend
)

target_link_libraries(clang-import-test
${CLANG_IMPORT_TEST_LIB_DEPS}
)
Loading

0 comments on commit fe929aa

Please sign in to comment.