1 | //===-- dictionary.c - Generate fuzzing dictionary for clang --------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This binary emits a fuzzing dictionary describing strings that are |
10 | // significant to the clang parser: keywords and other tokens. |
11 | // |
12 | // The dictionary can be used by a fuzzer to reach interesting parser states |
13 | // much more quickly. |
14 | // |
15 | // The output is a single-file dictionary supported by libFuzzer and AFL: |
16 | // https://llvm.org/docs/LibFuzzer.html#dictionaries |
17 | // |
18 | //===----------------------------------------------------------------------===// |
19 | |
20 | #include <stdio.h> |
21 | |
22 | static void emit(const char *Name, const char *Spelling) { |
23 | static char Hex[] = "0123456789abcdef" ; |
24 | |
25 | printf(format: "%s=\"" , Name); |
26 | unsigned char C; |
27 | while ((C = *Spelling++)) { |
28 | if (C < 32 || C == '"' || C == '\\') |
29 | printf(format: "\\x%c%c" , Hex[C>>4], Hex[C%16]); |
30 | else |
31 | printf(format: "%c" , C); |
32 | } |
33 | printf(format: "\"\n" ); |
34 | } |
35 | |
36 | int main(int argc, char **argv) { |
37 | #define PUNCTUATOR(Name, Spelling) emit(#Name, Spelling); |
38 | #define KEYWORD(Name, Criteria) emit(#Name, #Name); |
39 | #define PPKEYWORD(Name) emit(#Name, #Name); |
40 | #define CXX_KEYWORD_OPERATOR(Name, Equivalent) emit(#Name, #Name); |
41 | #define OBJC_AT_KEYWORD(Name) emit(#Name, #Name); |
42 | #define ALIAS(Spelling, Equivalent, Criteria) emit(Spelling, Spelling); |
43 | #include "clang/Basic/TokenKinds.def" |
44 | // Some other sub-token chunks significant to the lexer. |
45 | emit(Name: "ucn16" , Spelling: "\\u0000" ); |
46 | emit(Name: "ucn32" , Spelling: "\\U00000000" ); |
47 | emit(Name: "rawstart" , Spelling: "R\"(" ); |
48 | emit(Name: "rawend" , Spelling: ")\"" ); |
49 | emit(Name: "quote" , Spelling: "\"" ); |
50 | emit(Name: "squote" , Spelling: "'" ); |
51 | emit(Name: "u8quote" , Spelling: "u8\"" ); |
52 | emit(Name: "u16quote" , Spelling: "u\"" ); |
53 | emit(Name: "u32quote" , Spelling: "U\"" ); |
54 | emit(Name: "esc_nl" , Spelling: "\\\n" ); |
55 | emit(Name: "hex" , Spelling: "0x" ); |
56 | } |
57 | |
58 | |