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
22static void emit(const char *Name, const char *Spelling) {
23 static char Hex[] = "0123456789abcdef";
24 // Skip EmptySpellingName for IsDeducible.
25 if (!Name[0]) return;
26
27 printf(format: "%s=\"", Name);
28 unsigned char C;
29 while ((C = *Spelling++)) {
30 if (C < 32 || C == '"' || C == '\\')
31 printf(format: "\\x%c%c", Hex[C>>4], Hex[C%16]);
32 else
33 printf(format: "%c", C);
34 }
35 printf(format: "\"\n");
36}
37
38int main(int argc, char **argv) {
39#define PUNCTUATOR(Name, Spelling) emit(#Name, Spelling);
40#define KEYWORD(Name, Criteria) emit(#Name, #Name);
41#define PPKEYWORD(Name) emit(#Name, #Name);
42#define CXX_KEYWORD_OPERATOR(Name, Equivalent) emit(#Name, #Name);
43#define OBJC_AT_KEYWORD(Name) emit(#Name, #Name);
44#define ALIAS(Spelling, Equivalent, Criteria) emit(Spelling, Spelling);
45#include "clang/Basic/TokenKinds.def"
46 // Some other sub-token chunks significant to the lexer.
47 emit(Name: "ucn16", Spelling: "\\u0000");
48 emit(Name: "ucn32", Spelling: "\\U00000000");
49 emit(Name: "rawstart", Spelling: "R\"(");
50 emit(Name: "rawend", Spelling: ")\"");
51 emit(Name: "quote", Spelling: "\"");
52 emit(Name: "squote", Spelling: "'");
53 emit(Name: "u8quote", Spelling: "u8\"");
54 emit(Name: "u16quote", Spelling: "u\"");
55 emit(Name: "u32quote", Spelling: "U\"");
56 emit(Name: "esc_nl", Spelling: "\\\n");
57 emit(Name: "hex", Spelling: "0x");
58}
59
60