A compiler frontend for the C programming language
BSD-3-CLAUSE License
C language (draft) proposal Enabling Generic Functions and Parametric Types in C; prototype available here.
Psyche-C is a compiler frontend for the C language. It is designed as a library, with a focus on the implementation of static analysis tools of C programs, without requiring understanding of their build setup. Bellow are the main characteristics of Psyche-C:
struct
, union
, enum
, and typedef
(due to #include
failures).Psyche-C's native API is in C++, but APIs for other languages are planned.
void analyse(const SourceText& srcText, const FileInfo& fi)
{
ParseOptions parseOpts;
parseOpts.setAmbiguityMode(AmbiguityMode::DisambiguateAlgorithmically);
auto tree = SyntaxTree::parseText(srcText,
TextPreprocessingState::Preprocessed,
TextCompleteness::Fragment,
parseOpts,
fi.fileName());
auto compilation = Compilation::create("code-analysis");
compilation->addSyntaxTree(tree.get());
AnalysisVisitor analysis(tree.get(), compilation->semanticModel(tree.get()));
analysis.run(tree->translationUnitRoot());
}
SyntaxVisitor::Action AnalysisVisitor::visitFunctionDefinition(const FunctionDefinitionSyntax* node) override
{
const sym = semaModel->declaredSymbol(node);
if (sym->kind() == SymbolKind::Function) {
const FunctionSymbol* funSym = sym->asFunction();
// ...
}
return Action::Skip;
}
Psyche-C comes with the cnippet driver and it can be used as an ordinary parser for C snippets. For instance, if you compile the snippet below with cnippet, you'll see a diagnostic similar to the one you'd see with GCC or Clang.
void f()
{
int ;
}
~ cnip test.c
test.c:4:4 error: declaration does not declare anything
int ;
^
Psyche-C can optionally (so far only available in the original branch) infer the missing types of a C snippet.
For instance, for the snippet below, Psyche-C can infer a (compilable) declaration for T
an synthesize it during compilation.
void f()
{
T v = 0;
v->value = 42;
v->next = v;
}
typedef struct TYPE_2__ TYPE_1__;
struct TYPE_2__
{
int value;
struct TYPE_2__* next;
} ;
typedef TYPE_1__* T;
You might want to use this functionality to:
Except for type inference, which is written in Haskell, Psyche-C is written in C++17; cnippet is written in Python 3.
To build:
cmake CMakeLists.txt && make -j 4
To run the tests:
./test-suite
Of Psyche-C itself:
Type Inference for C: Applications to the Static Analysis of Incomplete Programs ACM Transactions on Programming Languages and Systems — TOPLAS, Volume 42, Issue 3, Article No. 15, Dec. 2020.
Inference of static semantics for incomplete C programs Proceedings of the ACM on Programming Languages, Volume 2, Issue POPL, Jan. 2018, Article No. 29.
That use Psyche-C:
SLaDe: A Portable Small Language Model Decompiler for Optimized Assembly Proceedings of the IEEE/ACM International Symposium on Code Generation and Optimization - CGO, 2024.
AnghaBench: a Suite with One Million Compilable C Benchmarks for Code-Size Reduction Proceedings of the IEEE/ACM International Symposium on Code Generation and Optimization — CGO, 2021.
Generation of in-bounds inputs for arrays in memory-unsafe languages Proceedings of the IEEE/ACM International Symposium on Code Generation and Optimization — CGO, Feb. 2019, p. 136-148.
Automatic annotation of tasks in structured code Proceedings of the International Conference on Parallel Architectures and Compilation Techniques — PACT, Nov. 2018, Article No. 31.