xref: /openbsd-src/gnu/llvm/clang/lib/Format/FormatToken.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- FormatToken.h - Format C++ code ------------------------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick ///
9e5dd7070Spatrick /// \file
10e5dd7070Spatrick /// This file contains the declaration of the FormatToken, a wrapper
11e5dd7070Spatrick /// around Token with additional information related to formatting.
12e5dd7070Spatrick ///
13e5dd7070Spatrick //===----------------------------------------------------------------------===//
14e5dd7070Spatrick 
15e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_FORMAT_FORMATTOKEN_H
16e5dd7070Spatrick #define LLVM_CLANG_LIB_FORMAT_FORMATTOKEN_H
17e5dd7070Spatrick 
18e5dd7070Spatrick #include "clang/Basic/IdentifierTable.h"
19e5dd7070Spatrick #include "clang/Basic/OperatorPrecedence.h"
20e5dd7070Spatrick #include "clang/Format/Format.h"
21e5dd7070Spatrick #include "clang/Lex/Lexer.h"
22e5dd7070Spatrick #include <memory>
23*12c85518Srobert #include <optional>
24e5dd7070Spatrick #include <unordered_set>
25e5dd7070Spatrick 
26e5dd7070Spatrick namespace clang {
27e5dd7070Spatrick namespace format {
28e5dd7070Spatrick 
29e5dd7070Spatrick #define LIST_TOKEN_TYPES                                                       \
30e5dd7070Spatrick   TYPE(ArrayInitializerLSquare)                                                \
31e5dd7070Spatrick   TYPE(ArraySubscriptLSquare)                                                  \
32e5dd7070Spatrick   TYPE(AttributeColon)                                                         \
33a9ac8606Spatrick   TYPE(AttributeMacro)                                                         \
34e5dd7070Spatrick   TYPE(AttributeParen)                                                         \
35e5dd7070Spatrick   TYPE(AttributeSquare)                                                        \
36e5dd7070Spatrick   TYPE(BinaryOperator)                                                         \
37e5dd7070Spatrick   TYPE(BitFieldColon)                                                          \
38e5dd7070Spatrick   TYPE(BlockComment)                                                           \
39*12c85518Srobert   TYPE(BracedListLBrace)                                                       \
40e5dd7070Spatrick   TYPE(CastRParen)                                                             \
41*12c85518Srobert   TYPE(ClassLBrace)                                                            \
42*12c85518Srobert   TYPE(CompoundRequirementLBrace)                                              \
43*12c85518Srobert   /* ternary ?: expression */                                                  \
44e5dd7070Spatrick   TYPE(ConditionalExpr)                                                        \
45*12c85518Srobert   /* the condition in an if statement */                                       \
46*12c85518Srobert   TYPE(ConditionLParen)                                                        \
47e5dd7070Spatrick   TYPE(ConflictAlternative)                                                    \
48e5dd7070Spatrick   TYPE(ConflictEnd)                                                            \
49e5dd7070Spatrick   TYPE(ConflictStart)                                                          \
50*12c85518Srobert   /* l_brace of if/for/while */                                                \
51*12c85518Srobert   TYPE(ControlStatementLBrace)                                                 \
52*12c85518Srobert   TYPE(CppCastLParen)                                                          \
53*12c85518Srobert   TYPE(CSharpGenericTypeConstraint)                                            \
54*12c85518Srobert   TYPE(CSharpGenericTypeConstraintColon)                                       \
55*12c85518Srobert   TYPE(CSharpGenericTypeConstraintComma)                                       \
56*12c85518Srobert   TYPE(CSharpNamedArgumentColon)                                               \
57*12c85518Srobert   TYPE(CSharpNullable)                                                         \
58*12c85518Srobert   TYPE(CSharpNullConditionalLSquare)                                           \
59*12c85518Srobert   TYPE(CSharpStringLiteral)                                                    \
60e5dd7070Spatrick   TYPE(CtorInitializerColon)                                                   \
61e5dd7070Spatrick   TYPE(CtorInitializerComma)                                                   \
62e5dd7070Spatrick   TYPE(DesignatedInitializerLSquare)                                           \
63e5dd7070Spatrick   TYPE(DesignatedInitializerPeriod)                                            \
64e5dd7070Spatrick   TYPE(DictLiteral)                                                            \
65*12c85518Srobert   TYPE(ElseLBrace)                                                             \
66*12c85518Srobert   TYPE(EnumLBrace)                                                             \
67a9ac8606Spatrick   TYPE(FatArrow)                                                               \
68e5dd7070Spatrick   TYPE(ForEachMacro)                                                           \
69e5dd7070Spatrick   TYPE(FunctionAnnotationRParen)                                               \
70e5dd7070Spatrick   TYPE(FunctionDeclarationName)                                                \
71e5dd7070Spatrick   TYPE(FunctionLBrace)                                                         \
72*12c85518Srobert   TYPE(FunctionLikeOrFreestandingMacro)                                        \
73e5dd7070Spatrick   TYPE(FunctionTypeLParen)                                                     \
74*12c85518Srobert   /* The colons as part of a C11 _Generic selection */                         \
75*12c85518Srobert   TYPE(GenericSelectionColon)                                                  \
76*12c85518Srobert   /* The colon at the end of a goto label or a case label. Currently only used \
77*12c85518Srobert    * for Verilog. */                                                           \
78*12c85518Srobert   TYPE(GotoLabelColon)                                                         \
79a9ac8606Spatrick   TYPE(IfMacro)                                                                \
80e5dd7070Spatrick   TYPE(ImplicitStringLiteral)                                                  \
81e5dd7070Spatrick   TYPE(InheritanceColon)                                                       \
82e5dd7070Spatrick   TYPE(InheritanceComma)                                                       \
83e5dd7070Spatrick   TYPE(InlineASMBrace)                                                         \
84e5dd7070Spatrick   TYPE(InlineASMColon)                                                         \
85ec727ea7Spatrick   TYPE(InlineASMSymbolicNameLSquare)                                           \
86e5dd7070Spatrick   TYPE(JavaAnnotation)                                                         \
87*12c85518Srobert   TYPE(JsAndAndEqual)                                                          \
88e5dd7070Spatrick   TYPE(JsComputedPropertyName)                                                 \
89e5dd7070Spatrick   TYPE(JsExponentiation)                                                       \
90e5dd7070Spatrick   TYPE(JsExponentiationEqual)                                                  \
91a9ac8606Spatrick   TYPE(JsPipePipeEqual)                                                        \
92e5dd7070Spatrick   TYPE(JsPrivateIdentifier)                                                    \
93e5dd7070Spatrick   TYPE(JsTypeColon)                                                            \
94e5dd7070Spatrick   TYPE(JsTypeOperator)                                                         \
95e5dd7070Spatrick   TYPE(JsTypeOptionalQuestion)                                                 \
96e5dd7070Spatrick   TYPE(LambdaArrow)                                                            \
97e5dd7070Spatrick   TYPE(LambdaLBrace)                                                           \
98e5dd7070Spatrick   TYPE(LambdaLSquare)                                                          \
99e5dd7070Spatrick   TYPE(LeadingJavaAnnotation)                                                  \
100e5dd7070Spatrick   TYPE(LineComment)                                                            \
101e5dd7070Spatrick   TYPE(MacroBlockBegin)                                                        \
102e5dd7070Spatrick   TYPE(MacroBlockEnd)                                                          \
103*12c85518Srobert   TYPE(ModulePartitionColon)                                                   \
104e5dd7070Spatrick   TYPE(NamespaceMacro)                                                         \
105a9ac8606Spatrick   TYPE(NonNullAssertion)                                                       \
106a9ac8606Spatrick   TYPE(NullCoalescingEqual)                                                    \
107a9ac8606Spatrick   TYPE(NullCoalescingOperator)                                                 \
108a9ac8606Spatrick   TYPE(NullPropagatingOperator)                                                \
109e5dd7070Spatrick   TYPE(ObjCBlockLBrace)                                                        \
110e5dd7070Spatrick   TYPE(ObjCBlockLParen)                                                        \
111e5dd7070Spatrick   TYPE(ObjCDecl)                                                               \
112e5dd7070Spatrick   TYPE(ObjCForIn)                                                              \
113e5dd7070Spatrick   TYPE(ObjCMethodExpr)                                                         \
114e5dd7070Spatrick   TYPE(ObjCMethodSpecifier)                                                    \
115e5dd7070Spatrick   TYPE(ObjCProperty)                                                           \
116e5dd7070Spatrick   TYPE(ObjCStringLiteral)                                                      \
117e5dd7070Spatrick   TYPE(OverloadedOperator)                                                     \
118e5dd7070Spatrick   TYPE(OverloadedOperatorLParen)                                               \
119e5dd7070Spatrick   TYPE(PointerOrReference)                                                     \
120*12c85518Srobert   TYPE(ProtoExtensionLSquare)                                                  \
121e5dd7070Spatrick   TYPE(PureVirtualSpecifier)                                                   \
122e5dd7070Spatrick   TYPE(RangeBasedForLoopColon)                                                 \
123*12c85518Srobert   TYPE(RecordLBrace)                                                           \
124e5dd7070Spatrick   TYPE(RegexLiteral)                                                           \
125*12c85518Srobert   TYPE(RequiresClause)                                                         \
126*12c85518Srobert   TYPE(RequiresClauseInARequiresExpression)                                    \
127*12c85518Srobert   TYPE(RequiresExpression)                                                     \
128*12c85518Srobert   TYPE(RequiresExpressionLBrace)                                               \
129*12c85518Srobert   TYPE(RequiresExpressionLParen)                                               \
130e5dd7070Spatrick   TYPE(SelectorName)                                                           \
131e5dd7070Spatrick   TYPE(StartOfName)                                                            \
132a9ac8606Spatrick   TYPE(StatementAttributeLikeMacro)                                            \
133e5dd7070Spatrick   TYPE(StatementMacro)                                                         \
134*12c85518Srobert   TYPE(StructLBrace)                                                           \
135e5dd7070Spatrick   TYPE(StructuredBindingLSquare)                                               \
136e5dd7070Spatrick   TYPE(TemplateCloser)                                                         \
137e5dd7070Spatrick   TYPE(TemplateOpener)                                                         \
138e5dd7070Spatrick   TYPE(TemplateString)                                                         \
139e5dd7070Spatrick   TYPE(TrailingAnnotation)                                                     \
140e5dd7070Spatrick   TYPE(TrailingReturnArrow)                                                    \
141e5dd7070Spatrick   TYPE(TrailingUnaryOperator)                                                  \
142a9ac8606Spatrick   TYPE(TypeDeclarationParen)                                                   \
143e5dd7070Spatrick   TYPE(TypenameMacro)                                                          \
144e5dd7070Spatrick   TYPE(UnaryOperator)                                                          \
145*12c85518Srobert   TYPE(UnionLBrace)                                                            \
146ec727ea7Spatrick   TYPE(UntouchableMacroFunc)                                                   \
147*12c85518Srobert   /* like in begin : block */                                                  \
148*12c85518Srobert   TYPE(VerilogBlockLabelColon)                                                 \
149*12c85518Srobert   /* The square bracket for the dimension part of the type name.               \
150*12c85518Srobert    * In 'logic [1:0] x[1:0]', only the first '['. This way we can have space   \
151*12c85518Srobert    * before the first bracket but not the second. */                           \
152*12c85518Srobert   TYPE(VerilogDimensionedTypeName)                                             \
153*12c85518Srobert   /* for the base in a number literal, not including the quote */              \
154*12c85518Srobert   TYPE(VerilogNumberBase)                                                      \
155*12c85518Srobert   /* Things inside the table in user-defined primitives. */                    \
156*12c85518Srobert   TYPE(VerilogTableItem)                                                       \
157e5dd7070Spatrick   TYPE(Unknown)
158e5dd7070Spatrick 
159ec727ea7Spatrick /// Determines the semantic type of a syntactic token, e.g. whether "<" is a
160ec727ea7Spatrick /// template opener or binary operator.
161a9ac8606Spatrick enum TokenType : uint8_t {
162e5dd7070Spatrick #define TYPE(X) TT_##X,
163e5dd7070Spatrick   LIST_TOKEN_TYPES
164e5dd7070Spatrick #undef TYPE
165e5dd7070Spatrick       NUM_TOKEN_TYPES
166e5dd7070Spatrick };
167e5dd7070Spatrick 
168e5dd7070Spatrick /// Determines the name of a token type.
169e5dd7070Spatrick const char *getTokenTypeName(TokenType Type);
170e5dd7070Spatrick 
171e5dd7070Spatrick // Represents what type of block a set of braces open.
172e5dd7070Spatrick enum BraceBlockKind { BK_Unknown, BK_Block, BK_BracedInit };
173e5dd7070Spatrick 
174e5dd7070Spatrick // The packing kind of a function's parameters.
175e5dd7070Spatrick enum ParameterPackingKind { PPK_BinPacked, PPK_OnePerLine, PPK_Inconclusive };
176e5dd7070Spatrick 
177e5dd7070Spatrick enum FormatDecision { FD_Unformatted, FD_Continue, FD_Break };
178e5dd7070Spatrick 
179a9ac8606Spatrick /// Roles a token can take in a configured macro expansion.
180a9ac8606Spatrick enum MacroRole {
181a9ac8606Spatrick   /// The token was expanded from a macro argument when formatting the expanded
182a9ac8606Spatrick   /// token sequence.
183a9ac8606Spatrick   MR_ExpandedArg,
184a9ac8606Spatrick   /// The token is part of a macro argument that was previously formatted as
185a9ac8606Spatrick   /// expansion when formatting the unexpanded macro call.
186a9ac8606Spatrick   MR_UnexpandedArg,
187a9ac8606Spatrick   /// The token was expanded from a macro definition, and is not visible as part
188a9ac8606Spatrick   /// of the macro call.
189a9ac8606Spatrick   MR_Hidden,
190a9ac8606Spatrick };
191a9ac8606Spatrick 
192a9ac8606Spatrick struct FormatToken;
193a9ac8606Spatrick 
194a9ac8606Spatrick /// Contains information on the token's role in a macro expansion.
195a9ac8606Spatrick ///
196a9ac8606Spatrick /// Given the following definitions:
197a9ac8606Spatrick /// A(X) = [ X ]
198a9ac8606Spatrick /// B(X) = < X >
199a9ac8606Spatrick /// C(X) = X
200a9ac8606Spatrick ///
201a9ac8606Spatrick /// Consider the macro call:
202a9ac8606Spatrick /// A({B(C(C(x)))}) -> [{<x>}]
203a9ac8606Spatrick ///
204a9ac8606Spatrick /// In this case, the tokens of the unexpanded macro call will have the
205a9ac8606Spatrick /// following relevant entries in their macro context (note that formatting
206a9ac8606Spatrick /// the unexpanded macro call happens *after* formatting the expanded macro
207a9ac8606Spatrick /// call):
208a9ac8606Spatrick ///                   A( { B( C( C(x) ) ) } )
209a9ac8606Spatrick /// Role:             NN U NN NN NNUN N N U N  (N=None, U=UnexpandedArg)
210a9ac8606Spatrick ///
211a9ac8606Spatrick ///                   [  { <       x    > } ]
212a9ac8606Spatrick /// Role:             H  E H       E    H E H  (H=Hidden, E=ExpandedArg)
213a9ac8606Spatrick /// ExpandedFrom[0]:  A  A A       A    A A A
214a9ac8606Spatrick /// ExpandedFrom[1]:       B       B    B
215a9ac8606Spatrick /// ExpandedFrom[2]:               C
216a9ac8606Spatrick /// ExpandedFrom[3]:               C
217a9ac8606Spatrick /// StartOfExpansion: 1  0 1       2    0 0 0
218a9ac8606Spatrick /// EndOfExpansion:   0  0 0       2    1 0 1
219a9ac8606Spatrick struct MacroExpansion {
MacroExpansionMacroExpansion220a9ac8606Spatrick   MacroExpansion(MacroRole Role) : Role(Role) {}
221a9ac8606Spatrick 
222a9ac8606Spatrick   /// The token's role in the macro expansion.
223a9ac8606Spatrick   /// When formatting an expanded macro, all tokens that are part of macro
224a9ac8606Spatrick   /// arguments will be MR_ExpandedArg, while all tokens that are not visible in
225a9ac8606Spatrick   /// the macro call will be MR_Hidden.
226a9ac8606Spatrick   /// When formatting an unexpanded macro call, all tokens that are part of
227a9ac8606Spatrick   /// macro arguments will be MR_UnexpandedArg.
228a9ac8606Spatrick   MacroRole Role;
229a9ac8606Spatrick 
230a9ac8606Spatrick   /// The stack of macro call identifier tokens this token was expanded from.
231a9ac8606Spatrick   llvm::SmallVector<FormatToken *, 1> ExpandedFrom;
232a9ac8606Spatrick 
233a9ac8606Spatrick   /// The number of expansions of which this macro is the first entry.
234a9ac8606Spatrick   unsigned StartOfExpansion = 0;
235a9ac8606Spatrick 
236a9ac8606Spatrick   /// The number of currently open expansions in \c ExpandedFrom this macro is
237a9ac8606Spatrick   /// the last token in.
238a9ac8606Spatrick   unsigned EndOfExpansion = 0;
239a9ac8606Spatrick };
240a9ac8606Spatrick 
241e5dd7070Spatrick class TokenRole;
242e5dd7070Spatrick class AnnotatedLine;
243e5dd7070Spatrick 
244e5dd7070Spatrick /// A wrapper around a \c Token storing information about the
245e5dd7070Spatrick /// whitespace characters preceding it.
246e5dd7070Spatrick struct FormatToken {
FormatTokenFormatToken247a9ac8606Spatrick   FormatToken()
248a9ac8606Spatrick       : HasUnescapedNewline(false), IsMultiline(false), IsFirst(false),
249a9ac8606Spatrick         MustBreakBefore(false), IsUnterminatedLiteral(false),
250a9ac8606Spatrick         CanBreakBefore(false), ClosesTemplateDeclaration(false),
251a9ac8606Spatrick         StartsBinaryExpression(false), EndsBinaryExpression(false),
252a9ac8606Spatrick         PartOfMultiVariableDeclStmt(false), ContinuesLineCommentSection(false),
253*12c85518Srobert         Finalized(false), ClosesRequiresClause(false),
254*12c85518Srobert         EndsCppAttributeGroup(false), BlockKind(BK_Unknown),
255*12c85518Srobert         Decision(FD_Unformatted), PackingKind(PPK_Inconclusive),
256*12c85518Srobert         TypeIsFinalized(false), Type(TT_Unknown) {}
257e5dd7070Spatrick 
258e5dd7070Spatrick   /// The \c Token.
259e5dd7070Spatrick   Token Tok;
260e5dd7070Spatrick 
261a9ac8606Spatrick   /// The raw text of the token.
262a9ac8606Spatrick   ///
263a9ac8606Spatrick   /// Contains the raw token text without leading whitespace and without leading
264a9ac8606Spatrick   /// escaped newlines.
265a9ac8606Spatrick   StringRef TokenText;
266a9ac8606Spatrick 
267a9ac8606Spatrick   /// A token can have a special role that can carry extra information
268a9ac8606Spatrick   /// about the token's formatting.
269a9ac8606Spatrick   /// FIXME: Make FormatToken for parsing and AnnotatedToken two different
270a9ac8606Spatrick   /// classes and make this a unique_ptr in the AnnotatedToken class.
271a9ac8606Spatrick   std::shared_ptr<TokenRole> Role;
272a9ac8606Spatrick 
273a9ac8606Spatrick   /// The range of the whitespace immediately preceding the \c Token.
274a9ac8606Spatrick   SourceRange WhitespaceRange;
275a9ac8606Spatrick 
276a9ac8606Spatrick   /// Whether there is at least one unescaped newline before the \c
277a9ac8606Spatrick   /// Token.
278a9ac8606Spatrick   unsigned HasUnescapedNewline : 1;
279a9ac8606Spatrick 
280a9ac8606Spatrick   /// Whether the token text contains newlines (escaped or not).
281a9ac8606Spatrick   unsigned IsMultiline : 1;
282a9ac8606Spatrick 
283a9ac8606Spatrick   /// Indicates that this is the first token of the file.
284a9ac8606Spatrick   unsigned IsFirst : 1;
285a9ac8606Spatrick 
286a9ac8606Spatrick   /// Whether there must be a line break before this token.
287a9ac8606Spatrick   ///
288a9ac8606Spatrick   /// This happens for example when a preprocessor directive ended directly
289a9ac8606Spatrick   /// before the token.
290a9ac8606Spatrick   unsigned MustBreakBefore : 1;
291a9ac8606Spatrick 
292a9ac8606Spatrick   /// Set to \c true if this token is an unterminated literal.
293a9ac8606Spatrick   unsigned IsUnterminatedLiteral : 1;
294a9ac8606Spatrick 
295a9ac8606Spatrick   /// \c true if it is allowed to break before this token.
296a9ac8606Spatrick   unsigned CanBreakBefore : 1;
297a9ac8606Spatrick 
298a9ac8606Spatrick   /// \c true if this is the ">" of "template<..>".
299a9ac8606Spatrick   unsigned ClosesTemplateDeclaration : 1;
300a9ac8606Spatrick 
301a9ac8606Spatrick   /// \c true if this token starts a binary expression, i.e. has at least
302a9ac8606Spatrick   /// one fake l_paren with a precedence greater than prec::Unknown.
303a9ac8606Spatrick   unsigned StartsBinaryExpression : 1;
304a9ac8606Spatrick   /// \c true if this token ends a binary expression.
305a9ac8606Spatrick   unsigned EndsBinaryExpression : 1;
306a9ac8606Spatrick 
307a9ac8606Spatrick   /// Is this token part of a \c DeclStmt defining multiple variables?
308a9ac8606Spatrick   ///
309a9ac8606Spatrick   /// Only set if \c Type == \c TT_StartOfName.
310a9ac8606Spatrick   unsigned PartOfMultiVariableDeclStmt : 1;
311a9ac8606Spatrick 
312a9ac8606Spatrick   /// Does this line comment continue a line comment section?
313a9ac8606Spatrick   ///
314a9ac8606Spatrick   /// Only set to true if \c Type == \c TT_LineComment.
315a9ac8606Spatrick   unsigned ContinuesLineCommentSection : 1;
316a9ac8606Spatrick 
317a9ac8606Spatrick   /// If \c true, this token has been fully formatted (indented and
318a9ac8606Spatrick   /// potentially re-formatted inside), and we do not allow further formatting
319a9ac8606Spatrick   /// changes.
320a9ac8606Spatrick   unsigned Finalized : 1;
321a9ac8606Spatrick 
322*12c85518Srobert   /// \c true if this is the last token within requires clause.
323*12c85518Srobert   unsigned ClosesRequiresClause : 1;
324*12c85518Srobert 
325*12c85518Srobert   /// \c true if this token ends a group of C++ attributes.
326*12c85518Srobert   unsigned EndsCppAttributeGroup : 1;
327*12c85518Srobert 
328a9ac8606Spatrick private:
329a9ac8606Spatrick   /// Contains the kind of block if this token is a brace.
330a9ac8606Spatrick   unsigned BlockKind : 2;
331a9ac8606Spatrick 
332a9ac8606Spatrick public:
getBlockKindFormatToken333a9ac8606Spatrick   BraceBlockKind getBlockKind() const {
334a9ac8606Spatrick     return static_cast<BraceBlockKind>(BlockKind);
335a9ac8606Spatrick   }
setBlockKindFormatToken336a9ac8606Spatrick   void setBlockKind(BraceBlockKind BBK) {
337a9ac8606Spatrick     BlockKind = BBK;
338a9ac8606Spatrick     assert(getBlockKind() == BBK && "BraceBlockKind overflow!");
339a9ac8606Spatrick   }
340a9ac8606Spatrick 
341a9ac8606Spatrick private:
342a9ac8606Spatrick   /// Stores the formatting decision for the token once it was made.
343a9ac8606Spatrick   unsigned Decision : 2;
344a9ac8606Spatrick 
345a9ac8606Spatrick public:
getDecisionFormatToken346a9ac8606Spatrick   FormatDecision getDecision() const {
347a9ac8606Spatrick     return static_cast<FormatDecision>(Decision);
348a9ac8606Spatrick   }
setDecisionFormatToken349a9ac8606Spatrick   void setDecision(FormatDecision D) {
350a9ac8606Spatrick     Decision = D;
351a9ac8606Spatrick     assert(getDecision() == D && "FormatDecision overflow!");
352a9ac8606Spatrick   }
353a9ac8606Spatrick 
354a9ac8606Spatrick private:
355a9ac8606Spatrick   /// If this is an opening parenthesis, how are the parameters packed?
356a9ac8606Spatrick   unsigned PackingKind : 2;
357a9ac8606Spatrick 
358a9ac8606Spatrick public:
getPackingKindFormatToken359a9ac8606Spatrick   ParameterPackingKind getPackingKind() const {
360a9ac8606Spatrick     return static_cast<ParameterPackingKind>(PackingKind);
361a9ac8606Spatrick   }
setPackingKindFormatToken362a9ac8606Spatrick   void setPackingKind(ParameterPackingKind K) {
363a9ac8606Spatrick     PackingKind = K;
364a9ac8606Spatrick     assert(getPackingKind() == K && "ParameterPackingKind overflow!");
365a9ac8606Spatrick   }
366a9ac8606Spatrick 
367a9ac8606Spatrick private:
368*12c85518Srobert   unsigned TypeIsFinalized : 1;
369a9ac8606Spatrick   TokenType Type;
370a9ac8606Spatrick 
371a9ac8606Spatrick public:
372a9ac8606Spatrick   /// Returns the token's type, e.g. whether "<" is a template opener or
373a9ac8606Spatrick   /// binary operator.
getTypeFormatToken374a9ac8606Spatrick   TokenType getType() const { return Type; }
setTypeFormatToken375*12c85518Srobert   void setType(TokenType T) {
376*12c85518Srobert     assert((!TypeIsFinalized || T == Type) &&
377*12c85518Srobert            "Please use overwriteFixedType to change a fixed type.");
378*12c85518Srobert     Type = T;
379*12c85518Srobert   }
380*12c85518Srobert   /// Sets the type and also the finalized flag. This prevents the type to be
381*12c85518Srobert   /// reset in TokenAnnotator::resetTokenMetadata(). If the type needs to be set
382*12c85518Srobert   /// to another one please use overwriteFixedType, or even better remove the
383*12c85518Srobert   /// need to reassign the type.
setFinalizedTypeFormatToken384*12c85518Srobert   void setFinalizedType(TokenType T) {
385*12c85518Srobert     Type = T;
386*12c85518Srobert     TypeIsFinalized = true;
387*12c85518Srobert   }
overwriteFixedTypeFormatToken388*12c85518Srobert   void overwriteFixedType(TokenType T) {
389*12c85518Srobert     TypeIsFinalized = false;
390*12c85518Srobert     setType(T);
391*12c85518Srobert   }
isTypeFinalizedFormatToken392*12c85518Srobert   bool isTypeFinalized() const { return TypeIsFinalized; }
393*12c85518Srobert 
394*12c85518Srobert   /// Used to set an operator precedence explicitly.
395*12c85518Srobert   prec::Level ForcedPrecedence = prec::Unknown;
396a9ac8606Spatrick 
397e5dd7070Spatrick   /// The number of newlines immediately before the \c Token.
398e5dd7070Spatrick   ///
399e5dd7070Spatrick   /// This can be used to determine what the user wrote in the original code
400e5dd7070Spatrick   /// and thereby e.g. leave an empty line between two function definitions.
401e5dd7070Spatrick   unsigned NewlinesBefore = 0;
402e5dd7070Spatrick 
403e5dd7070Spatrick   /// The offset just past the last '\n' in this token's leading
404e5dd7070Spatrick   /// whitespace (relative to \c WhiteSpaceStart). 0 if there is no '\n'.
405e5dd7070Spatrick   unsigned LastNewlineOffset = 0;
406e5dd7070Spatrick 
407e5dd7070Spatrick   /// The width of the non-whitespace parts of the token (or its first
408e5dd7070Spatrick   /// line for multi-line tokens) in columns.
409e5dd7070Spatrick   /// We need this to correctly measure number of columns a token spans.
410e5dd7070Spatrick   unsigned ColumnWidth = 0;
411e5dd7070Spatrick 
412e5dd7070Spatrick   /// Contains the width in columns of the last line of a multi-line
413e5dd7070Spatrick   /// token.
414e5dd7070Spatrick   unsigned LastLineColumnWidth = 0;
415e5dd7070Spatrick 
416e5dd7070Spatrick   /// The number of spaces that should be inserted before this token.
417e5dd7070Spatrick   unsigned SpacesRequiredBefore = 0;
418e5dd7070Spatrick 
419e5dd7070Spatrick   /// Number of parameters, if this is "(", "[" or "<".
420e5dd7070Spatrick   unsigned ParameterCount = 0;
421e5dd7070Spatrick 
422e5dd7070Spatrick   /// Number of parameters that are nested blocks,
423e5dd7070Spatrick   /// if this is "(", "[" or "<".
424e5dd7070Spatrick   unsigned BlockParameterCount = 0;
425e5dd7070Spatrick 
426e5dd7070Spatrick   /// If this is a bracket ("<", "(", "[" or "{"), contains the kind of
427e5dd7070Spatrick   /// the surrounding bracket.
428e5dd7070Spatrick   tok::TokenKind ParentBracket = tok::unknown;
429e5dd7070Spatrick 
430e5dd7070Spatrick   /// The total length of the unwrapped line up to and including this
431e5dd7070Spatrick   /// token.
432e5dd7070Spatrick   unsigned TotalLength = 0;
433e5dd7070Spatrick 
434e5dd7070Spatrick   /// The original 0-based column of this token, including expanded tabs.
435e5dd7070Spatrick   /// The configured TabWidth is used as tab width.
436e5dd7070Spatrick   unsigned OriginalColumn = 0;
437e5dd7070Spatrick 
438e5dd7070Spatrick   /// The length of following tokens until the next natural split point,
439e5dd7070Spatrick   /// or the next token that can be broken.
440e5dd7070Spatrick   unsigned UnbreakableTailLength = 0;
441e5dd7070Spatrick 
442e5dd7070Spatrick   // FIXME: Come up with a 'cleaner' concept.
443e5dd7070Spatrick   /// The binding strength of a token. This is a combined value of
444e5dd7070Spatrick   /// operator precedence, parenthesis nesting, etc.
445e5dd7070Spatrick   unsigned BindingStrength = 0;
446e5dd7070Spatrick 
447e5dd7070Spatrick   /// The nesting level of this token, i.e. the number of surrounding (),
448e5dd7070Spatrick   /// [], {} or <>.
449e5dd7070Spatrick   unsigned NestingLevel = 0;
450e5dd7070Spatrick 
451e5dd7070Spatrick   /// The indent level of this token. Copied from the surrounding line.
452e5dd7070Spatrick   unsigned IndentLevel = 0;
453e5dd7070Spatrick 
454e5dd7070Spatrick   /// Penalty for inserting a line break before this token.
455e5dd7070Spatrick   unsigned SplitPenalty = 0;
456e5dd7070Spatrick 
457e5dd7070Spatrick   /// If this is the first ObjC selector name in an ObjC method
458e5dd7070Spatrick   /// definition or call, this contains the length of the longest name.
459e5dd7070Spatrick   ///
460e5dd7070Spatrick   /// This being set to 0 means that the selectors should not be colon-aligned,
461e5dd7070Spatrick   /// e.g. because several of them are block-type.
462e5dd7070Spatrick   unsigned LongestObjCSelectorName = 0;
463e5dd7070Spatrick 
464e5dd7070Spatrick   /// If this is the first ObjC selector name in an ObjC method
465e5dd7070Spatrick   /// definition or call, this contains the number of parts that the whole
466e5dd7070Spatrick   /// selector consist of.
467e5dd7070Spatrick   unsigned ObjCSelectorNameParts = 0;
468e5dd7070Spatrick 
469e5dd7070Spatrick   /// The 0-based index of the parameter/argument. For ObjC it is set
470e5dd7070Spatrick   /// for the selector name token.
471e5dd7070Spatrick   /// For now calculated only for ObjC.
472e5dd7070Spatrick   unsigned ParameterIndex = 0;
473e5dd7070Spatrick 
474e5dd7070Spatrick   /// Stores the number of required fake parentheses and the
475e5dd7070Spatrick   /// corresponding operator precedence.
476e5dd7070Spatrick   ///
477e5dd7070Spatrick   /// If multiple fake parentheses start at a token, this vector stores them in
478e5dd7070Spatrick   /// reverse order, i.e. inner fake parenthesis first.
479e5dd7070Spatrick   SmallVector<prec::Level, 4> FakeLParens;
480e5dd7070Spatrick   /// Insert this many fake ) after this token for correct indentation.
481e5dd7070Spatrick   unsigned FakeRParens = 0;
482e5dd7070Spatrick 
483e5dd7070Spatrick   /// If this is an operator (or "."/"->") in a sequence of operators
484e5dd7070Spatrick   /// with the same precedence, contains the 0-based operator index.
485e5dd7070Spatrick   unsigned OperatorIndex = 0;
486e5dd7070Spatrick 
487e5dd7070Spatrick   /// If this is an operator (or "."/"->") in a sequence of operators
488e5dd7070Spatrick   /// with the same precedence, points to the next operator.
489e5dd7070Spatrick   FormatToken *NextOperator = nullptr;
490e5dd7070Spatrick 
491e5dd7070Spatrick   /// If this is a bracket, this points to the matching one.
492e5dd7070Spatrick   FormatToken *MatchingParen = nullptr;
493e5dd7070Spatrick 
494e5dd7070Spatrick   /// The previous token in the unwrapped line.
495e5dd7070Spatrick   FormatToken *Previous = nullptr;
496e5dd7070Spatrick 
497e5dd7070Spatrick   /// The next token in the unwrapped line.
498e5dd7070Spatrick   FormatToken *Next = nullptr;
499e5dd7070Spatrick 
500a9ac8606Spatrick   /// The first token in set of column elements.
501a9ac8606Spatrick   bool StartsColumn = false;
502a9ac8606Spatrick 
503a9ac8606Spatrick   /// This notes the start of the line of an array initializer.
504a9ac8606Spatrick   bool ArrayInitializerLineStart = false;
505a9ac8606Spatrick 
506a9ac8606Spatrick   /// This starts an array initializer.
507a9ac8606Spatrick   bool IsArrayInitializer = false;
508a9ac8606Spatrick 
509*12c85518Srobert   /// Is optional and can be removed.
510*12c85518Srobert   bool Optional = false;
511*12c85518Srobert 
512*12c85518Srobert   /// Number of optional braces to be inserted after this token:
513*12c85518Srobert   ///   -1: a single left brace
514*12c85518Srobert   ///    0: no braces
515*12c85518Srobert   ///   >0: number of right braces
516*12c85518Srobert   int8_t BraceCount = 0;
517*12c85518Srobert 
518e5dd7070Spatrick   /// If this token starts a block, this contains all the unwrapped lines
519e5dd7070Spatrick   /// in it.
520e5dd7070Spatrick   SmallVector<AnnotatedLine *, 1> Children;
521e5dd7070Spatrick 
522a9ac8606Spatrick   // Contains all attributes related to how this token takes part
523a9ac8606Spatrick   // in a configured macro expansion.
524*12c85518Srobert   std::optional<MacroExpansion> MacroCtx;
525*12c85518Srobert 
526*12c85518Srobert   /// When macro expansion introduces nodes with children, those are marked as
527*12c85518Srobert   /// \c MacroParent.
528*12c85518Srobert   /// FIXME: The formatting code currently hard-codes the assumption that
529*12c85518Srobert   /// child nodes are introduced by blocks following an opening brace.
530*12c85518Srobert   /// This is deeply baked into the code and disentangling this will require
531*12c85518Srobert   /// signficant refactorings. \c MacroParent allows us to special-case the
532*12c85518Srobert   /// cases in which we treat parents as block-openers for now.
533*12c85518Srobert   bool MacroParent = false;
534e5dd7070Spatrick 
isFormatToken535e5dd7070Spatrick   bool is(tok::TokenKind Kind) const { return Tok.is(Kind); }
isFormatToken536a9ac8606Spatrick   bool is(TokenType TT) const { return getType() == TT; }
isFormatToken537e5dd7070Spatrick   bool is(const IdentifierInfo *II) const {
538e5dd7070Spatrick     return II && II == Tok.getIdentifierInfo();
539e5dd7070Spatrick   }
isFormatToken540e5dd7070Spatrick   bool is(tok::PPKeywordKind Kind) const {
541e5dd7070Spatrick     return Tok.getIdentifierInfo() &&
542e5dd7070Spatrick            Tok.getIdentifierInfo()->getPPKeywordID() == Kind;
543e5dd7070Spatrick   }
isFormatToken544a9ac8606Spatrick   bool is(BraceBlockKind BBK) const { return getBlockKind() == BBK; }
isFormatToken545a9ac8606Spatrick   bool is(ParameterPackingKind PPK) const { return getPackingKind() == PPK; }
546a9ac8606Spatrick 
isOneOfFormatToken547e5dd7070Spatrick   template <typename A, typename B> bool isOneOf(A K1, B K2) const {
548e5dd7070Spatrick     return is(K1) || is(K2);
549e5dd7070Spatrick   }
550e5dd7070Spatrick   template <typename A, typename B, typename... Ts>
isOneOfFormatToken551e5dd7070Spatrick   bool isOneOf(A K1, B K2, Ts... Ks) const {
552e5dd7070Spatrick     return is(K1) || isOneOf(K2, Ks...);
553e5dd7070Spatrick   }
isNotFormatToken554e5dd7070Spatrick   template <typename T> bool isNot(T Kind) const { return !is(Kind); }
555e5dd7070Spatrick 
556e5dd7070Spatrick   bool isIf(bool AllowConstexprMacro = true) const {
557e5dd7070Spatrick     return is(tok::kw_if) || endsSequence(tok::kw_constexpr, tok::kw_if) ||
558e5dd7070Spatrick            (endsSequence(tok::identifier, tok::kw_if) && AllowConstexprMacro);
559e5dd7070Spatrick   }
560e5dd7070Spatrick 
closesScopeAfterBlockFormatToken561e5dd7070Spatrick   bool closesScopeAfterBlock() const {
562a9ac8606Spatrick     if (getBlockKind() == BK_Block)
563e5dd7070Spatrick       return true;
564e5dd7070Spatrick     if (closesScope())
565e5dd7070Spatrick       return Previous->closesScopeAfterBlock();
566e5dd7070Spatrick     return false;
567e5dd7070Spatrick   }
568e5dd7070Spatrick 
569e5dd7070Spatrick   /// \c true if this token starts a sequence with the given tokens in order,
570e5dd7070Spatrick   /// following the ``Next`` pointers, ignoring comments.
571e5dd7070Spatrick   template <typename A, typename... Ts>
startsSequenceFormatToken572e5dd7070Spatrick   bool startsSequence(A K1, Ts... Tokens) const {
573e5dd7070Spatrick     return startsSequenceInternal(K1, Tokens...);
574e5dd7070Spatrick   }
575e5dd7070Spatrick 
576e5dd7070Spatrick   /// \c true if this token ends a sequence with the given tokens in order,
577e5dd7070Spatrick   /// following the ``Previous`` pointers, ignoring comments.
578e5dd7070Spatrick   /// For example, given tokens [T1, T2, T3], the function returns true if
579e5dd7070Spatrick   /// 3 tokens ending at this (ignoring comments) are [T3, T2, T1]. In other
580e5dd7070Spatrick   /// words, the tokens passed to this function need to the reverse of the
581e5dd7070Spatrick   /// order the tokens appear in code.
582e5dd7070Spatrick   template <typename A, typename... Ts>
endsSequenceFormatToken583e5dd7070Spatrick   bool endsSequence(A K1, Ts... Tokens) const {
584e5dd7070Spatrick     return endsSequenceInternal(K1, Tokens...);
585e5dd7070Spatrick   }
586e5dd7070Spatrick 
isStringLiteralFormatToken587e5dd7070Spatrick   bool isStringLiteral() const { return tok::isStringLiteral(Tok.getKind()); }
588e5dd7070Spatrick 
isObjCAtKeywordFormatToken589e5dd7070Spatrick   bool isObjCAtKeyword(tok::ObjCKeywordKind Kind) const {
590e5dd7070Spatrick     return Tok.isObjCAtKeyword(Kind);
591e5dd7070Spatrick   }
592e5dd7070Spatrick 
593e5dd7070Spatrick   bool isAccessSpecifier(bool ColonRequired = true) const {
594*12c85518Srobert     if (!isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private))
595*12c85518Srobert       return false;
596*12c85518Srobert     if (!ColonRequired)
597*12c85518Srobert       return true;
598*12c85518Srobert     const auto NextNonComment = getNextNonComment();
599*12c85518Srobert     return NextNonComment && NextNonComment->is(tok::colon);
600e5dd7070Spatrick   }
601e5dd7070Spatrick 
canBePointerOrReferenceQualifierFormatToken602a9ac8606Spatrick   bool canBePointerOrReferenceQualifier() const {
603a9ac8606Spatrick     return isOneOf(tok::kw_const, tok::kw_restrict, tok::kw_volatile,
604a9ac8606Spatrick                    tok::kw___attribute, tok::kw__Nonnull, tok::kw__Nullable,
605a9ac8606Spatrick                    tok::kw__Null_unspecified, tok::kw___ptr32, tok::kw___ptr64,
606a9ac8606Spatrick                    TT_AttributeMacro);
607a9ac8606Spatrick   }
608a9ac8606Spatrick 
609e5dd7070Spatrick   /// Determine whether the token is a simple-type-specifier.
610*12c85518Srobert   [[nodiscard]] bool isSimpleTypeSpecifier() const;
611*12c85518Srobert 
612*12c85518Srobert   [[nodiscard]] bool isTypeOrIdentifier() const;
613e5dd7070Spatrick 
isObjCAccessSpecifierFormatToken614e5dd7070Spatrick   bool isObjCAccessSpecifier() const {
615e5dd7070Spatrick     return is(tok::at) && Next &&
616e5dd7070Spatrick            (Next->isObjCAtKeyword(tok::objc_public) ||
617e5dd7070Spatrick             Next->isObjCAtKeyword(tok::objc_protected) ||
618e5dd7070Spatrick             Next->isObjCAtKeyword(tok::objc_package) ||
619e5dd7070Spatrick             Next->isObjCAtKeyword(tok::objc_private));
620e5dd7070Spatrick   }
621e5dd7070Spatrick 
622e5dd7070Spatrick   /// Returns whether \p Tok is ([{ or an opening < of a template or in
623e5dd7070Spatrick   /// protos.
opensScopeFormatToken624e5dd7070Spatrick   bool opensScope() const {
625e5dd7070Spatrick     if (is(TT_TemplateString) && TokenText.endswith("${"))
626e5dd7070Spatrick       return true;
627e5dd7070Spatrick     if (is(TT_DictLiteral) && is(tok::less))
628e5dd7070Spatrick       return true;
629e5dd7070Spatrick     return isOneOf(tok::l_paren, tok::l_brace, tok::l_square,
630e5dd7070Spatrick                    TT_TemplateOpener);
631e5dd7070Spatrick   }
632e5dd7070Spatrick   /// Returns whether \p Tok is )]} or a closing > of a template or in
633e5dd7070Spatrick   /// protos.
closesScopeFormatToken634e5dd7070Spatrick   bool closesScope() const {
635e5dd7070Spatrick     if (is(TT_TemplateString) && TokenText.startswith("}"))
636e5dd7070Spatrick       return true;
637e5dd7070Spatrick     if (is(TT_DictLiteral) && is(tok::greater))
638e5dd7070Spatrick       return true;
639e5dd7070Spatrick     return isOneOf(tok::r_paren, tok::r_brace, tok::r_square,
640e5dd7070Spatrick                    TT_TemplateCloser);
641e5dd7070Spatrick   }
642e5dd7070Spatrick 
643e5dd7070Spatrick   /// Returns \c true if this is a "." or "->" accessing a member.
isMemberAccessFormatToken644e5dd7070Spatrick   bool isMemberAccess() const {
645e5dd7070Spatrick     return isOneOf(tok::arrow, tok::period, tok::arrowstar) &&
646e5dd7070Spatrick            !isOneOf(TT_DesignatedInitializerPeriod, TT_TrailingReturnArrow,
647e5dd7070Spatrick                     TT_LambdaArrow, TT_LeadingJavaAnnotation);
648e5dd7070Spatrick   }
649e5dd7070Spatrick 
isUnaryOperatorFormatToken650e5dd7070Spatrick   bool isUnaryOperator() const {
651e5dd7070Spatrick     switch (Tok.getKind()) {
652e5dd7070Spatrick     case tok::plus:
653e5dd7070Spatrick     case tok::plusplus:
654e5dd7070Spatrick     case tok::minus:
655e5dd7070Spatrick     case tok::minusminus:
656e5dd7070Spatrick     case tok::exclaim:
657e5dd7070Spatrick     case tok::tilde:
658e5dd7070Spatrick     case tok::kw_sizeof:
659e5dd7070Spatrick     case tok::kw_alignof:
660e5dd7070Spatrick       return true;
661e5dd7070Spatrick     default:
662e5dd7070Spatrick       return false;
663e5dd7070Spatrick     }
664e5dd7070Spatrick   }
665e5dd7070Spatrick 
isBinaryOperatorFormatToken666e5dd7070Spatrick   bool isBinaryOperator() const {
667e5dd7070Spatrick     // Comma is a binary operator, but does not behave as such wrt. formatting.
668e5dd7070Spatrick     return getPrecedence() > prec::Comma;
669e5dd7070Spatrick   }
670e5dd7070Spatrick 
isTrailingCommentFormatToken671e5dd7070Spatrick   bool isTrailingComment() const {
672e5dd7070Spatrick     return is(tok::comment) &&
673e5dd7070Spatrick            (is(TT_LineComment) || !Next || Next->NewlinesBefore > 0);
674e5dd7070Spatrick   }
675e5dd7070Spatrick 
676e5dd7070Spatrick   /// Returns \c true if this is a keyword that can be used
677e5dd7070Spatrick   /// like a function call (e.g. sizeof, typeid, ...).
isFunctionLikeKeywordFormatToken678e5dd7070Spatrick   bool isFunctionLikeKeyword() const {
679e5dd7070Spatrick     switch (Tok.getKind()) {
680e5dd7070Spatrick     case tok::kw_throw:
681e5dd7070Spatrick     case tok::kw_typeid:
682e5dd7070Spatrick     case tok::kw_return:
683e5dd7070Spatrick     case tok::kw_sizeof:
684e5dd7070Spatrick     case tok::kw_alignof:
685e5dd7070Spatrick     case tok::kw_alignas:
686e5dd7070Spatrick     case tok::kw_decltype:
687e5dd7070Spatrick     case tok::kw_noexcept:
688e5dd7070Spatrick     case tok::kw_static_assert:
689a9ac8606Spatrick     case tok::kw__Atomic:
690e5dd7070Spatrick     case tok::kw___attribute:
691*12c85518Srobert #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
692*12c85518Srobert #include "clang/Basic/TransformTypeTraits.def"
693a9ac8606Spatrick     case tok::kw_requires:
694e5dd7070Spatrick       return true;
695e5dd7070Spatrick     default:
696e5dd7070Spatrick       return false;
697e5dd7070Spatrick     }
698e5dd7070Spatrick   }
699e5dd7070Spatrick 
700e5dd7070Spatrick   /// Returns \c true if this is a string literal that's like a label,
701e5dd7070Spatrick   /// e.g. ends with "=" or ":".
isLabelStringFormatToken702e5dd7070Spatrick   bool isLabelString() const {
703e5dd7070Spatrick     if (!is(tok::string_literal))
704e5dd7070Spatrick       return false;
705e5dd7070Spatrick     StringRef Content = TokenText;
706e5dd7070Spatrick     if (Content.startswith("\"") || Content.startswith("'"))
707e5dd7070Spatrick       Content = Content.drop_front(1);
708e5dd7070Spatrick     if (Content.endswith("\"") || Content.endswith("'"))
709e5dd7070Spatrick       Content = Content.drop_back(1);
710e5dd7070Spatrick     Content = Content.trim();
711e5dd7070Spatrick     return Content.size() > 1 &&
712e5dd7070Spatrick            (Content.back() == ':' || Content.back() == '=');
713e5dd7070Spatrick   }
714e5dd7070Spatrick 
715e5dd7070Spatrick   /// Returns actual token start location without leading escaped
716e5dd7070Spatrick   /// newlines and whitespace.
717e5dd7070Spatrick   ///
718e5dd7070Spatrick   /// This can be different to Tok.getLocation(), which includes leading escaped
719e5dd7070Spatrick   /// newlines.
getStartOfNonWhitespaceFormatToken720e5dd7070Spatrick   SourceLocation getStartOfNonWhitespace() const {
721e5dd7070Spatrick     return WhitespaceRange.getEnd();
722e5dd7070Spatrick   }
723e5dd7070Spatrick 
724*12c85518Srobert   /// Returns \c true if the range of whitespace immediately preceding the \c
725*12c85518Srobert   /// Token is not empty.
hasWhitespaceBeforeFormatToken726*12c85518Srobert   bool hasWhitespaceBefore() const {
727*12c85518Srobert     return WhitespaceRange.getBegin() != WhitespaceRange.getEnd();
728*12c85518Srobert   }
729*12c85518Srobert 
getPrecedenceFormatToken730e5dd7070Spatrick   prec::Level getPrecedence() const {
731*12c85518Srobert     if (ForcedPrecedence != prec::Unknown)
732*12c85518Srobert       return ForcedPrecedence;
733e5dd7070Spatrick     return getBinOpPrecedence(Tok.getKind(), /*GreaterThanIsOperator=*/true,
734e5dd7070Spatrick                               /*CPlusPlus11=*/true);
735e5dd7070Spatrick   }
736e5dd7070Spatrick 
737e5dd7070Spatrick   /// Returns the previous token ignoring comments.
getPreviousNonCommentFormatToken738*12c85518Srobert   [[nodiscard]] FormatToken *getPreviousNonComment() const {
739e5dd7070Spatrick     FormatToken *Tok = Previous;
740e5dd7070Spatrick     while (Tok && Tok->is(tok::comment))
741e5dd7070Spatrick       Tok = Tok->Previous;
742e5dd7070Spatrick     return Tok;
743e5dd7070Spatrick   }
744e5dd7070Spatrick 
745e5dd7070Spatrick   /// Returns the next token ignoring comments.
getNextNonCommentFormatToken746*12c85518Srobert   [[nodiscard]] const FormatToken *getNextNonComment() const {
747e5dd7070Spatrick     const FormatToken *Tok = Next;
748e5dd7070Spatrick     while (Tok && Tok->is(tok::comment))
749e5dd7070Spatrick       Tok = Tok->Next;
750e5dd7070Spatrick     return Tok;
751e5dd7070Spatrick   }
752e5dd7070Spatrick 
753e5dd7070Spatrick   /// Returns \c true if this tokens starts a block-type list, i.e. a
754e5dd7070Spatrick   /// list that should be indented with a block indent.
755*12c85518Srobert   [[nodiscard]] bool opensBlockOrBlockTypeList(const FormatStyle &Style) const;
756e5dd7070Spatrick 
757e5dd7070Spatrick   /// Returns whether the token is the left square bracket of a C++
758e5dd7070Spatrick   /// structured binding declaration.
isCppStructuredBindingFormatToken759e5dd7070Spatrick   bool isCppStructuredBinding(const FormatStyle &Style) const {
760e5dd7070Spatrick     if (!Style.isCpp() || isNot(tok::l_square))
761e5dd7070Spatrick       return false;
762e5dd7070Spatrick     const FormatToken *T = this;
763e5dd7070Spatrick     do {
764e5dd7070Spatrick       T = T->getPreviousNonComment();
765e5dd7070Spatrick     } while (T && T->isOneOf(tok::kw_const, tok::kw_volatile, tok::amp,
766e5dd7070Spatrick                              tok::ampamp));
767e5dd7070Spatrick     return T && T->is(tok::kw_auto);
768e5dd7070Spatrick   }
769e5dd7070Spatrick 
770e5dd7070Spatrick   /// Same as opensBlockOrBlockTypeList, but for the closing token.
closesBlockOrBlockTypeListFormatToken771e5dd7070Spatrick   bool closesBlockOrBlockTypeList(const FormatStyle &Style) const {
772e5dd7070Spatrick     if (is(TT_TemplateString) && closesScope())
773e5dd7070Spatrick       return true;
774e5dd7070Spatrick     return MatchingParen && MatchingParen->opensBlockOrBlockTypeList(Style);
775e5dd7070Spatrick   }
776e5dd7070Spatrick 
777e5dd7070Spatrick   /// Return the actual namespace token, if this token starts a namespace
778e5dd7070Spatrick   /// block.
getNamespaceTokenFormatToken779e5dd7070Spatrick   const FormatToken *getNamespaceToken() const {
780e5dd7070Spatrick     const FormatToken *NamespaceTok = this;
781e5dd7070Spatrick     if (is(tok::comment))
782e5dd7070Spatrick       NamespaceTok = NamespaceTok->getNextNonComment();
783e5dd7070Spatrick     // Detect "(inline|export)? namespace" in the beginning of a line.
784e5dd7070Spatrick     if (NamespaceTok && NamespaceTok->isOneOf(tok::kw_inline, tok::kw_export))
785e5dd7070Spatrick       NamespaceTok = NamespaceTok->getNextNonComment();
786e5dd7070Spatrick     return NamespaceTok &&
787e5dd7070Spatrick                    NamespaceTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro)
788e5dd7070Spatrick                ? NamespaceTok
789e5dd7070Spatrick                : nullptr;
790e5dd7070Spatrick   }
791e5dd7070Spatrick 
copyFromFormatToken792a9ac8606Spatrick   void copyFrom(const FormatToken &Tok) { *this = Tok; }
793a9ac8606Spatrick 
794e5dd7070Spatrick private:
795a9ac8606Spatrick   // Only allow copying via the explicit copyFrom method.
796e5dd7070Spatrick   FormatToken(const FormatToken &) = delete;
797a9ac8606Spatrick   FormatToken &operator=(const FormatToken &) = default;
798e5dd7070Spatrick 
799e5dd7070Spatrick   template <typename A, typename... Ts>
startsSequenceInternalFormatToken800e5dd7070Spatrick   bool startsSequenceInternal(A K1, Ts... Tokens) const {
801e5dd7070Spatrick     if (is(tok::comment) && Next)
802e5dd7070Spatrick       return Next->startsSequenceInternal(K1, Tokens...);
803e5dd7070Spatrick     return is(K1) && Next && Next->startsSequenceInternal(Tokens...);
804e5dd7070Spatrick   }
805e5dd7070Spatrick 
startsSequenceInternalFormatToken806e5dd7070Spatrick   template <typename A> bool startsSequenceInternal(A K1) const {
807e5dd7070Spatrick     if (is(tok::comment) && Next)
808e5dd7070Spatrick       return Next->startsSequenceInternal(K1);
809e5dd7070Spatrick     return is(K1);
810e5dd7070Spatrick   }
811e5dd7070Spatrick 
endsSequenceInternalFormatToken812e5dd7070Spatrick   template <typename A, typename... Ts> bool endsSequenceInternal(A K1) const {
813e5dd7070Spatrick     if (is(tok::comment) && Previous)
814e5dd7070Spatrick       return Previous->endsSequenceInternal(K1);
815e5dd7070Spatrick     return is(K1);
816e5dd7070Spatrick   }
817e5dd7070Spatrick 
818e5dd7070Spatrick   template <typename A, typename... Ts>
endsSequenceInternalFormatToken819e5dd7070Spatrick   bool endsSequenceInternal(A K1, Ts... Tokens) const {
820e5dd7070Spatrick     if (is(tok::comment) && Previous)
821e5dd7070Spatrick       return Previous->endsSequenceInternal(K1, Tokens...);
822e5dd7070Spatrick     return is(K1) && Previous && Previous->endsSequenceInternal(Tokens...);
823e5dd7070Spatrick   }
824e5dd7070Spatrick };
825e5dd7070Spatrick 
826e5dd7070Spatrick class ContinuationIndenter;
827e5dd7070Spatrick struct LineState;
828e5dd7070Spatrick 
829e5dd7070Spatrick class TokenRole {
830e5dd7070Spatrick public:
TokenRole(const FormatStyle & Style)831e5dd7070Spatrick   TokenRole(const FormatStyle &Style) : Style(Style) {}
832e5dd7070Spatrick   virtual ~TokenRole();
833e5dd7070Spatrick 
834e5dd7070Spatrick   /// After the \c TokenAnnotator has finished annotating all the tokens,
835e5dd7070Spatrick   /// this function precomputes required information for formatting.
836e5dd7070Spatrick   virtual void precomputeFormattingInfos(const FormatToken *Token);
837e5dd7070Spatrick 
838e5dd7070Spatrick   /// Apply the special formatting that the given role demands.
839e5dd7070Spatrick   ///
840e5dd7070Spatrick   /// Assumes that the token having this role is already formatted.
841e5dd7070Spatrick   ///
842e5dd7070Spatrick   /// Continues formatting from \p State leaving indentation to \p Indenter and
843e5dd7070Spatrick   /// returns the total penalty that this formatting incurs.
formatFromToken(LineState & State,ContinuationIndenter * Indenter,bool DryRun)844e5dd7070Spatrick   virtual unsigned formatFromToken(LineState &State,
845e5dd7070Spatrick                                    ContinuationIndenter *Indenter,
846e5dd7070Spatrick                                    bool DryRun) {
847e5dd7070Spatrick     return 0;
848e5dd7070Spatrick   }
849e5dd7070Spatrick 
850e5dd7070Spatrick   /// Same as \c formatFromToken, but assumes that the first token has
851e5dd7070Spatrick   /// already been set thereby deciding on the first line break.
formatAfterToken(LineState & State,ContinuationIndenter * Indenter,bool DryRun)852e5dd7070Spatrick   virtual unsigned formatAfterToken(LineState &State,
853e5dd7070Spatrick                                     ContinuationIndenter *Indenter,
854e5dd7070Spatrick                                     bool DryRun) {
855e5dd7070Spatrick     return 0;
856e5dd7070Spatrick   }
857e5dd7070Spatrick 
858e5dd7070Spatrick   /// Notifies the \c Role that a comma was found.
CommaFound(const FormatToken * Token)859e5dd7070Spatrick   virtual void CommaFound(const FormatToken *Token) {}
860e5dd7070Spatrick 
lastComma()861e5dd7070Spatrick   virtual const FormatToken *lastComma() { return nullptr; }
862e5dd7070Spatrick 
863e5dd7070Spatrick protected:
864e5dd7070Spatrick   const FormatStyle &Style;
865e5dd7070Spatrick };
866e5dd7070Spatrick 
867e5dd7070Spatrick class CommaSeparatedList : public TokenRole {
868e5dd7070Spatrick public:
CommaSeparatedList(const FormatStyle & Style)869e5dd7070Spatrick   CommaSeparatedList(const FormatStyle &Style)
870e5dd7070Spatrick       : TokenRole(Style), HasNestedBracedList(false) {}
871e5dd7070Spatrick 
872e5dd7070Spatrick   void precomputeFormattingInfos(const FormatToken *Token) override;
873e5dd7070Spatrick 
874e5dd7070Spatrick   unsigned formatAfterToken(LineState &State, ContinuationIndenter *Indenter,
875e5dd7070Spatrick                             bool DryRun) override;
876e5dd7070Spatrick 
877e5dd7070Spatrick   unsigned formatFromToken(LineState &State, ContinuationIndenter *Indenter,
878e5dd7070Spatrick                            bool DryRun) override;
879e5dd7070Spatrick 
880e5dd7070Spatrick   /// Adds \p Token as the next comma to the \c CommaSeparated list.
CommaFound(const FormatToken * Token)881e5dd7070Spatrick   void CommaFound(const FormatToken *Token) override {
882e5dd7070Spatrick     Commas.push_back(Token);
883e5dd7070Spatrick   }
884e5dd7070Spatrick 
lastComma()885e5dd7070Spatrick   const FormatToken *lastComma() override {
886e5dd7070Spatrick     if (Commas.empty())
887e5dd7070Spatrick       return nullptr;
888e5dd7070Spatrick     return Commas.back();
889e5dd7070Spatrick   }
890e5dd7070Spatrick 
891e5dd7070Spatrick private:
892e5dd7070Spatrick   /// A struct that holds information on how to format a given list with
893e5dd7070Spatrick   /// a specific number of columns.
894e5dd7070Spatrick   struct ColumnFormat {
895e5dd7070Spatrick     /// The number of columns to use.
896e5dd7070Spatrick     unsigned Columns;
897e5dd7070Spatrick 
898e5dd7070Spatrick     /// The total width in characters.
899e5dd7070Spatrick     unsigned TotalWidth;
900e5dd7070Spatrick 
901e5dd7070Spatrick     /// The number of lines required for this format.
902e5dd7070Spatrick     unsigned LineCount;
903e5dd7070Spatrick 
904e5dd7070Spatrick     /// The size of each column in characters.
905e5dd7070Spatrick     SmallVector<unsigned, 8> ColumnSizes;
906e5dd7070Spatrick   };
907e5dd7070Spatrick 
908e5dd7070Spatrick   /// Calculate which \c ColumnFormat fits best into
909e5dd7070Spatrick   /// \p RemainingCharacters.
910e5dd7070Spatrick   const ColumnFormat *getColumnFormat(unsigned RemainingCharacters) const;
911e5dd7070Spatrick 
912e5dd7070Spatrick   /// The ordered \c FormatTokens making up the commas of this list.
913e5dd7070Spatrick   SmallVector<const FormatToken *, 8> Commas;
914e5dd7070Spatrick 
915e5dd7070Spatrick   /// The length of each of the list's items in characters including the
916e5dd7070Spatrick   /// trailing comma.
917e5dd7070Spatrick   SmallVector<unsigned, 8> ItemLengths;
918e5dd7070Spatrick 
919e5dd7070Spatrick   /// Precomputed formats that can be used for this list.
920e5dd7070Spatrick   SmallVector<ColumnFormat, 4> Formats;
921e5dd7070Spatrick 
922e5dd7070Spatrick   bool HasNestedBracedList;
923e5dd7070Spatrick };
924e5dd7070Spatrick 
925e5dd7070Spatrick /// Encapsulates keywords that are context sensitive or for languages not
926e5dd7070Spatrick /// properly supported by Clang's lexer.
927e5dd7070Spatrick struct AdditionalKeywords {
AdditionalKeywordsAdditionalKeywords928e5dd7070Spatrick   AdditionalKeywords(IdentifierTable &IdentTable) {
929e5dd7070Spatrick     kw_final = &IdentTable.get("final");
930e5dd7070Spatrick     kw_override = &IdentTable.get("override");
931e5dd7070Spatrick     kw_in = &IdentTable.get("in");
932e5dd7070Spatrick     kw_of = &IdentTable.get("of");
933e5dd7070Spatrick     kw_CF_CLOSED_ENUM = &IdentTable.get("CF_CLOSED_ENUM");
934e5dd7070Spatrick     kw_CF_ENUM = &IdentTable.get("CF_ENUM");
935e5dd7070Spatrick     kw_CF_OPTIONS = &IdentTable.get("CF_OPTIONS");
936e5dd7070Spatrick     kw_NS_CLOSED_ENUM = &IdentTable.get("NS_CLOSED_ENUM");
937e5dd7070Spatrick     kw_NS_ENUM = &IdentTable.get("NS_ENUM");
938e5dd7070Spatrick     kw_NS_OPTIONS = &IdentTable.get("NS_OPTIONS");
939e5dd7070Spatrick 
940e5dd7070Spatrick     kw_as = &IdentTable.get("as");
941e5dd7070Spatrick     kw_async = &IdentTable.get("async");
942e5dd7070Spatrick     kw_await = &IdentTable.get("await");
943e5dd7070Spatrick     kw_declare = &IdentTable.get("declare");
944e5dd7070Spatrick     kw_finally = &IdentTable.get("finally");
945e5dd7070Spatrick     kw_from = &IdentTable.get("from");
946e5dd7070Spatrick     kw_function = &IdentTable.get("function");
947e5dd7070Spatrick     kw_get = &IdentTable.get("get");
948e5dd7070Spatrick     kw_import = &IdentTable.get("import");
949e5dd7070Spatrick     kw_infer = &IdentTable.get("infer");
950e5dd7070Spatrick     kw_is = &IdentTable.get("is");
951e5dd7070Spatrick     kw_let = &IdentTable.get("let");
952e5dd7070Spatrick     kw_module = &IdentTable.get("module");
953e5dd7070Spatrick     kw_readonly = &IdentTable.get("readonly");
954e5dd7070Spatrick     kw_set = &IdentTable.get("set");
955e5dd7070Spatrick     kw_type = &IdentTable.get("type");
956e5dd7070Spatrick     kw_typeof = &IdentTable.get("typeof");
957e5dd7070Spatrick     kw_var = &IdentTable.get("var");
958e5dd7070Spatrick     kw_yield = &IdentTable.get("yield");
959e5dd7070Spatrick 
960e5dd7070Spatrick     kw_abstract = &IdentTable.get("abstract");
961e5dd7070Spatrick     kw_assert = &IdentTable.get("assert");
962e5dd7070Spatrick     kw_extends = &IdentTable.get("extends");
963e5dd7070Spatrick     kw_implements = &IdentTable.get("implements");
964e5dd7070Spatrick     kw_instanceof = &IdentTable.get("instanceof");
965e5dd7070Spatrick     kw_interface = &IdentTable.get("interface");
966e5dd7070Spatrick     kw_native = &IdentTable.get("native");
967e5dd7070Spatrick     kw_package = &IdentTable.get("package");
968e5dd7070Spatrick     kw_synchronized = &IdentTable.get("synchronized");
969e5dd7070Spatrick     kw_throws = &IdentTable.get("throws");
970e5dd7070Spatrick     kw___except = &IdentTable.get("__except");
971e5dd7070Spatrick     kw___has_include = &IdentTable.get("__has_include");
972e5dd7070Spatrick     kw___has_include_next = &IdentTable.get("__has_include_next");
973e5dd7070Spatrick 
974e5dd7070Spatrick     kw_mark = &IdentTable.get("mark");
975*12c85518Srobert     kw_region = &IdentTable.get("region");
976e5dd7070Spatrick 
977e5dd7070Spatrick     kw_extend = &IdentTable.get("extend");
978e5dd7070Spatrick     kw_option = &IdentTable.get("option");
979e5dd7070Spatrick     kw_optional = &IdentTable.get("optional");
980e5dd7070Spatrick     kw_repeated = &IdentTable.get("repeated");
981e5dd7070Spatrick     kw_required = &IdentTable.get("required");
982e5dd7070Spatrick     kw_returns = &IdentTable.get("returns");
983e5dd7070Spatrick 
984e5dd7070Spatrick     kw_signals = &IdentTable.get("signals");
985e5dd7070Spatrick     kw_qsignals = &IdentTable.get("Q_SIGNALS");
986e5dd7070Spatrick     kw_slots = &IdentTable.get("slots");
987e5dd7070Spatrick     kw_qslots = &IdentTable.get("Q_SLOTS");
988e5dd7070Spatrick 
989*12c85518Srobert     // For internal clang-format use.
990*12c85518Srobert     kw_internal_ident_after_define =
991*12c85518Srobert         &IdentTable.get("__CLANG_FORMAT_INTERNAL_IDENT_AFTER_DEFINE__");
992*12c85518Srobert 
993e5dd7070Spatrick     // C# keywords
994e5dd7070Spatrick     kw_dollar = &IdentTable.get("dollar");
995e5dd7070Spatrick     kw_base = &IdentTable.get("base");
996e5dd7070Spatrick     kw_byte = &IdentTable.get("byte");
997e5dd7070Spatrick     kw_checked = &IdentTable.get("checked");
998e5dd7070Spatrick     kw_decimal = &IdentTable.get("decimal");
999e5dd7070Spatrick     kw_delegate = &IdentTable.get("delegate");
1000e5dd7070Spatrick     kw_event = &IdentTable.get("event");
1001e5dd7070Spatrick     kw_fixed = &IdentTable.get("fixed");
1002e5dd7070Spatrick     kw_foreach = &IdentTable.get("foreach");
1003*12c85518Srobert     kw_init = &IdentTable.get("init");
1004e5dd7070Spatrick     kw_implicit = &IdentTable.get("implicit");
1005e5dd7070Spatrick     kw_internal = &IdentTable.get("internal");
1006e5dd7070Spatrick     kw_lock = &IdentTable.get("lock");
1007e5dd7070Spatrick     kw_null = &IdentTable.get("null");
1008e5dd7070Spatrick     kw_object = &IdentTable.get("object");
1009e5dd7070Spatrick     kw_out = &IdentTable.get("out");
1010e5dd7070Spatrick     kw_params = &IdentTable.get("params");
1011e5dd7070Spatrick     kw_ref = &IdentTable.get("ref");
1012e5dd7070Spatrick     kw_string = &IdentTable.get("string");
1013e5dd7070Spatrick     kw_stackalloc = &IdentTable.get("stackalloc");
1014e5dd7070Spatrick     kw_sbyte = &IdentTable.get("sbyte");
1015e5dd7070Spatrick     kw_sealed = &IdentTable.get("sealed");
1016e5dd7070Spatrick     kw_uint = &IdentTable.get("uint");
1017e5dd7070Spatrick     kw_ulong = &IdentTable.get("ulong");
1018e5dd7070Spatrick     kw_unchecked = &IdentTable.get("unchecked");
1019e5dd7070Spatrick     kw_unsafe = &IdentTable.get("unsafe");
1020e5dd7070Spatrick     kw_ushort = &IdentTable.get("ushort");
1021ec727ea7Spatrick     kw_when = &IdentTable.get("when");
1022ec727ea7Spatrick     kw_where = &IdentTable.get("where");
1023e5dd7070Spatrick 
1024*12c85518Srobert     // Verilog keywords
1025*12c85518Srobert     kw_always = &IdentTable.get("always");
1026*12c85518Srobert     kw_always_comb = &IdentTable.get("always_comb");
1027*12c85518Srobert     kw_always_ff = &IdentTable.get("always_ff");
1028*12c85518Srobert     kw_always_latch = &IdentTable.get("always_latch");
1029*12c85518Srobert     kw_assign = &IdentTable.get("assign");
1030*12c85518Srobert     kw_assume = &IdentTable.get("assume");
1031*12c85518Srobert     kw_automatic = &IdentTable.get("automatic");
1032*12c85518Srobert     kw_before = &IdentTable.get("before");
1033*12c85518Srobert     kw_begin = &IdentTable.get("begin");
1034*12c85518Srobert     kw_begin_keywords = &IdentTable.get("begin_keywords");
1035*12c85518Srobert     kw_bins = &IdentTable.get("bins");
1036*12c85518Srobert     kw_binsof = &IdentTable.get("binsof");
1037*12c85518Srobert     kw_casex = &IdentTable.get("casex");
1038*12c85518Srobert     kw_casez = &IdentTable.get("casez");
1039*12c85518Srobert     kw_celldefine = &IdentTable.get("celldefine");
1040*12c85518Srobert     kw_checker = &IdentTable.get("checker");
1041*12c85518Srobert     kw_clocking = &IdentTable.get("clocking");
1042*12c85518Srobert     kw_constraint = &IdentTable.get("constraint");
1043*12c85518Srobert     kw_cover = &IdentTable.get("cover");
1044*12c85518Srobert     kw_covergroup = &IdentTable.get("covergroup");
1045*12c85518Srobert     kw_coverpoint = &IdentTable.get("coverpoint");
1046*12c85518Srobert     kw_default_decay_time = &IdentTable.get("default_decay_time");
1047*12c85518Srobert     kw_default_nettype = &IdentTable.get("default_nettype");
1048*12c85518Srobert     kw_default_trireg_strength = &IdentTable.get("default_trireg_strength");
1049*12c85518Srobert     kw_delay_mode_distributed = &IdentTable.get("delay_mode_distributed");
1050*12c85518Srobert     kw_delay_mode_path = &IdentTable.get("delay_mode_path");
1051*12c85518Srobert     kw_delay_mode_unit = &IdentTable.get("delay_mode_unit");
1052*12c85518Srobert     kw_delay_mode_zero = &IdentTable.get("delay_mode_zero");
1053*12c85518Srobert     kw_disable = &IdentTable.get("disable");
1054*12c85518Srobert     kw_dist = &IdentTable.get("dist");
1055*12c85518Srobert     kw_elsif = &IdentTable.get("elsif");
1056*12c85518Srobert     kw_end = &IdentTable.get("end");
1057*12c85518Srobert     kw_end_keywords = &IdentTable.get("end_keywords");
1058*12c85518Srobert     kw_endcase = &IdentTable.get("endcase");
1059*12c85518Srobert     kw_endcelldefine = &IdentTable.get("endcelldefine");
1060*12c85518Srobert     kw_endchecker = &IdentTable.get("endchecker");
1061*12c85518Srobert     kw_endclass = &IdentTable.get("endclass");
1062*12c85518Srobert     kw_endclocking = &IdentTable.get("endclocking");
1063*12c85518Srobert     kw_endfunction = &IdentTable.get("endfunction");
1064*12c85518Srobert     kw_endgenerate = &IdentTable.get("endgenerate");
1065*12c85518Srobert     kw_endgroup = &IdentTable.get("endgroup");
1066*12c85518Srobert     kw_endinterface = &IdentTable.get("endinterface");
1067*12c85518Srobert     kw_endmodule = &IdentTable.get("endmodule");
1068*12c85518Srobert     kw_endpackage = &IdentTable.get("endpackage");
1069*12c85518Srobert     kw_endprimitive = &IdentTable.get("endprimitive");
1070*12c85518Srobert     kw_endprogram = &IdentTable.get("endprogram");
1071*12c85518Srobert     kw_endproperty = &IdentTable.get("endproperty");
1072*12c85518Srobert     kw_endsequence = &IdentTable.get("endsequence");
1073*12c85518Srobert     kw_endspecify = &IdentTable.get("endspecify");
1074*12c85518Srobert     kw_endtable = &IdentTable.get("endtable");
1075*12c85518Srobert     kw_endtask = &IdentTable.get("endtask");
1076*12c85518Srobert     kw_forever = &IdentTable.get("forever");
1077*12c85518Srobert     kw_fork = &IdentTable.get("fork");
1078*12c85518Srobert     kw_generate = &IdentTable.get("generate");
1079*12c85518Srobert     kw_highz0 = &IdentTable.get("highz0");
1080*12c85518Srobert     kw_highz1 = &IdentTable.get("highz1");
1081*12c85518Srobert     kw_iff = &IdentTable.get("iff");
1082*12c85518Srobert     kw_ifnone = &IdentTable.get("ifnone");
1083*12c85518Srobert     kw_ignore_bins = &IdentTable.get("ignore_bins");
1084*12c85518Srobert     kw_illegal_bins = &IdentTable.get("illegal_bins");
1085*12c85518Srobert     kw_initial = &IdentTable.get("initial");
1086*12c85518Srobert     kw_inout = &IdentTable.get("inout");
1087*12c85518Srobert     kw_input = &IdentTable.get("input");
1088*12c85518Srobert     kw_inside = &IdentTable.get("inside");
1089*12c85518Srobert     kw_interconnect = &IdentTable.get("interconnect");
1090*12c85518Srobert     kw_intersect = &IdentTable.get("intersect");
1091*12c85518Srobert     kw_join = &IdentTable.get("join");
1092*12c85518Srobert     kw_join_any = &IdentTable.get("join_any");
1093*12c85518Srobert     kw_join_none = &IdentTable.get("join_none");
1094*12c85518Srobert     kw_large = &IdentTable.get("large");
1095*12c85518Srobert     kw_local = &IdentTable.get("local");
1096*12c85518Srobert     kw_localparam = &IdentTable.get("localparam");
1097*12c85518Srobert     kw_macromodule = &IdentTable.get("macromodule");
1098*12c85518Srobert     kw_matches = &IdentTable.get("matches");
1099*12c85518Srobert     kw_medium = &IdentTable.get("medium");
1100*12c85518Srobert     kw_nounconnected_drive = &IdentTable.get("nounconnected_drive");
1101*12c85518Srobert     kw_output = &IdentTable.get("output");
1102*12c85518Srobert     kw_packed = &IdentTable.get("packed");
1103*12c85518Srobert     kw_parameter = &IdentTable.get("parameter");
1104*12c85518Srobert     kw_primitive = &IdentTable.get("primitive");
1105*12c85518Srobert     kw_priority = &IdentTable.get("priority");
1106*12c85518Srobert     kw_program = &IdentTable.get("program");
1107*12c85518Srobert     kw_property = &IdentTable.get("property");
1108*12c85518Srobert     kw_pull0 = &IdentTable.get("pull0");
1109*12c85518Srobert     kw_pull1 = &IdentTable.get("pull1");
1110*12c85518Srobert     kw_pure = &IdentTable.get("pure");
1111*12c85518Srobert     kw_rand = &IdentTable.get("rand");
1112*12c85518Srobert     kw_randc = &IdentTable.get("randc");
1113*12c85518Srobert     kw_randcase = &IdentTable.get("randcase");
1114*12c85518Srobert     kw_randsequence = &IdentTable.get("randsequence");
1115*12c85518Srobert     kw_repeat = &IdentTable.get("repeat");
1116*12c85518Srobert     kw_resetall = &IdentTable.get("resetall");
1117*12c85518Srobert     kw_sample = &IdentTable.get("sample");
1118*12c85518Srobert     kw_scalared = &IdentTable.get("scalared");
1119*12c85518Srobert     kw_sequence = &IdentTable.get("sequence");
1120*12c85518Srobert     kw_small = &IdentTable.get("small");
1121*12c85518Srobert     kw_soft = &IdentTable.get("soft");
1122*12c85518Srobert     kw_solve = &IdentTable.get("solve");
1123*12c85518Srobert     kw_specify = &IdentTable.get("specify");
1124*12c85518Srobert     kw_specparam = &IdentTable.get("specparam");
1125*12c85518Srobert     kw_strong0 = &IdentTable.get("strong0");
1126*12c85518Srobert     kw_strong1 = &IdentTable.get("strong1");
1127*12c85518Srobert     kw_supply0 = &IdentTable.get("supply0");
1128*12c85518Srobert     kw_supply1 = &IdentTable.get("supply1");
1129*12c85518Srobert     kw_table = &IdentTable.get("table");
1130*12c85518Srobert     kw_tagged = &IdentTable.get("tagged");
1131*12c85518Srobert     kw_task = &IdentTable.get("task");
1132*12c85518Srobert     kw_timescale = &IdentTable.get("timescale");
1133*12c85518Srobert     kw_tri = &IdentTable.get("tri");
1134*12c85518Srobert     kw_tri0 = &IdentTable.get("tri0");
1135*12c85518Srobert     kw_tri1 = &IdentTable.get("tri1");
1136*12c85518Srobert     kw_triand = &IdentTable.get("triand");
1137*12c85518Srobert     kw_trior = &IdentTable.get("trior");
1138*12c85518Srobert     kw_trireg = &IdentTable.get("trireg");
1139*12c85518Srobert     kw_unconnected_drive = &IdentTable.get("unconnected_drive");
1140*12c85518Srobert     kw_undefineall = &IdentTable.get("undefineall");
1141*12c85518Srobert     kw_unique = &IdentTable.get("unique");
1142*12c85518Srobert     kw_unique0 = &IdentTable.get("unique0");
1143*12c85518Srobert     kw_uwire = &IdentTable.get("uwire");
1144*12c85518Srobert     kw_vectored = &IdentTable.get("vectored");
1145*12c85518Srobert     kw_wand = &IdentTable.get("wand");
1146*12c85518Srobert     kw_weak0 = &IdentTable.get("weak0");
1147*12c85518Srobert     kw_weak1 = &IdentTable.get("weak1");
1148*12c85518Srobert     kw_wildcard = &IdentTable.get("wildcard");
1149*12c85518Srobert     kw_wire = &IdentTable.get("wire");
1150*12c85518Srobert     kw_with = &IdentTable.get("with");
1151*12c85518Srobert     kw_wor = &IdentTable.get("wor");
1152*12c85518Srobert 
1153*12c85518Srobert     // Symbols that are treated as keywords.
1154*12c85518Srobert     kw_verilogHash = &IdentTable.get("#");
1155*12c85518Srobert     kw_verilogHashHash = &IdentTable.get("##");
1156*12c85518Srobert     kw_apostrophe = &IdentTable.get("\'");
1157*12c85518Srobert 
1158e5dd7070Spatrick     // Keep this at the end of the constructor to make sure everything here
1159e5dd7070Spatrick     // is
1160e5dd7070Spatrick     // already initialized.
1161e5dd7070Spatrick     JsExtraKeywords = std::unordered_set<IdentifierInfo *>(
1162e5dd7070Spatrick         {kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from,
1163*12c85518Srobert          kw_function, kw_get, kw_import, kw_is, kw_let, kw_module, kw_override,
1164*12c85518Srobert          kw_readonly, kw_set, kw_type, kw_typeof, kw_var, kw_yield,
1165e5dd7070Spatrick          // Keywords from the Java section.
1166e5dd7070Spatrick          kw_abstract, kw_extends, kw_implements, kw_instanceof, kw_interface});
1167e5dd7070Spatrick 
1168e5dd7070Spatrick     CSharpExtraKeywords = std::unordered_set<IdentifierInfo *>(
1169e5dd7070Spatrick         {kw_base, kw_byte, kw_checked, kw_decimal, kw_delegate, kw_event,
1170*12c85518Srobert          kw_fixed, kw_foreach, kw_implicit, kw_in, kw_init, kw_interface,
1171*12c85518Srobert          kw_internal, kw_is, kw_lock, kw_null, kw_object, kw_out, kw_override,
1172*12c85518Srobert          kw_params, kw_readonly, kw_ref, kw_string, kw_stackalloc, kw_sbyte,
1173*12c85518Srobert          kw_sealed, kw_uint, kw_ulong, kw_unchecked, kw_unsafe, kw_ushort,
1174*12c85518Srobert          kw_when, kw_where,
1175e5dd7070Spatrick          // Keywords from the JavaScript section.
1176e5dd7070Spatrick          kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from,
1177e5dd7070Spatrick          kw_function, kw_get, kw_import, kw_is, kw_let, kw_module, kw_readonly,
1178e5dd7070Spatrick          kw_set, kw_type, kw_typeof, kw_var, kw_yield,
1179e5dd7070Spatrick          // Keywords from the Java section.
1180e5dd7070Spatrick          kw_abstract, kw_extends, kw_implements, kw_instanceof, kw_interface});
1181*12c85518Srobert 
1182*12c85518Srobert     // Some keywords are not included here because they don't need special
1183*12c85518Srobert     // treatment like `showcancelled` or they should be treated as identifiers
1184*12c85518Srobert     // like `int` and `logic`.
1185*12c85518Srobert     VerilogExtraKeywords =
1186*12c85518Srobert         std::unordered_set<IdentifierInfo *>({kw_always,
1187*12c85518Srobert                                               kw_always_comb,
1188*12c85518Srobert                                               kw_always_ff,
1189*12c85518Srobert                                               kw_always_latch,
1190*12c85518Srobert                                               kw_assert,
1191*12c85518Srobert                                               kw_assign,
1192*12c85518Srobert                                               kw_assume,
1193*12c85518Srobert                                               kw_automatic,
1194*12c85518Srobert                                               kw_before,
1195*12c85518Srobert                                               kw_begin,
1196*12c85518Srobert                                               kw_bins,
1197*12c85518Srobert                                               kw_binsof,
1198*12c85518Srobert                                               kw_casex,
1199*12c85518Srobert                                               kw_casez,
1200*12c85518Srobert                                               kw_celldefine,
1201*12c85518Srobert                                               kw_checker,
1202*12c85518Srobert                                               kw_clocking,
1203*12c85518Srobert                                               kw_constraint,
1204*12c85518Srobert                                               kw_cover,
1205*12c85518Srobert                                               kw_covergroup,
1206*12c85518Srobert                                               kw_coverpoint,
1207*12c85518Srobert                                               kw_disable,
1208*12c85518Srobert                                               kw_dist,
1209*12c85518Srobert                                               kw_end,
1210*12c85518Srobert                                               kw_endcase,
1211*12c85518Srobert                                               kw_endchecker,
1212*12c85518Srobert                                               kw_endclass,
1213*12c85518Srobert                                               kw_endclocking,
1214*12c85518Srobert                                               kw_endfunction,
1215*12c85518Srobert                                               kw_endgenerate,
1216*12c85518Srobert                                               kw_endgroup,
1217*12c85518Srobert                                               kw_endinterface,
1218*12c85518Srobert                                               kw_endmodule,
1219*12c85518Srobert                                               kw_endpackage,
1220*12c85518Srobert                                               kw_endprimitive,
1221*12c85518Srobert                                               kw_endprogram,
1222*12c85518Srobert                                               kw_endproperty,
1223*12c85518Srobert                                               kw_endsequence,
1224*12c85518Srobert                                               kw_endspecify,
1225*12c85518Srobert                                               kw_endtable,
1226*12c85518Srobert                                               kw_endtask,
1227*12c85518Srobert                                               kw_extends,
1228*12c85518Srobert                                               kw_final,
1229*12c85518Srobert                                               kw_foreach,
1230*12c85518Srobert                                               kw_forever,
1231*12c85518Srobert                                               kw_fork,
1232*12c85518Srobert                                               kw_function,
1233*12c85518Srobert                                               kw_generate,
1234*12c85518Srobert                                               kw_highz0,
1235*12c85518Srobert                                               kw_highz1,
1236*12c85518Srobert                                               kw_iff,
1237*12c85518Srobert                                               kw_ifnone,
1238*12c85518Srobert                                               kw_ignore_bins,
1239*12c85518Srobert                                               kw_illegal_bins,
1240*12c85518Srobert                                               kw_implements,
1241*12c85518Srobert                                               kw_import,
1242*12c85518Srobert                                               kw_initial,
1243*12c85518Srobert                                               kw_inout,
1244*12c85518Srobert                                               kw_input,
1245*12c85518Srobert                                               kw_inside,
1246*12c85518Srobert                                               kw_interconnect,
1247*12c85518Srobert                                               kw_interface,
1248*12c85518Srobert                                               kw_intersect,
1249*12c85518Srobert                                               kw_join,
1250*12c85518Srobert                                               kw_join_any,
1251*12c85518Srobert                                               kw_join_none,
1252*12c85518Srobert                                               kw_large,
1253*12c85518Srobert                                               kw_let,
1254*12c85518Srobert                                               kw_local,
1255*12c85518Srobert                                               kw_localparam,
1256*12c85518Srobert                                               kw_macromodule,
1257*12c85518Srobert                                               kw_matches,
1258*12c85518Srobert                                               kw_medium,
1259*12c85518Srobert                                               kw_output,
1260*12c85518Srobert                                               kw_package,
1261*12c85518Srobert                                               kw_packed,
1262*12c85518Srobert                                               kw_parameter,
1263*12c85518Srobert                                               kw_primitive,
1264*12c85518Srobert                                               kw_priority,
1265*12c85518Srobert                                               kw_program,
1266*12c85518Srobert                                               kw_property,
1267*12c85518Srobert                                               kw_pull0,
1268*12c85518Srobert                                               kw_pull1,
1269*12c85518Srobert                                               kw_pure,
1270*12c85518Srobert                                               kw_rand,
1271*12c85518Srobert                                               kw_randc,
1272*12c85518Srobert                                               kw_randcase,
1273*12c85518Srobert                                               kw_randsequence,
1274*12c85518Srobert                                               kw_ref,
1275*12c85518Srobert                                               kw_repeat,
1276*12c85518Srobert                                               kw_sample,
1277*12c85518Srobert                                               kw_scalared,
1278*12c85518Srobert                                               kw_sequence,
1279*12c85518Srobert                                               kw_small,
1280*12c85518Srobert                                               kw_soft,
1281*12c85518Srobert                                               kw_solve,
1282*12c85518Srobert                                               kw_specify,
1283*12c85518Srobert                                               kw_specparam,
1284*12c85518Srobert                                               kw_strong0,
1285*12c85518Srobert                                               kw_strong1,
1286*12c85518Srobert                                               kw_supply0,
1287*12c85518Srobert                                               kw_supply1,
1288*12c85518Srobert                                               kw_table,
1289*12c85518Srobert                                               kw_tagged,
1290*12c85518Srobert                                               kw_task,
1291*12c85518Srobert                                               kw_tri,
1292*12c85518Srobert                                               kw_tri0,
1293*12c85518Srobert                                               kw_tri1,
1294*12c85518Srobert                                               kw_triand,
1295*12c85518Srobert                                               kw_trior,
1296*12c85518Srobert                                               kw_trireg,
1297*12c85518Srobert                                               kw_unique,
1298*12c85518Srobert                                               kw_unique0,
1299*12c85518Srobert                                               kw_uwire,
1300*12c85518Srobert                                               kw_var,
1301*12c85518Srobert                                               kw_vectored,
1302*12c85518Srobert                                               kw_wand,
1303*12c85518Srobert                                               kw_weak0,
1304*12c85518Srobert                                               kw_weak1,
1305*12c85518Srobert                                               kw_wildcard,
1306*12c85518Srobert                                               kw_wire,
1307*12c85518Srobert                                               kw_with,
1308*12c85518Srobert                                               kw_wor,
1309*12c85518Srobert                                               kw_verilogHash,
1310*12c85518Srobert                                               kw_verilogHashHash});
1311e5dd7070Spatrick   }
1312e5dd7070Spatrick 
1313e5dd7070Spatrick   // Context sensitive keywords.
1314e5dd7070Spatrick   IdentifierInfo *kw_final;
1315e5dd7070Spatrick   IdentifierInfo *kw_override;
1316e5dd7070Spatrick   IdentifierInfo *kw_in;
1317e5dd7070Spatrick   IdentifierInfo *kw_of;
1318e5dd7070Spatrick   IdentifierInfo *kw_CF_CLOSED_ENUM;
1319e5dd7070Spatrick   IdentifierInfo *kw_CF_ENUM;
1320e5dd7070Spatrick   IdentifierInfo *kw_CF_OPTIONS;
1321e5dd7070Spatrick   IdentifierInfo *kw_NS_CLOSED_ENUM;
1322e5dd7070Spatrick   IdentifierInfo *kw_NS_ENUM;
1323e5dd7070Spatrick   IdentifierInfo *kw_NS_OPTIONS;
1324e5dd7070Spatrick   IdentifierInfo *kw___except;
1325e5dd7070Spatrick   IdentifierInfo *kw___has_include;
1326e5dd7070Spatrick   IdentifierInfo *kw___has_include_next;
1327e5dd7070Spatrick 
1328e5dd7070Spatrick   // JavaScript keywords.
1329e5dd7070Spatrick   IdentifierInfo *kw_as;
1330e5dd7070Spatrick   IdentifierInfo *kw_async;
1331e5dd7070Spatrick   IdentifierInfo *kw_await;
1332e5dd7070Spatrick   IdentifierInfo *kw_declare;
1333e5dd7070Spatrick   IdentifierInfo *kw_finally;
1334e5dd7070Spatrick   IdentifierInfo *kw_from;
1335e5dd7070Spatrick   IdentifierInfo *kw_function;
1336e5dd7070Spatrick   IdentifierInfo *kw_get;
1337e5dd7070Spatrick   IdentifierInfo *kw_import;
1338e5dd7070Spatrick   IdentifierInfo *kw_infer;
1339e5dd7070Spatrick   IdentifierInfo *kw_is;
1340e5dd7070Spatrick   IdentifierInfo *kw_let;
1341e5dd7070Spatrick   IdentifierInfo *kw_module;
1342e5dd7070Spatrick   IdentifierInfo *kw_readonly;
1343e5dd7070Spatrick   IdentifierInfo *kw_set;
1344e5dd7070Spatrick   IdentifierInfo *kw_type;
1345e5dd7070Spatrick   IdentifierInfo *kw_typeof;
1346e5dd7070Spatrick   IdentifierInfo *kw_var;
1347e5dd7070Spatrick   IdentifierInfo *kw_yield;
1348e5dd7070Spatrick 
1349e5dd7070Spatrick   // Java keywords.
1350e5dd7070Spatrick   IdentifierInfo *kw_abstract;
1351e5dd7070Spatrick   IdentifierInfo *kw_assert;
1352e5dd7070Spatrick   IdentifierInfo *kw_extends;
1353e5dd7070Spatrick   IdentifierInfo *kw_implements;
1354e5dd7070Spatrick   IdentifierInfo *kw_instanceof;
1355e5dd7070Spatrick   IdentifierInfo *kw_interface;
1356e5dd7070Spatrick   IdentifierInfo *kw_native;
1357e5dd7070Spatrick   IdentifierInfo *kw_package;
1358e5dd7070Spatrick   IdentifierInfo *kw_synchronized;
1359e5dd7070Spatrick   IdentifierInfo *kw_throws;
1360e5dd7070Spatrick 
1361e5dd7070Spatrick   // Pragma keywords.
1362e5dd7070Spatrick   IdentifierInfo *kw_mark;
1363*12c85518Srobert   IdentifierInfo *kw_region;
1364e5dd7070Spatrick 
1365e5dd7070Spatrick   // Proto keywords.
1366e5dd7070Spatrick   IdentifierInfo *kw_extend;
1367e5dd7070Spatrick   IdentifierInfo *kw_option;
1368e5dd7070Spatrick   IdentifierInfo *kw_optional;
1369e5dd7070Spatrick   IdentifierInfo *kw_repeated;
1370e5dd7070Spatrick   IdentifierInfo *kw_required;
1371e5dd7070Spatrick   IdentifierInfo *kw_returns;
1372e5dd7070Spatrick 
1373e5dd7070Spatrick   // QT keywords.
1374e5dd7070Spatrick   IdentifierInfo *kw_signals;
1375e5dd7070Spatrick   IdentifierInfo *kw_qsignals;
1376e5dd7070Spatrick   IdentifierInfo *kw_slots;
1377e5dd7070Spatrick   IdentifierInfo *kw_qslots;
1378e5dd7070Spatrick 
1379*12c85518Srobert   // For internal use by clang-format.
1380*12c85518Srobert   IdentifierInfo *kw_internal_ident_after_define;
1381*12c85518Srobert 
1382e5dd7070Spatrick   // C# keywords
1383e5dd7070Spatrick   IdentifierInfo *kw_dollar;
1384e5dd7070Spatrick   IdentifierInfo *kw_base;
1385e5dd7070Spatrick   IdentifierInfo *kw_byte;
1386e5dd7070Spatrick   IdentifierInfo *kw_checked;
1387e5dd7070Spatrick   IdentifierInfo *kw_decimal;
1388e5dd7070Spatrick   IdentifierInfo *kw_delegate;
1389e5dd7070Spatrick   IdentifierInfo *kw_event;
1390e5dd7070Spatrick   IdentifierInfo *kw_fixed;
1391e5dd7070Spatrick   IdentifierInfo *kw_foreach;
1392e5dd7070Spatrick   IdentifierInfo *kw_implicit;
1393*12c85518Srobert   IdentifierInfo *kw_init;
1394e5dd7070Spatrick   IdentifierInfo *kw_internal;
1395e5dd7070Spatrick 
1396e5dd7070Spatrick   IdentifierInfo *kw_lock;
1397e5dd7070Spatrick   IdentifierInfo *kw_null;
1398e5dd7070Spatrick   IdentifierInfo *kw_object;
1399e5dd7070Spatrick   IdentifierInfo *kw_out;
1400e5dd7070Spatrick 
1401e5dd7070Spatrick   IdentifierInfo *kw_params;
1402e5dd7070Spatrick 
1403e5dd7070Spatrick   IdentifierInfo *kw_ref;
1404e5dd7070Spatrick   IdentifierInfo *kw_string;
1405e5dd7070Spatrick   IdentifierInfo *kw_stackalloc;
1406e5dd7070Spatrick   IdentifierInfo *kw_sbyte;
1407e5dd7070Spatrick   IdentifierInfo *kw_sealed;
1408e5dd7070Spatrick   IdentifierInfo *kw_uint;
1409e5dd7070Spatrick   IdentifierInfo *kw_ulong;
1410e5dd7070Spatrick   IdentifierInfo *kw_unchecked;
1411e5dd7070Spatrick   IdentifierInfo *kw_unsafe;
1412e5dd7070Spatrick   IdentifierInfo *kw_ushort;
1413ec727ea7Spatrick   IdentifierInfo *kw_when;
1414ec727ea7Spatrick   IdentifierInfo *kw_where;
1415e5dd7070Spatrick 
1416*12c85518Srobert   // Verilog keywords
1417*12c85518Srobert   IdentifierInfo *kw_always;
1418*12c85518Srobert   IdentifierInfo *kw_always_comb;
1419*12c85518Srobert   IdentifierInfo *kw_always_ff;
1420*12c85518Srobert   IdentifierInfo *kw_always_latch;
1421*12c85518Srobert   IdentifierInfo *kw_assign;
1422*12c85518Srobert   IdentifierInfo *kw_assume;
1423*12c85518Srobert   IdentifierInfo *kw_automatic;
1424*12c85518Srobert   IdentifierInfo *kw_before;
1425*12c85518Srobert   IdentifierInfo *kw_begin;
1426*12c85518Srobert   IdentifierInfo *kw_begin_keywords;
1427*12c85518Srobert   IdentifierInfo *kw_bins;
1428*12c85518Srobert   IdentifierInfo *kw_binsof;
1429*12c85518Srobert   IdentifierInfo *kw_casex;
1430*12c85518Srobert   IdentifierInfo *kw_casez;
1431*12c85518Srobert   IdentifierInfo *kw_celldefine;
1432*12c85518Srobert   IdentifierInfo *kw_checker;
1433*12c85518Srobert   IdentifierInfo *kw_clocking;
1434*12c85518Srobert   IdentifierInfo *kw_constraint;
1435*12c85518Srobert   IdentifierInfo *kw_cover;
1436*12c85518Srobert   IdentifierInfo *kw_covergroup;
1437*12c85518Srobert   IdentifierInfo *kw_coverpoint;
1438*12c85518Srobert   IdentifierInfo *kw_default_decay_time;
1439*12c85518Srobert   IdentifierInfo *kw_default_nettype;
1440*12c85518Srobert   IdentifierInfo *kw_default_trireg_strength;
1441*12c85518Srobert   IdentifierInfo *kw_delay_mode_distributed;
1442*12c85518Srobert   IdentifierInfo *kw_delay_mode_path;
1443*12c85518Srobert   IdentifierInfo *kw_delay_mode_unit;
1444*12c85518Srobert   IdentifierInfo *kw_delay_mode_zero;
1445*12c85518Srobert   IdentifierInfo *kw_disable;
1446*12c85518Srobert   IdentifierInfo *kw_dist;
1447*12c85518Srobert   IdentifierInfo *kw_elsif;
1448*12c85518Srobert   IdentifierInfo *kw_end;
1449*12c85518Srobert   IdentifierInfo *kw_end_keywords;
1450*12c85518Srobert   IdentifierInfo *kw_endcase;
1451*12c85518Srobert   IdentifierInfo *kw_endcelldefine;
1452*12c85518Srobert   IdentifierInfo *kw_endchecker;
1453*12c85518Srobert   IdentifierInfo *kw_endclass;
1454*12c85518Srobert   IdentifierInfo *kw_endclocking;
1455*12c85518Srobert   IdentifierInfo *kw_endfunction;
1456*12c85518Srobert   IdentifierInfo *kw_endgenerate;
1457*12c85518Srobert   IdentifierInfo *kw_endgroup;
1458*12c85518Srobert   IdentifierInfo *kw_endinterface;
1459*12c85518Srobert   IdentifierInfo *kw_endmodule;
1460*12c85518Srobert   IdentifierInfo *kw_endpackage;
1461*12c85518Srobert   IdentifierInfo *kw_endprimitive;
1462*12c85518Srobert   IdentifierInfo *kw_endprogram;
1463*12c85518Srobert   IdentifierInfo *kw_endproperty;
1464*12c85518Srobert   IdentifierInfo *kw_endsequence;
1465*12c85518Srobert   IdentifierInfo *kw_endspecify;
1466*12c85518Srobert   IdentifierInfo *kw_endtable;
1467*12c85518Srobert   IdentifierInfo *kw_endtask;
1468*12c85518Srobert   IdentifierInfo *kw_forever;
1469*12c85518Srobert   IdentifierInfo *kw_fork;
1470*12c85518Srobert   IdentifierInfo *kw_generate;
1471*12c85518Srobert   IdentifierInfo *kw_highz0;
1472*12c85518Srobert   IdentifierInfo *kw_highz1;
1473*12c85518Srobert   IdentifierInfo *kw_iff;
1474*12c85518Srobert   IdentifierInfo *kw_ifnone;
1475*12c85518Srobert   IdentifierInfo *kw_ignore_bins;
1476*12c85518Srobert   IdentifierInfo *kw_illegal_bins;
1477*12c85518Srobert   IdentifierInfo *kw_initial;
1478*12c85518Srobert   IdentifierInfo *kw_inout;
1479*12c85518Srobert   IdentifierInfo *kw_input;
1480*12c85518Srobert   IdentifierInfo *kw_inside;
1481*12c85518Srobert   IdentifierInfo *kw_interconnect;
1482*12c85518Srobert   IdentifierInfo *kw_intersect;
1483*12c85518Srobert   IdentifierInfo *kw_join;
1484*12c85518Srobert   IdentifierInfo *kw_join_any;
1485*12c85518Srobert   IdentifierInfo *kw_join_none;
1486*12c85518Srobert   IdentifierInfo *kw_large;
1487*12c85518Srobert   IdentifierInfo *kw_local;
1488*12c85518Srobert   IdentifierInfo *kw_localparam;
1489*12c85518Srobert   IdentifierInfo *kw_macromodule;
1490*12c85518Srobert   IdentifierInfo *kw_matches;
1491*12c85518Srobert   IdentifierInfo *kw_medium;
1492*12c85518Srobert   IdentifierInfo *kw_nounconnected_drive;
1493*12c85518Srobert   IdentifierInfo *kw_output;
1494*12c85518Srobert   IdentifierInfo *kw_packed;
1495*12c85518Srobert   IdentifierInfo *kw_parameter;
1496*12c85518Srobert   IdentifierInfo *kw_primitive;
1497*12c85518Srobert   IdentifierInfo *kw_priority;
1498*12c85518Srobert   IdentifierInfo *kw_program;
1499*12c85518Srobert   IdentifierInfo *kw_property;
1500*12c85518Srobert   IdentifierInfo *kw_pull0;
1501*12c85518Srobert   IdentifierInfo *kw_pull1;
1502*12c85518Srobert   IdentifierInfo *kw_pure;
1503*12c85518Srobert   IdentifierInfo *kw_rand;
1504*12c85518Srobert   IdentifierInfo *kw_randc;
1505*12c85518Srobert   IdentifierInfo *kw_randcase;
1506*12c85518Srobert   IdentifierInfo *kw_randsequence;
1507*12c85518Srobert   IdentifierInfo *kw_repeat;
1508*12c85518Srobert   IdentifierInfo *kw_resetall;
1509*12c85518Srobert   IdentifierInfo *kw_sample;
1510*12c85518Srobert   IdentifierInfo *kw_scalared;
1511*12c85518Srobert   IdentifierInfo *kw_sequence;
1512*12c85518Srobert   IdentifierInfo *kw_small;
1513*12c85518Srobert   IdentifierInfo *kw_soft;
1514*12c85518Srobert   IdentifierInfo *kw_solve;
1515*12c85518Srobert   IdentifierInfo *kw_specify;
1516*12c85518Srobert   IdentifierInfo *kw_specparam;
1517*12c85518Srobert   IdentifierInfo *kw_strong0;
1518*12c85518Srobert   IdentifierInfo *kw_strong1;
1519*12c85518Srobert   IdentifierInfo *kw_supply0;
1520*12c85518Srobert   IdentifierInfo *kw_supply1;
1521*12c85518Srobert   IdentifierInfo *kw_table;
1522*12c85518Srobert   IdentifierInfo *kw_tagged;
1523*12c85518Srobert   IdentifierInfo *kw_task;
1524*12c85518Srobert   IdentifierInfo *kw_timescale;
1525*12c85518Srobert   IdentifierInfo *kw_tri0;
1526*12c85518Srobert   IdentifierInfo *kw_tri1;
1527*12c85518Srobert   IdentifierInfo *kw_tri;
1528*12c85518Srobert   IdentifierInfo *kw_triand;
1529*12c85518Srobert   IdentifierInfo *kw_trior;
1530*12c85518Srobert   IdentifierInfo *kw_trireg;
1531*12c85518Srobert   IdentifierInfo *kw_unconnected_drive;
1532*12c85518Srobert   IdentifierInfo *kw_undefineall;
1533*12c85518Srobert   IdentifierInfo *kw_unique;
1534*12c85518Srobert   IdentifierInfo *kw_unique0;
1535*12c85518Srobert   IdentifierInfo *kw_uwire;
1536*12c85518Srobert   IdentifierInfo *kw_vectored;
1537*12c85518Srobert   IdentifierInfo *kw_wand;
1538*12c85518Srobert   IdentifierInfo *kw_weak0;
1539*12c85518Srobert   IdentifierInfo *kw_weak1;
1540*12c85518Srobert   IdentifierInfo *kw_wildcard;
1541*12c85518Srobert   IdentifierInfo *kw_wire;
1542*12c85518Srobert   IdentifierInfo *kw_with;
1543*12c85518Srobert   IdentifierInfo *kw_wor;
1544*12c85518Srobert 
1545*12c85518Srobert   // Workaround for hashes and backticks in Verilog.
1546*12c85518Srobert   IdentifierInfo *kw_verilogHash;
1547*12c85518Srobert   IdentifierInfo *kw_verilogHashHash;
1548*12c85518Srobert 
1549*12c85518Srobert   // Symbols in Verilog that don't exist in C++.
1550*12c85518Srobert   IdentifierInfo *kw_apostrophe;
1551*12c85518Srobert 
1552*12c85518Srobert   /// Returns \c true if \p Tok is a keyword or an identifier.
isWordLikeAdditionalKeywords1553*12c85518Srobert   bool isWordLike(const FormatToken &Tok) const {
1554*12c85518Srobert     // getIdentifierinfo returns non-null for keywords as well as identifiers.
1555*12c85518Srobert     return Tok.Tok.getIdentifierInfo() != nullptr &&
1556*12c85518Srobert            !Tok.isOneOf(kw_verilogHash, kw_verilogHashHash, kw_apostrophe);
1557*12c85518Srobert   }
1558*12c85518Srobert 
1559e5dd7070Spatrick   /// Returns \c true if \p Tok is a true JavaScript identifier, returns
1560e5dd7070Spatrick   /// \c false if it is a keyword or a pseudo keyword.
1561ec727ea7Spatrick   /// If \c AcceptIdentifierName is true, returns true not only for keywords,
1562ec727ea7Spatrick   // but also for IdentifierName tokens (aka pseudo-keywords), such as
1563ec727ea7Spatrick   // ``yield``.
1564ec727ea7Spatrick   bool IsJavaScriptIdentifier(const FormatToken &Tok,
1565ec727ea7Spatrick                               bool AcceptIdentifierName = true) const {
1566ec727ea7Spatrick     // Based on the list of JavaScript & TypeScript keywords here:
1567*12c85518Srobert     // https://github.com/microsoft/TypeScript/blob/main/src/compiler/scanner.ts#L74
1568ec727ea7Spatrick     switch (Tok.Tok.getKind()) {
1569ec727ea7Spatrick     case tok::kw_break:
1570ec727ea7Spatrick     case tok::kw_case:
1571ec727ea7Spatrick     case tok::kw_catch:
1572ec727ea7Spatrick     case tok::kw_class:
1573ec727ea7Spatrick     case tok::kw_continue:
1574ec727ea7Spatrick     case tok::kw_const:
1575ec727ea7Spatrick     case tok::kw_default:
1576ec727ea7Spatrick     case tok::kw_delete:
1577ec727ea7Spatrick     case tok::kw_do:
1578ec727ea7Spatrick     case tok::kw_else:
1579ec727ea7Spatrick     case tok::kw_enum:
1580ec727ea7Spatrick     case tok::kw_export:
1581ec727ea7Spatrick     case tok::kw_false:
1582ec727ea7Spatrick     case tok::kw_for:
1583ec727ea7Spatrick     case tok::kw_if:
1584ec727ea7Spatrick     case tok::kw_import:
1585ec727ea7Spatrick     case tok::kw_module:
1586ec727ea7Spatrick     case tok::kw_new:
1587ec727ea7Spatrick     case tok::kw_private:
1588ec727ea7Spatrick     case tok::kw_protected:
1589ec727ea7Spatrick     case tok::kw_public:
1590ec727ea7Spatrick     case tok::kw_return:
1591ec727ea7Spatrick     case tok::kw_static:
1592ec727ea7Spatrick     case tok::kw_switch:
1593ec727ea7Spatrick     case tok::kw_this:
1594ec727ea7Spatrick     case tok::kw_throw:
1595ec727ea7Spatrick     case tok::kw_true:
1596ec727ea7Spatrick     case tok::kw_try:
1597ec727ea7Spatrick     case tok::kw_typeof:
1598ec727ea7Spatrick     case tok::kw_void:
1599ec727ea7Spatrick     case tok::kw_while:
1600ec727ea7Spatrick       // These are JS keywords that are lexed by LLVM/clang as keywords.
1601ec727ea7Spatrick       return false;
1602ec727ea7Spatrick     case tok::identifier: {
1603ec727ea7Spatrick       // For identifiers, make sure they are true identifiers, excluding the
1604ec727ea7Spatrick       // JavaScript pseudo-keywords (not lexed by LLVM/clang as keywords).
1605ec727ea7Spatrick       bool IsPseudoKeyword =
1606ec727ea7Spatrick           JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) !=
1607e5dd7070Spatrick           JsExtraKeywords.end();
1608ec727ea7Spatrick       return AcceptIdentifierName || !IsPseudoKeyword;
1609ec727ea7Spatrick     }
1610ec727ea7Spatrick     default:
1611ec727ea7Spatrick       // Other keywords are handled in the switch below, to avoid problems due
1612ec727ea7Spatrick       // to duplicate case labels when using the #include trick.
1613ec727ea7Spatrick       break;
1614ec727ea7Spatrick     }
1615ec727ea7Spatrick 
1616ec727ea7Spatrick     switch (Tok.Tok.getKind()) {
1617ec727ea7Spatrick       // Handle C++ keywords not included above: these are all JS identifiers.
1618ec727ea7Spatrick #define KEYWORD(X, Y) case tok::kw_##X:
1619ec727ea7Spatrick #include "clang/Basic/TokenKinds.def"
1620ec727ea7Spatrick       // #undef KEYWORD is not needed -- it's #undef-ed at the end of
1621ec727ea7Spatrick       // TokenKinds.def
1622ec727ea7Spatrick       return true;
1623ec727ea7Spatrick     default:
1624ec727ea7Spatrick       // All other tokens (punctuation etc) are not JS identifiers.
1625ec727ea7Spatrick       return false;
1626ec727ea7Spatrick     }
1627e5dd7070Spatrick   }
1628e5dd7070Spatrick 
1629e5dd7070Spatrick   /// Returns \c true if \p Tok is a C# keyword, returns
1630e5dd7070Spatrick   /// \c false if it is a anything else.
isCSharpKeywordAdditionalKeywords1631e5dd7070Spatrick   bool isCSharpKeyword(const FormatToken &Tok) const {
1632e5dd7070Spatrick     switch (Tok.Tok.getKind()) {
1633e5dd7070Spatrick     case tok::kw_bool:
1634e5dd7070Spatrick     case tok::kw_break:
1635e5dd7070Spatrick     case tok::kw_case:
1636e5dd7070Spatrick     case tok::kw_catch:
1637e5dd7070Spatrick     case tok::kw_char:
1638e5dd7070Spatrick     case tok::kw_class:
1639e5dd7070Spatrick     case tok::kw_const:
1640e5dd7070Spatrick     case tok::kw_continue:
1641e5dd7070Spatrick     case tok::kw_default:
1642e5dd7070Spatrick     case tok::kw_do:
1643e5dd7070Spatrick     case tok::kw_double:
1644e5dd7070Spatrick     case tok::kw_else:
1645e5dd7070Spatrick     case tok::kw_enum:
1646e5dd7070Spatrick     case tok::kw_explicit:
1647e5dd7070Spatrick     case tok::kw_extern:
1648e5dd7070Spatrick     case tok::kw_false:
1649e5dd7070Spatrick     case tok::kw_float:
1650e5dd7070Spatrick     case tok::kw_for:
1651e5dd7070Spatrick     case tok::kw_goto:
1652e5dd7070Spatrick     case tok::kw_if:
1653e5dd7070Spatrick     case tok::kw_int:
1654e5dd7070Spatrick     case tok::kw_long:
1655e5dd7070Spatrick     case tok::kw_namespace:
1656e5dd7070Spatrick     case tok::kw_new:
1657e5dd7070Spatrick     case tok::kw_operator:
1658e5dd7070Spatrick     case tok::kw_private:
1659e5dd7070Spatrick     case tok::kw_protected:
1660e5dd7070Spatrick     case tok::kw_public:
1661e5dd7070Spatrick     case tok::kw_return:
1662e5dd7070Spatrick     case tok::kw_short:
1663e5dd7070Spatrick     case tok::kw_sizeof:
1664e5dd7070Spatrick     case tok::kw_static:
1665e5dd7070Spatrick     case tok::kw_struct:
1666e5dd7070Spatrick     case tok::kw_switch:
1667e5dd7070Spatrick     case tok::kw_this:
1668e5dd7070Spatrick     case tok::kw_throw:
1669e5dd7070Spatrick     case tok::kw_true:
1670e5dd7070Spatrick     case tok::kw_try:
1671e5dd7070Spatrick     case tok::kw_typeof:
1672e5dd7070Spatrick     case tok::kw_using:
1673e5dd7070Spatrick     case tok::kw_virtual:
1674e5dd7070Spatrick     case tok::kw_void:
1675e5dd7070Spatrick     case tok::kw_volatile:
1676e5dd7070Spatrick     case tok::kw_while:
1677e5dd7070Spatrick       return true;
1678e5dd7070Spatrick     default:
1679e5dd7070Spatrick       return Tok.is(tok::identifier) &&
1680e5dd7070Spatrick              CSharpExtraKeywords.find(Tok.Tok.getIdentifierInfo()) ==
1681e5dd7070Spatrick                  CSharpExtraKeywords.end();
1682e5dd7070Spatrick     }
1683e5dd7070Spatrick   }
1684e5dd7070Spatrick 
isVerilogWordOperatorAdditionalKeywords1685*12c85518Srobert   bool isVerilogWordOperator(const FormatToken &Tok) const {
1686*12c85518Srobert     return Tok.isOneOf(kw_before, kw_intersect, kw_dist, kw_iff, kw_inside,
1687*12c85518Srobert                        kw_with);
1688*12c85518Srobert   }
1689*12c85518Srobert 
isVerilogIdentifierAdditionalKeywords1690*12c85518Srobert   bool isVerilogIdentifier(const FormatToken &Tok) const {
1691*12c85518Srobert     switch (Tok.Tok.getKind()) {
1692*12c85518Srobert     case tok::kw_case:
1693*12c85518Srobert     case tok::kw_class:
1694*12c85518Srobert     case tok::kw_const:
1695*12c85518Srobert     case tok::kw_continue:
1696*12c85518Srobert     case tok::kw_default:
1697*12c85518Srobert     case tok::kw_do:
1698*12c85518Srobert     case tok::kw_extern:
1699*12c85518Srobert     case tok::kw_else:
1700*12c85518Srobert     case tok::kw_enum:
1701*12c85518Srobert     case tok::kw_for:
1702*12c85518Srobert     case tok::kw_if:
1703*12c85518Srobert     case tok::kw_restrict:
1704*12c85518Srobert     case tok::kw_signed:
1705*12c85518Srobert     case tok::kw_static:
1706*12c85518Srobert     case tok::kw_struct:
1707*12c85518Srobert     case tok::kw_typedef:
1708*12c85518Srobert     case tok::kw_union:
1709*12c85518Srobert     case tok::kw_unsigned:
1710*12c85518Srobert     case tok::kw_virtual:
1711*12c85518Srobert     case tok::kw_while:
1712*12c85518Srobert       return false;
1713*12c85518Srobert     case tok::identifier:
1714*12c85518Srobert       return VerilogExtraKeywords.find(Tok.Tok.getIdentifierInfo()) ==
1715*12c85518Srobert              VerilogExtraKeywords.end();
1716*12c85518Srobert     default:
1717*12c85518Srobert       // getIdentifierInfo returns non-null for both identifiers and keywords.
1718*12c85518Srobert       return Tok.Tok.getIdentifierInfo() != nullptr;
1719*12c85518Srobert     }
1720*12c85518Srobert   }
1721*12c85518Srobert 
1722*12c85518Srobert   /// Returns whether \p Tok is a Verilog preprocessor directive.  This is
1723*12c85518Srobert   /// needed because macro expansions start with a backtick as well and they
1724*12c85518Srobert   /// need to be treated differently.
isVerilogPPDirectiveAdditionalKeywords1725*12c85518Srobert   bool isVerilogPPDirective(const FormatToken &Tok) const {
1726*12c85518Srobert     auto Info = Tok.Tok.getIdentifierInfo();
1727*12c85518Srobert     if (!Info)
1728*12c85518Srobert       return false;
1729*12c85518Srobert     switch (Info->getPPKeywordID()) {
1730*12c85518Srobert     case tok::pp_define:
1731*12c85518Srobert     case tok::pp_else:
1732*12c85518Srobert     case tok::pp_endif:
1733*12c85518Srobert     case tok::pp_ifdef:
1734*12c85518Srobert     case tok::pp_ifndef:
1735*12c85518Srobert     case tok::pp_include:
1736*12c85518Srobert     case tok::pp_line:
1737*12c85518Srobert     case tok::pp_pragma:
1738*12c85518Srobert     case tok::pp_undef:
1739*12c85518Srobert       return true;
1740*12c85518Srobert     default:
1741*12c85518Srobert       return Tok.isOneOf(kw_begin_keywords, kw_celldefine,
1742*12c85518Srobert                          kw_default_decay_time, kw_default_nettype,
1743*12c85518Srobert                          kw_default_trireg_strength, kw_delay_mode_distributed,
1744*12c85518Srobert                          kw_delay_mode_path, kw_delay_mode_unit,
1745*12c85518Srobert                          kw_delay_mode_zero, kw_elsif, kw_end_keywords,
1746*12c85518Srobert                          kw_endcelldefine, kw_nounconnected_drive, kw_resetall,
1747*12c85518Srobert                          kw_timescale, kw_unconnected_drive, kw_undefineall);
1748*12c85518Srobert     }
1749*12c85518Srobert   }
1750*12c85518Srobert 
1751*12c85518Srobert   /// Returns whether \p Tok is a Verilog keyword that opens a block.
isVerilogBeginAdditionalKeywords1752*12c85518Srobert   bool isVerilogBegin(const FormatToken &Tok) const {
1753*12c85518Srobert     // `table` is not included since it needs to be treated specially.
1754*12c85518Srobert     return !Tok.endsSequence(kw_fork, kw_disable) &&
1755*12c85518Srobert            Tok.isOneOf(kw_begin, kw_fork, kw_generate, kw_specify);
1756*12c85518Srobert   }
1757*12c85518Srobert 
1758*12c85518Srobert   /// Returns whether \p Tok is a Verilog keyword that closes a block.
isVerilogEndAdditionalKeywords1759*12c85518Srobert   bool isVerilogEnd(const FormatToken &Tok) const {
1760*12c85518Srobert     return !Tok.endsSequence(kw_join, kw_rand) &&
1761*12c85518Srobert            Tok.isOneOf(TT_MacroBlockEnd, kw_end, kw_endcase, kw_endclass,
1762*12c85518Srobert                        kw_endclocking, kw_endchecker, kw_endfunction,
1763*12c85518Srobert                        kw_endgenerate, kw_endgroup, kw_endinterface,
1764*12c85518Srobert                        kw_endmodule, kw_endpackage, kw_endprimitive,
1765*12c85518Srobert                        kw_endprogram, kw_endproperty, kw_endsequence,
1766*12c85518Srobert                        kw_endspecify, kw_endtable, kw_endtask, kw_join,
1767*12c85518Srobert                        kw_join_any, kw_join_none);
1768*12c85518Srobert   }
1769*12c85518Srobert 
1770*12c85518Srobert   /// Returns whether \p Tok is a Verilog keyword that opens a module, etc.
isVerilogHierarchyAdditionalKeywords1771*12c85518Srobert   bool isVerilogHierarchy(const FormatToken &Tok) const {
1772*12c85518Srobert     if (Tok.endsSequence(kw_function, kw_with))
1773*12c85518Srobert       return false;
1774*12c85518Srobert     if (Tok.is(kw_property)) {
1775*12c85518Srobert       const FormatToken *Prev = Tok.getPreviousNonComment();
1776*12c85518Srobert       return !(Prev &&
1777*12c85518Srobert                Prev->isOneOf(tok::kw_restrict, kw_assert, kw_assume, kw_cover));
1778*12c85518Srobert     }
1779*12c85518Srobert     return Tok.isOneOf(tok::kw_case, tok::kw_class, kw_function, kw_module,
1780*12c85518Srobert                        kw_interface, kw_package, kw_casex, kw_casez, kw_checker,
1781*12c85518Srobert                        kw_clocking, kw_covergroup, kw_macromodule, kw_primitive,
1782*12c85518Srobert                        kw_program, kw_property, kw_randcase, kw_randsequence,
1783*12c85518Srobert                        kw_task);
1784*12c85518Srobert   }
1785*12c85518Srobert 
isVerilogEndOfLabelAdditionalKeywords1786*12c85518Srobert   bool isVerilogEndOfLabel(const FormatToken &Tok) const {
1787*12c85518Srobert     const FormatToken *Next = Tok.getNextNonComment();
1788*12c85518Srobert     // In Verilog the colon in a default label is optional.
1789*12c85518Srobert     return Tok.is(TT_GotoLabelColon) ||
1790*12c85518Srobert            (Tok.is(tok::kw_default) &&
1791*12c85518Srobert             !(Next && Next->isOneOf(tok::colon, tok::semi, kw_clocking, kw_iff,
1792*12c85518Srobert                                     kw_input, kw_output, kw_sequence)));
1793*12c85518Srobert   }
1794*12c85518Srobert 
1795e5dd7070Spatrick private:
1796e5dd7070Spatrick   /// The JavaScript keywords beyond the C++ keyword set.
1797e5dd7070Spatrick   std::unordered_set<IdentifierInfo *> JsExtraKeywords;
1798e5dd7070Spatrick 
1799e5dd7070Spatrick   /// The C# keywords beyond the C++ keyword set
1800e5dd7070Spatrick   std::unordered_set<IdentifierInfo *> CSharpExtraKeywords;
1801*12c85518Srobert 
1802*12c85518Srobert   /// The Verilog keywords beyond the C++ keyword set.
1803*12c85518Srobert   std::unordered_set<IdentifierInfo *> VerilogExtraKeywords;
1804e5dd7070Spatrick };
1805e5dd7070Spatrick 
1806e5dd7070Spatrick } // namespace format
1807e5dd7070Spatrick } // namespace clang
1808e5dd7070Spatrick 
1809e5dd7070Spatrick #endif
1810