brintos

brintos / llvm-project-archived public Read only

0
0
Text · 83.8 KiB · 56abd70 Raw
2086 lines · c
1//===--- FormatToken.h - Format C++ code ------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the declaration of the FormatToken, a wrapper11/// around Token with additional information related to formatting.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_CLANG_LIB_FORMAT_FORMATTOKEN_H16#define LLVM_CLANG_LIB_FORMAT_FORMATTOKEN_H17 18#include "clang/Basic/IdentifierTable.h"19#include "clang/Basic/OperatorPrecedence.h"20#include "clang/Format/Format.h"21#include "clang/Lex/Lexer.h"22#include <unordered_set>23 24namespace clang {25namespace format {26 27#define LIST_TOKEN_TYPES                                                       \28  TYPE(AfterPPDirective)                                                       \29  TYPE(ArrayInitializerLSquare)                                                \30  TYPE(ArraySubscriptLSquare)                                                  \31  TYPE(AttributeColon)                                                         \32  TYPE(AttributeLParen)                                                        \33  TYPE(AttributeLSquare)                                                       \34  TYPE(AttributeMacro)                                                         \35  TYPE(AttributeRParen)                                                        \36  TYPE(AttributeRSquare)                                                       \37  TYPE(BinaryOperator)                                                         \38  TYPE(BitFieldColon)                                                          \39  TYPE(BlockComment)                                                           \40  /* l_brace of a block that is not the body of a (e.g. loop) statement. */    \41  TYPE(BlockLBrace)                                                            \42  TYPE(BracedListLBrace)                                                       \43  TYPE(CaseLabelArrow)                                                         \44  /* The colon at the end of a case label. */                                  \45  TYPE(CaseLabelColon)                                                         \46  TYPE(CastRParen)                                                             \47  TYPE(ClassLBrace)                                                            \48  /* Name of class/struct/union/interface definition. */                       \49  TYPE(ClassHeadName)                                                          \50  TYPE(ClassRBrace)                                                            \51  TYPE(CompoundRequirementLBrace)                                              \52  /* ternary ?: expression */                                                  \53  TYPE(ConditionalExpr)                                                        \54  /* the condition in an if statement */                                       \55  TYPE(ConditionLParen)                                                        \56  TYPE(ConflictAlternative)                                                    \57  TYPE(ConflictEnd)                                                            \58  TYPE(ConflictStart)                                                          \59  /* l_brace of if/for/while/switch/catch */                                   \60  TYPE(ControlStatementLBrace)                                                 \61  TYPE(ControlStatementRBrace)                                                 \62  TYPE(CppCastLParen)                                                          \63  TYPE(CSharpGenericTypeConstraint)                                            \64  TYPE(CSharpGenericTypeConstraintColon)                                       \65  TYPE(CSharpGenericTypeConstraintComma)                                       \66  TYPE(CSharpNamedArgumentColon)                                               \67  TYPE(CSharpNullable)                                                         \68  TYPE(CSharpNullConditionalLSquare)                                           \69  TYPE(CSharpStringLiteral)                                                    \70  TYPE(CtorInitializerColon)                                                   \71  TYPE(CtorInitializerComma)                                                   \72  TYPE(CtorDtorDeclName)                                                       \73  TYPE(DesignatedInitializerLSquare)                                           \74  TYPE(DesignatedInitializerPeriod)                                            \75  TYPE(DictLiteral)                                                            \76  TYPE(DoWhile)                                                                \77  TYPE(ElseLBrace)                                                             \78  TYPE(ElseRBrace)                                                             \79  TYPE(EnumLBrace)                                                             \80  TYPE(EnumRBrace)                                                             \81  TYPE(FatArrow)                                                               \82  TYPE(ForEachMacro)                                                           \83  TYPE(FunctionAnnotationRParen)                                               \84  TYPE(FunctionDeclarationName)                                                \85  TYPE(FunctionDeclarationLParen)                                              \86  TYPE(FunctionLBrace)                                                         \87  TYPE(FunctionLikeMacro)                                                      \88  TYPE(FunctionLikeOrFreestandingMacro)                                        \89  TYPE(FunctionTypeLParen)                                                     \90  /* The colons as part of a C11 _Generic selection */                         \91  TYPE(GenericSelectionColon)                                                  \92  /* The colon at the end of a goto label. */                                  \93  TYPE(GotoLabelColon)                                                         \94  TYPE(IfMacro)                                                                \95  TYPE(ImplicitStringLiteral)                                                  \96  TYPE(InheritanceColon)                                                       \97  TYPE(InheritanceComma)                                                       \98  TYPE(InlineASMBrace)                                                         \99  TYPE(InlineASMColon)                                                         \100  TYPE(InlineASMSymbolicNameLSquare)                                           \101  TYPE(JavaAnnotation)                                                         \102  TYPE(JsAndAndEqual)                                                          \103  TYPE(JsComputedPropertyName)                                                 \104  TYPE(JsExponentiation)                                                       \105  TYPE(JsExponentiationEqual)                                                  \106  TYPE(JsPipePipeEqual)                                                        \107  TYPE(JsPrivateIdentifier)                                                    \108  TYPE(JsTypeColon)                                                            \109  TYPE(JsTypeOperator)                                                         \110  TYPE(JsTypeOptionalQuestion)                                                 \111  TYPE(LambdaArrow)                                                            \112  TYPE(LambdaDefinitionLParen)                                                 \113  TYPE(LambdaLBrace)                                                           \114  TYPE(LambdaLSquare)                                                          \115  TYPE(LeadingJavaAnnotation)                                                  \116  TYPE(LineComment)                                                            \117  TYPE(MacroBlockBegin)                                                        \118  TYPE(MacroBlockEnd)                                                          \119  TYPE(ModulePartitionColon)                                                   \120  TYPE(NamespaceLBrace)                                                        \121  TYPE(NamespaceMacro)                                                         \122  TYPE(NamespaceRBrace)                                                        \123  TYPE(NonNullAssertion)                                                       \124  TYPE(NullCoalescingEqual)                                                    \125  TYPE(NullCoalescingOperator)                                                 \126  TYPE(NullPropagatingOperator)                                                \127  TYPE(ObjCBlockLBrace)                                                        \128  TYPE(ObjCBlockLParen)                                                        \129  TYPE(ObjCDecl)                                                               \130  TYPE(ObjCForIn)                                                              \131  /* The square brackets surrounding a method call, the colon separating the   \132   * method or parameter name and the argument inside the square brackets, and \133   * the colon separating the method or parameter name and the type inside the \134   * method declaration. */                                                    \135  TYPE(ObjCMethodExpr)                                                         \136  /* The '+' or '-' at the start of the line. */                               \137  TYPE(ObjCMethodSpecifier)                                                    \138  TYPE(ObjCProperty)                                                           \139  /* The parentheses following '@selector' and the colon following the method  \140   * or parameter name inside the parentheses. */                              \141  TYPE(ObjCSelector)                                                           \142  TYPE(ObjCStringLiteral)                                                      \143  TYPE(OverloadedOperator)                                                     \144  TYPE(OverloadedOperatorLParen)                                               \145  TYPE(PointerOrReference)                                                     \146  TYPE(ProtoExtensionLSquare)                                                  \147  TYPE(PureVirtualSpecifier)                                                   \148  TYPE(QtProperty)                                                             \149  TYPE(RangeBasedForLoopColon)                                                 \150  TYPE(RecordLBrace)                                                           \151  TYPE(RecordRBrace)                                                           \152  TYPE(RegexLiteral)                                                           \153  TYPE(RequiresClause)                                                         \154  TYPE(RequiresClauseInARequiresExpression)                                    \155  TYPE(RequiresExpression)                                                     \156  TYPE(RequiresExpressionLBrace)                                               \157  TYPE(RequiresExpressionLParen)                                               \158  /* The hash key in languages that have hash literals, not including the      \159   * field name in the C++ struct literal. Also the method or parameter name   \160   * in the Objective-C method declaration or call. */                         \161  TYPE(SelectorName)                                                           \162  TYPE(StartOfName)                                                            \163  TYPE(StatementAttributeLikeMacro)                                            \164  TYPE(StatementMacro)                                                         \165  /* A string that is part of a string concatenation. For C#, JavaScript, and  \166   * Java, it is used for marking whether a string needs parentheses around it \167   * if it is to be split into parts joined by `+`. For Verilog, whether       \168   * braces need to be added to split it. Not used for other languages. */     \169  TYPE(StringInConcatenation)                                                  \170  TYPE(StructLBrace)                                                           \171  TYPE(StructRBrace)                                                           \172  TYPE(StructuredBindingLSquare)                                               \173  TYPE(SwitchExpressionLabel)                                                  \174  TYPE(SwitchExpressionLBrace)                                                 \175  TYPE(TableGenBangOperator)                                                   \176  TYPE(TableGenCondOperator)                                                   \177  TYPE(TableGenCondOperatorColon)                                              \178  TYPE(TableGenCondOperatorComma)                                              \179  TYPE(TableGenDAGArgCloser)                                                   \180  TYPE(TableGenDAGArgListColon)                                                \181  TYPE(TableGenDAGArgListColonToAlign)                                         \182  TYPE(TableGenDAGArgListComma)                                                \183  TYPE(TableGenDAGArgListCommaToBreak)                                         \184  TYPE(TableGenDAGArgOpener)                                                   \185  TYPE(TableGenDAGArgOpenerToBreak)                                            \186  TYPE(TableGenDAGArgOperatorID)                                               \187  TYPE(TableGenDAGArgOperatorToBreak)                                          \188  TYPE(TableGenListCloser)                                                     \189  TYPE(TableGenListOpener)                                                     \190  TYPE(TableGenMultiLineString)                                                \191  TYPE(TableGenTrailingPasteOperator)                                          \192  TYPE(TableGenValueSuffix)                                                    \193  TYPE(TemplateCloser)                                                         \194  TYPE(TemplateOpener)                                                         \195  TYPE(TemplateString)                                                         \196  TYPE(TrailingAnnotation)                                                     \197  TYPE(TrailingReturnArrow)                                                    \198  TYPE(TrailingUnaryOperator)                                                  \199  TYPE(TypeDeclarationParen)                                                   \200  TYPE(TemplateName)                                                           \201  TYPE(TypeName)                                                               \202  TYPE(TypenameMacro)                                                          \203  TYPE(UnaryOperator)                                                          \204  TYPE(UnionLBrace)                                                            \205  TYPE(UnionRBrace)                                                            \206  TYPE(UntouchableMacroFunc)                                                   \207  TYPE(VariableTemplate)                                                       \208  /* Like in 'assign x = 0, y = 1;' . */                                       \209  TYPE(VerilogAssignComma)                                                     \210  /* like in begin : block */                                                  \211  TYPE(VerilogBlockLabelColon)                                                 \212  /* The square bracket for the dimension part of the type name.               \213   * In 'logic [1:0] x[1:0]', only the first '['. This way we can have space   \214   * before the first bracket but not the second. */                           \215  TYPE(VerilogDimensionedTypeName)                                             \216  /* list of port connections or parameters in a module instantiation */       \217  TYPE(VerilogInstancePortComma)                                               \218  TYPE(VerilogInstancePortLParen)                                              \219  /* A parenthesized list within which line breaks are inserted by the         \220   * formatter, for example the list of ports in a module header. */           \221  TYPE(VerilogMultiLineListLParen)                                             \222  /* for the base in a number literal, not including the quote */              \223  TYPE(VerilogNumberBase)                                                      \224  /* like `(strong1, pull0)` */                                                \225  TYPE(VerilogStrength)                                                        \226  /* Things inside the table in user-defined primitives. */                    \227  TYPE(VerilogTableItem)                                                       \228  /* those that separate ports of different types */                           \229  TYPE(VerilogTypeComma)                                                       \230  TYPE(Unknown)231 232/// Determines the semantic type of a syntactic token, e.g. whether "<" is a233/// template opener or binary operator.234enum TokenType : uint8_t {235#define TYPE(X) TT_##X,236  LIST_TOKEN_TYPES237#undef TYPE238      NUM_TOKEN_TYPES239};240 241/// Determines the name of a token type.242const char *getTokenTypeName(TokenType Type);243 244// Represents what type of block a set of braces open.245enum BraceBlockKind { BK_Unknown, BK_Block, BK_BracedInit };246 247// The packing kind of a function's parameters.248enum ParameterPackingKind { PPK_BinPacked, PPK_OnePerLine, PPK_Inconclusive };249 250enum FormatDecision { FD_Unformatted, FD_Continue, FD_Break };251 252/// Roles a token can take in a configured macro expansion.253enum MacroRole {254  /// The token was expanded from a macro argument when formatting the expanded255  /// token sequence.256  MR_ExpandedArg,257  /// The token is part of a macro argument that was previously formatted as258  /// expansion when formatting the unexpanded macro call.259  MR_UnexpandedArg,260  /// The token was expanded from a macro definition, and is not visible as part261  /// of the macro call.262  MR_Hidden,263};264 265struct FormatToken;266 267/// Contains information on the token's role in a macro expansion.268///269/// Given the following definitions:270/// A(X) = [ X ]271/// B(X) = < X >272/// C(X) = X273///274/// Consider the macro call:275/// A({B(C(C(x)))}) -> [{<x>}]276///277/// In this case, the tokens of the unexpanded macro call will have the278/// following relevant entries in their macro context (note that formatting279/// the unexpanded macro call happens *after* formatting the expanded macro280/// call):281///                   A( { B( C( C(x) ) ) } )282/// Role:             NN U NN NN NNUN N N U N  (N=None, U=UnexpandedArg)283///284///                   [  { <       x    > } ]285/// Role:             H  E H       E    H E H  (H=Hidden, E=ExpandedArg)286/// ExpandedFrom[0]:  A  A A       A    A A A287/// ExpandedFrom[1]:       B       B    B288/// ExpandedFrom[2]:               C289/// ExpandedFrom[3]:               C290/// StartOfExpansion: 1  0 1       2    0 0 0291/// EndOfExpansion:   0  0 0       2    1 0 1292struct MacroExpansion {293  MacroExpansion(MacroRole Role) : Role(Role) {}294 295  /// The token's role in the macro expansion.296  /// When formatting an expanded macro, all tokens that are part of macro297  /// arguments will be MR_ExpandedArg, while all tokens that are not visible in298  /// the macro call will be MR_Hidden.299  /// When formatting an unexpanded macro call, all tokens that are part of300  /// macro arguments will be MR_UnexpandedArg.301  MacroRole Role;302 303  /// The stack of macro call identifier tokens this token was expanded from.304  llvm::SmallVector<FormatToken *, 1> ExpandedFrom;305 306  /// The number of expansions of which this macro is the first entry.307  unsigned StartOfExpansion = 0;308 309  /// The number of currently open expansions in \c ExpandedFrom this macro is310  /// the last token in.311  unsigned EndOfExpansion = 0;312};313 314class TokenRole;315class AnnotatedLine;316 317/// A wrapper around a \c Token storing information about the318/// whitespace characters preceding it.319struct FormatToken {320  FormatToken()321      : HasUnescapedNewline(false), IsMultiline(false), IsFirst(false),322        MustBreakBefore(false), MustBreakBeforeFinalized(false),323        IsUnterminatedLiteral(false), CanBreakBefore(false),324        ClosesTemplateDeclaration(false), StartsBinaryExpression(false),325        EndsBinaryExpression(false), PartOfMultiVariableDeclStmt(false),326        ContinuesLineCommentSection(false), Finalized(false),327        ClosesRequiresClause(false), EndsCppAttributeGroup(false),328        BlockKind(BK_Unknown), Decision(FD_Unformatted),329        PackingKind(PPK_Inconclusive), TypeIsFinalized(false),330        Type(TT_Unknown) {}331 332  /// The \c Token.333  Token Tok;334 335  /// The raw text of the token.336  ///337  /// Contains the raw token text without leading whitespace and without leading338  /// escaped newlines.339  StringRef TokenText;340 341  /// A token can have a special role that can carry extra information342  /// about the token's formatting.343  /// FIXME: Make FormatToken for parsing and AnnotatedToken two different344  /// classes and make this a unique_ptr in the AnnotatedToken class.345  std::shared_ptr<TokenRole> Role;346 347  /// The range of the whitespace immediately preceding the \c Token.348  SourceRange WhitespaceRange;349 350  /// Whether there is at least one unescaped newline before the \c351  /// Token.352  unsigned HasUnescapedNewline : 1;353 354  /// Whether the token text contains newlines (escaped or not).355  unsigned IsMultiline : 1;356 357  /// Indicates that this is the first token of the file.358  unsigned IsFirst : 1;359 360  /// Whether there must be a line break before this token.361  ///362  /// This happens for example when a preprocessor directive ended directly363  /// before the token.364  unsigned MustBreakBefore : 1;365 366  /// Whether MustBreakBefore is finalized during parsing and must not367  /// be reset between runs.368  unsigned MustBreakBeforeFinalized : 1;369 370  /// Set to \c true if this token is an unterminated literal.371  unsigned IsUnterminatedLiteral : 1;372 373  /// \c true if it is allowed to break before this token.374  unsigned CanBreakBefore : 1;375 376  /// \c true if this is the ">" of "template<..>".377  unsigned ClosesTemplateDeclaration : 1;378 379  /// \c true if this token starts a binary expression, i.e. has at least380  /// one fake l_paren with a precedence greater than prec::Unknown.381  unsigned StartsBinaryExpression : 1;382  /// \c true if this token ends a binary expression.383  unsigned EndsBinaryExpression : 1;384 385  /// Is this token part of a \c DeclStmt defining multiple variables?386  ///387  /// Only set if \c Type == \c TT_StartOfName.388  unsigned PartOfMultiVariableDeclStmt : 1;389 390  /// Does this line comment continue a line comment section?391  ///392  /// Only set to true if \c Type == \c TT_LineComment.393  unsigned ContinuesLineCommentSection : 1;394 395  /// If \c true, this token has been fully formatted (indented and396  /// potentially re-formatted inside), and we do not allow further formatting397  /// changes.398  unsigned Finalized : 1;399 400  /// \c true if this is the last token within requires clause.401  unsigned ClosesRequiresClause : 1;402 403  /// \c true if this token ends a group of C++ attributes.404  unsigned EndsCppAttributeGroup : 1;405 406private:407  /// Contains the kind of block if this token is a brace.408  unsigned BlockKind : 2;409 410public:411  BraceBlockKind getBlockKind() const {412    return static_cast<BraceBlockKind>(BlockKind);413  }414  void setBlockKind(BraceBlockKind BBK) {415    BlockKind = BBK;416    assert(getBlockKind() == BBK && "BraceBlockKind overflow!");417  }418 419private:420  /// Stores the formatting decision for the token once it was made.421  unsigned Decision : 2;422 423public:424  FormatDecision getDecision() const {425    return static_cast<FormatDecision>(Decision);426  }427  void setDecision(FormatDecision D) {428    Decision = D;429    assert(getDecision() == D && "FormatDecision overflow!");430  }431 432private:433  /// If this is an opening parenthesis, how are the parameters packed?434  unsigned PackingKind : 2;435 436public:437  ParameterPackingKind getPackingKind() const {438    return static_cast<ParameterPackingKind>(PackingKind);439  }440  void setPackingKind(ParameterPackingKind K) {441    PackingKind = K;442    assert(getPackingKind() == K && "ParameterPackingKind overflow!");443  }444 445private:446  unsigned TypeIsFinalized : 1;447  TokenType Type;448 449public:450  /// Returns the token's type, e.g. whether "<" is a template opener or451  /// binary operator.452  TokenType getType() const { return Type; }453  void setType(TokenType T) {454    // If this token is a macro argument while formatting an unexpanded macro455    // call, we do not change its type any more - the type was deduced from456    // formatting the expanded macro stream already.457    if (MacroCtx && MacroCtx->Role == MR_UnexpandedArg)458      return;459    assert((!TypeIsFinalized || T == Type) &&460           "Please use overwriteFixedType to change a fixed type.");461    Type = T;462  }463  /// Sets the type and also the finalized flag. This prevents the type to be464  /// reset in TokenAnnotator::resetTokenMetadata(). If the type needs to be set465  /// to another one please use overwriteFixedType, or even better remove the466  /// need to reassign the type.467  void setFinalizedType(TokenType T) {468    if (MacroCtx && MacroCtx->Role == MR_UnexpandedArg)469      return;470    Type = T;471    TypeIsFinalized = true;472  }473  void overwriteFixedType(TokenType T) {474    if (MacroCtx && MacroCtx->Role == MR_UnexpandedArg)475      return;476    TypeIsFinalized = false;477    setType(T);478  }479  bool isTypeFinalized() const { return TypeIsFinalized; }480 481  /// Used to set an operator precedence explicitly.482  prec::Level ForcedPrecedence = prec::Unknown;483 484  /// The number of newlines immediately before the \c Token.485  ///486  /// This can be used to determine what the user wrote in the original code487  /// and thereby e.g. leave an empty line between two function definitions.488  unsigned NewlinesBefore = 0;489 490  /// The number of newlines immediately before the \c Token after formatting.491  ///492  /// This is used to avoid overlapping whitespace replacements when \c Newlines493  /// is recomputed for a finalized preprocessor branching directive.494  int Newlines = -1;495 496  /// The offset just past the last '\n' in this token's leading497  /// whitespace (relative to \c WhiteSpaceStart). 0 if there is no '\n'.498  unsigned LastNewlineOffset = 0;499 500  /// The width of the non-whitespace parts of the token (or its first501  /// line for multi-line tokens) in columns.502  /// We need this to correctly measure number of columns a token spans.503  unsigned ColumnWidth = 0;504 505  /// Contains the width in columns of the last line of a multi-line506  /// token.507  unsigned LastLineColumnWidth = 0;508 509  /// The number of spaces that should be inserted before this token.510  unsigned SpacesRequiredBefore = 0;511 512  /// Number of parameters, if this is "(", "[" or "<".513  unsigned ParameterCount = 0;514 515  /// Number of parameters that are nested blocks,516  /// if this is "(", "[" or "<".517  unsigned BlockParameterCount = 0;518 519  /// If this is a bracket ("<", "(", "[" or "{"), contains the kind of520  /// the surrounding bracket.521  tok::TokenKind ParentBracket = tok::unknown;522 523  /// The total length of the unwrapped line up to and including this524  /// token.525  unsigned TotalLength = 0;526 527  /// The original 0-based column of this token, including expanded tabs.528  /// The configured TabWidth is used as tab width.529  unsigned OriginalColumn = 0;530 531  /// The length of following tokens until the next natural split point,532  /// or the next token that can be broken.533  unsigned UnbreakableTailLength = 0;534 535  // FIXME: Come up with a 'cleaner' concept.536  /// The binding strength of a token. This is a combined value of537  /// operator precedence, parenthesis nesting, etc.538  unsigned BindingStrength = 0;539 540  /// The nesting level of this token, i.e. the number of surrounding (),541  /// [], {} or <>.542  unsigned NestingLevel = 0;543 544  /// The indent level of this token. Copied from the surrounding line.545  unsigned IndentLevel = 0;546 547  /// Penalty for inserting a line break before this token.548  unsigned SplitPenalty = 0;549 550  /// If this is the first ObjC selector name in an ObjC method551  /// definition or call, this contains the length of the longest name.552  ///553  /// This being set to 0 means that the selectors should not be colon-aligned,554  /// e.g. because several of them are block-type.555  unsigned LongestObjCSelectorName = 0;556 557  /// If this is the first ObjC selector name in an ObjC method558  /// definition or call, this contains the number of parts that the whole559  /// selector consist of.560  unsigned ObjCSelectorNameParts = 0;561 562  /// The 0-based index of the parameter/argument. For ObjC it is set563  /// for the selector name token.564  /// For now calculated only for ObjC.565  unsigned ParameterIndex = 0;566 567  /// Stores the number of required fake parentheses and the568  /// corresponding operator precedence.569  ///570  /// If multiple fake parentheses start at a token, this vector stores them in571  /// reverse order, i.e. inner fake parenthesis first.572  SmallVector<prec::Level, 4> FakeLParens;573  /// Insert this many fake ) after this token for correct indentation.574  unsigned FakeRParens = 0;575 576  /// If this is an operator (or "."/"->") in a sequence of operators577  /// with the same precedence, contains the 0-based operator index.578  unsigned OperatorIndex = 0;579 580  /// If this is an operator (or "."/"->") in a sequence of operators581  /// with the same precedence, points to the next operator.582  FormatToken *NextOperator = nullptr;583 584  /// If this is a bracket, this points to the matching one.585  FormatToken *MatchingParen = nullptr;586 587  /// The previous token in the unwrapped line.588  FormatToken *Previous = nullptr;589 590  /// The next token in the unwrapped line.591  FormatToken *Next = nullptr;592 593  /// The first token in set of column elements.594  bool StartsColumn = false;595 596  /// This notes the start of the line of an array initializer.597  bool ArrayInitializerLineStart = false;598 599  /// This starts an array initializer.600  bool IsArrayInitializer = false;601 602  /// Is optional and can be removed.603  bool Optional = false;604 605  /// Might be function declaration open/closing paren.606  bool MightBeFunctionDeclParen = false;607 608  /// Has "\n\f\n" or "\n\f\r\n" before TokenText.609  bool HasFormFeedBefore = false;610 611  /// Is the first token after a preprocessor line.612  bool FirstAfterPPLine = false;613 614  /// Number of optional braces to be inserted after this token:615  ///   -1: a single left brace616  ///    0: no braces617  ///   >0: number of right braces618  int8_t BraceCount = 0;619 620  /// If this token starts a block, this contains all the unwrapped lines621  /// in it.622  SmallVector<AnnotatedLine *, 1> Children;623 624  // Contains all attributes related to how this token takes part625  // in a configured macro expansion.626  std::optional<MacroExpansion> MacroCtx;627 628  /// When macro expansion introduces nodes with children, those are marked as629  /// \c MacroParent.630  /// FIXME: The formatting code currently hard-codes the assumption that631  /// child nodes are introduced by blocks following an opening brace.632  /// This is deeply baked into the code and disentangling this will require633  /// signficant refactorings. \c MacroParent allows us to special-case the634  /// cases in which we treat parents as block-openers for now.635  bool MacroParent = false;636 637  bool is(tok::TokenKind Kind) const { return Tok.is(Kind); }638  bool is(tok::ObjCKeywordKind Kind) const {639    return Tok.getObjCKeywordID() == Kind;640  }641  bool is(TokenType TT) const { return getType() == TT; }642  bool is(const IdentifierInfo *II) const {643    return II && II == Tok.getIdentifierInfo();644  }645  bool is(tok::PPKeywordKind Kind) const {646    return Tok.getIdentifierInfo() &&647           Tok.getIdentifierInfo()->getPPKeywordID() == Kind;648  }649  bool is(BraceBlockKind BBK) const { return getBlockKind() == BBK; }650  bool is(ParameterPackingKind PPK) const { return getPackingKind() == PPK; }651 652  template <typename A, typename B> bool isOneOf(A K1, B K2) const {653    return is(K1) || is(K2);654  }655  template <typename A, typename B, typename... Ts>656  bool isOneOf(A K1, B K2, Ts... Ks) const {657    return is(K1) || isOneOf(K2, Ks...);658  }659  template <typename T> bool isNot(T Kind) const { return !is(Kind); }660  template <typename... Ts> bool isNoneOf(Ts... Ks) const {661    return !isOneOf(Ks...);662  }663 664  bool isIf(bool AllowConstexprMacro = true) const {665    return is(tok::kw_if) || endsSequence(tok::kw_constexpr, tok::kw_if) ||666           (endsSequence(tok::identifier, tok::kw_if) && AllowConstexprMacro);667  }668 669  bool isLoop(const FormatStyle &Style) const {670    return isOneOf(tok::kw_for, tok::kw_while) ||671           (Style.isJavaScript() && isNot(tok::l_paren) && Previous &&672            Previous->is(tok::kw_for));673  }674 675  bool closesScopeAfterBlock() const {676    if (getBlockKind() == BK_Block)677      return true;678    if (closesScope())679      return Previous->closesScopeAfterBlock();680    return false;681  }682 683  /// \c true if this token starts a sequence with the given tokens in order,684  /// following the ``Next`` pointers, ignoring comments.685  template <typename A, typename... Ts>686  bool startsSequence(A K1, Ts... Tokens) const {687    return startsSequenceInternal(K1, Tokens...);688  }689 690  /// \c true if this token ends a sequence with the given tokens in order,691  /// following the ``Previous`` pointers, ignoring comments.692  /// For example, given tokens [T1, T2, T3], the function returns true if693  /// 3 tokens ending at this (ignoring comments) are [T3, T2, T1]. In other694  /// words, the tokens passed to this function need to the reverse of the695  /// order the tokens appear in code.696  template <typename A, typename... Ts>697  bool endsSequence(A K1, Ts... Tokens) const {698    return endsSequenceInternal(K1, Tokens...);699  }700 701  bool isStringLiteral() const { return tok::isStringLiteral(Tok.getKind()); }702 703  bool isAttribute() const {704    return isOneOf(tok::kw___attribute, tok::kw___declspec, TT_AttributeMacro);705  }706 707  bool isAccessSpecifierKeyword() const {708    return isOneOf(tok::kw_public, tok::kw_protected, tok::kw_private);709  }710 711  bool isAccessSpecifier(bool ColonRequired = true) const {712    if (!isAccessSpecifierKeyword())713      return false;714    if (!ColonRequired)715      return true;716    const auto *NextNonComment = getNextNonComment();717    return NextNonComment && NextNonComment->is(tok::colon);718  }719 720  bool canBePointerOrReferenceQualifier() const {721    return isOneOf(tok::kw_const, tok::kw_restrict, tok::kw_volatile,722                   tok::kw__Nonnull, tok::kw__Nullable,723                   tok::kw__Null_unspecified, tok::kw___ptr32, tok::kw___ptr64,724                   tok::kw___funcref) ||725           isAttribute();726  }727 728  [[nodiscard]] bool isQtProperty() const;729  [[nodiscard]] bool isTypeName(const LangOptions &LangOpts) const;730  [[nodiscard]] bool isTypeOrIdentifier(const LangOptions &LangOpts) const;731 732  bool isObjCAccessSpecifier() const {733    return is(tok::at) && Next &&734           Next->isOneOf(tok::objc_public, tok::objc_protected,735                         tok::objc_package, tok::objc_private);736  }737 738  bool isObjCLifetimeQualifier(const FormatStyle &Style) const {739    if (Style.Language != FormatStyle::LK_ObjC || isNot(tok::identifier) ||740        !TokenText.starts_with("__")) {741      return false;742    }743    const auto Qualifier = TokenText.substr(2);744    return Qualifier == "autoreleasing" || Qualifier == "strong" ||745           Qualifier == "weak" || Qualifier == "unsafe_unretained";746  }747 748  /// Returns whether \p Tok is ([{ or an opening < of a template or in749  /// protos.750  bool opensScope() const {751    if (is(TT_TemplateString) && TokenText.ends_with("${"))752      return true;753    if (is(TT_DictLiteral) && is(tok::less))754      return true;755    return isOneOf(tok::l_paren, tok::l_brace, tok::l_square,756                   TT_TemplateOpener);757  }758  /// Returns whether \p Tok is )]} or a closing > of a template or in759  /// protos.760  bool closesScope() const {761    if (is(TT_TemplateString) && TokenText.starts_with("}"))762      return true;763    if (is(TT_DictLiteral) && is(tok::greater))764      return true;765    return isOneOf(tok::r_paren, tok::r_brace, tok::r_square,766                   TT_TemplateCloser);767  }768 769  /// Returns \c true if this is a "." or "->" accessing a member.770  bool isMemberAccess() const {771    return isOneOf(tok::arrow, tok::period, tok::arrowstar) &&772           isNoneOf(TT_DesignatedInitializerPeriod, TT_TrailingReturnArrow,773                    TT_LambdaArrow, TT_LeadingJavaAnnotation);774  }775 776  bool isPointerOrReference() const {777    return isOneOf(tok::star, tok::amp, tok::ampamp);778  }779 780  bool isPlacementOperator() const {781    return isOneOf(tok::kw_new, tok::kw_delete);782  }783 784  bool isUnaryOperator() const {785    switch (Tok.getKind()) {786    case tok::plus:787    case tok::plusplus:788    case tok::minus:789    case tok::minusminus:790    case tok::exclaim:791    case tok::tilde:792    case tok::kw_sizeof:793    case tok::kw_alignof:794      return true;795    default:796      return false;797    }798  }799 800  bool isBinaryOperator() const {801    // Comma is a binary operator, but does not behave as such wrt. formatting.802    return getPrecedence() > prec::Comma;803  }804 805  bool isTrailingComment() const {806    return is(tok::comment) &&807           (is(TT_LineComment) || !Next || Next->NewlinesBefore > 0);808  }809 810  /// Returns \c true if this is a keyword that can be used811  /// like a function call (e.g. sizeof, typeid, ...).812  bool isFunctionLikeKeyword() const {813    if (isAttribute())814      return true;815 816    return isOneOf(tok::kw_throw, tok::kw_typeid, tok::kw_return,817                   tok::kw_sizeof, tok::kw_alignof, tok::kw_alignas,818                   tok::kw_decltype, tok::kw_noexcept, tok::kw_static_assert,819                   tok::kw__Atomic,820#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,821#include "clang/Basic/TransformTypeTraits.def"822                   tok::kw_requires);823  }824 825  /// Returns \c true if this is a string literal that's like a label,826  /// e.g. ends with "=" or ":".827  bool isLabelString() const {828    if (isNot(tok::string_literal))829      return false;830    StringRef Content = TokenText;831    if (Content.starts_with("\"") || Content.starts_with("'"))832      Content = Content.drop_front(1);833    if (Content.ends_with("\"") || Content.ends_with("'"))834      Content = Content.drop_back(1);835    Content = Content.trim();836    return Content.size() > 1 &&837           (Content.back() == ':' || Content.back() == '=');838  }839 840  /// Returns actual token start location without leading escaped841  /// newlines and whitespace.842  ///843  /// This can be different to Tok.getLocation(), which includes leading escaped844  /// newlines.845  SourceLocation getStartOfNonWhitespace() const {846    return WhitespaceRange.getEnd();847  }848 849  /// Returns \c true if the range of whitespace immediately preceding the \c850  /// Token is not empty.851  bool hasWhitespaceBefore() const {852    return WhitespaceRange.getBegin() != WhitespaceRange.getEnd();853  }854 855  prec::Level getPrecedence() const {856    if (ForcedPrecedence != prec::Unknown)857      return ForcedPrecedence;858    return getBinOpPrecedence(Tok.getKind(), /*GreaterThanIsOperator=*/true,859                              /*CPlusPlus11=*/true);860  }861 862  /// Returns the previous token ignoring comments.863  [[nodiscard]] FormatToken *getPreviousNonComment() const {864    FormatToken *Tok = Previous;865    while (Tok && Tok->is(tok::comment))866      Tok = Tok->Previous;867    return Tok;868  }869 870  /// Returns the next token ignoring comments.871  [[nodiscard]] FormatToken *getNextNonComment() const {872    FormatToken *Tok = Next;873    while (Tok && Tok->is(tok::comment))874      Tok = Tok->Next;875    return Tok;876  }877 878  /// Returns \c true if this token ends a block indented initializer list.879  [[nodiscard]] bool isBlockIndentedInitRBrace(const FormatStyle &Style) const;880 881  /// Returns \c true if this tokens starts a block-type list, i.e. a882  /// list that should be indented with a block indent.883  [[nodiscard]] bool opensBlockOrBlockTypeList(const FormatStyle &Style) const;884 885  /// Returns whether the token is the left square bracket of a C++886  /// structured binding declaration.887  bool isCppStructuredBinding(bool IsCpp) const {888    if (!IsCpp || isNot(tok::l_square))889      return false;890    const FormatToken *T = this;891    do {892      T = T->getPreviousNonComment();893    } while (T && T->isOneOf(tok::kw_const, tok::kw_volatile, tok::amp,894                             tok::ampamp));895    return T && T->is(tok::kw_auto);896  }897 898  /// Same as opensBlockOrBlockTypeList, but for the closing token.899  bool closesBlockOrBlockTypeList(const FormatStyle &Style) const {900    if (is(TT_TemplateString) && closesScope())901      return true;902    return MatchingParen && MatchingParen->opensBlockOrBlockTypeList(Style);903  }904 905  /// Return the actual namespace token, if this token starts a namespace906  /// block.907  const FormatToken *getNamespaceToken() const {908    const FormatToken *NamespaceTok = this;909    if (is(tok::comment))910      NamespaceTok = NamespaceTok->getNextNonComment();911    // Detect "(inline|export)? namespace" in the beginning of a line.912    if (NamespaceTok && NamespaceTok->isOneOf(tok::kw_inline, tok::kw_export))913      NamespaceTok = NamespaceTok->getNextNonComment();914    return NamespaceTok &&915                   NamespaceTok->isOneOf(tok::kw_namespace, TT_NamespaceMacro)916               ? NamespaceTok917               : nullptr;918  }919 920  void copyFrom(const FormatToken &Tok) { *this = Tok; }921 922private:923  // Only allow copying via the explicit copyFrom method.924  FormatToken(const FormatToken &) = delete;925  FormatToken &operator=(const FormatToken &) = default;926 927  template <typename A, typename... Ts>928  bool startsSequenceInternal(A K1, Ts... Tokens) const {929    if (is(tok::comment) && Next)930      return Next->startsSequenceInternal(K1, Tokens...);931    return is(K1) && Next && Next->startsSequenceInternal(Tokens...);932  }933 934  template <typename A> bool startsSequenceInternal(A K1) const {935    if (is(tok::comment) && Next)936      return Next->startsSequenceInternal(K1);937    return is(K1);938  }939 940  template <typename A, typename... Ts> bool endsSequenceInternal(A K1) const {941    if (is(tok::comment) && Previous)942      return Previous->endsSequenceInternal(K1);943    return is(K1);944  }945 946  template <typename A, typename... Ts>947  bool endsSequenceInternal(A K1, Ts... Tokens) const {948    if (is(tok::comment) && Previous)949      return Previous->endsSequenceInternal(K1, Tokens...);950    return is(K1) && Previous && Previous->endsSequenceInternal(Tokens...);951  }952};953 954class ContinuationIndenter;955struct LineState;956 957class TokenRole {958public:959  TokenRole(const FormatStyle &Style) : Style(Style) {}960  virtual ~TokenRole();961 962  /// After the \c TokenAnnotator has finished annotating all the tokens,963  /// this function precomputes required information for formatting.964  virtual void precomputeFormattingInfos(const FormatToken *Token);965 966  /// Apply the special formatting that the given role demands.967  ///968  /// Assumes that the token having this role is already formatted.969  ///970  /// Continues formatting from \p State leaving indentation to \p Indenter and971  /// returns the total penalty that this formatting incurs.972  virtual unsigned formatFromToken(LineState &State,973                                   ContinuationIndenter *Indenter,974                                   bool DryRun) {975    return 0;976  }977 978  /// Same as \c formatFromToken, but assumes that the first token has979  /// already been set thereby deciding on the first line break.980  virtual unsigned formatAfterToken(LineState &State,981                                    ContinuationIndenter *Indenter,982                                    bool DryRun) {983    return 0;984  }985 986  /// Notifies the \c Role that a comma was found.987  virtual void CommaFound(const FormatToken *Token) {}988 989  virtual const FormatToken *lastComma() { return nullptr; }990 991protected:992  const FormatStyle &Style;993};994 995class CommaSeparatedList : public TokenRole {996public:997  CommaSeparatedList(const FormatStyle &Style)998      : TokenRole(Style), HasNestedBracedList(false) {}999 1000  void precomputeFormattingInfos(const FormatToken *Token) override;1001 1002  unsigned formatAfterToken(LineState &State, ContinuationIndenter *Indenter,1003                            bool DryRun) override;1004 1005  unsigned formatFromToken(LineState &State, ContinuationIndenter *Indenter,1006                           bool DryRun) override;1007 1008  /// Adds \p Token as the next comma to the \c CommaSeparated list.1009  void CommaFound(const FormatToken *Token) override {1010    Commas.push_back(Token);1011  }1012 1013  const FormatToken *lastComma() override {1014    if (Commas.empty())1015      return nullptr;1016    return Commas.back();1017  }1018 1019private:1020  /// A struct that holds information on how to format a given list with1021  /// a specific number of columns.1022  struct ColumnFormat {1023    /// The number of columns to use.1024    unsigned Columns;1025 1026    /// The total width in characters.1027    unsigned TotalWidth;1028 1029    /// The number of lines required for this format.1030    unsigned LineCount;1031 1032    /// The size of each column in characters.1033    SmallVector<unsigned, 8> ColumnSizes;1034  };1035 1036  /// Calculate which \c ColumnFormat fits best into1037  /// \p RemainingCharacters.1038  const ColumnFormat *getColumnFormat(unsigned RemainingCharacters) const;1039 1040  /// The ordered \c FormatTokens making up the commas of this list.1041  SmallVector<const FormatToken *, 8> Commas;1042 1043  /// The length of each of the list's items in characters including the1044  /// trailing comma.1045  SmallVector<unsigned, 8> ItemLengths;1046 1047  /// Precomputed formats that can be used for this list.1048  SmallVector<ColumnFormat, 4> Formats;1049 1050  bool HasNestedBracedList;1051};1052 1053/// Encapsulates keywords that are context sensitive or for languages not1054/// properly supported by Clang's lexer.1055struct AdditionalKeywords {1056  AdditionalKeywords(IdentifierTable &IdentTable) {1057    kw_final = &IdentTable.get("final");1058    kw_override = &IdentTable.get("override");1059    kw_in = &IdentTable.get("in");1060    kw_of = &IdentTable.get("of");1061    kw_CF_CLOSED_ENUM = &IdentTable.get("CF_CLOSED_ENUM");1062    kw_CF_ENUM = &IdentTable.get("CF_ENUM");1063    kw_CF_OPTIONS = &IdentTable.get("CF_OPTIONS");1064    kw_NS_CLOSED_ENUM = &IdentTable.get("NS_CLOSED_ENUM");1065    kw_NS_ENUM = &IdentTable.get("NS_ENUM");1066    kw_NS_ERROR_ENUM = &IdentTable.get("NS_ERROR_ENUM");1067    kw_NS_OPTIONS = &IdentTable.get("NS_OPTIONS");1068 1069    kw_as = &IdentTable.get("as");1070    kw_async = &IdentTable.get("async");1071    kw_await = &IdentTable.get("await");1072    kw_declare = &IdentTable.get("declare");1073    kw_finally = &IdentTable.get("finally");1074    kw_from = &IdentTable.get("from");1075    kw_function = &IdentTable.get("function");1076    kw_get = &IdentTable.get("get");1077    kw_import = &IdentTable.get("import");1078    kw_infer = &IdentTable.get("infer");1079    kw_is = &IdentTable.get("is");1080    kw_let = &IdentTable.get("let");1081    kw_module = &IdentTable.get("module");1082    kw_readonly = &IdentTable.get("readonly");1083    kw_set = &IdentTable.get("set");1084    kw_type = &IdentTable.get("type");1085    kw_typeof = &IdentTable.get("typeof");1086    kw_var = &IdentTable.get("var");1087    kw_yield = &IdentTable.get("yield");1088 1089    kw_abstract = &IdentTable.get("abstract");1090    kw_assert = &IdentTable.get("assert");1091    kw_extends = &IdentTable.get("extends");1092    kw_implements = &IdentTable.get("implements");1093    kw_instanceof = &IdentTable.get("instanceof");1094    kw_interface = &IdentTable.get("interface");1095    kw_native = &IdentTable.get("native");1096    kw_package = &IdentTable.get("package");1097    kw_record = &IdentTable.get("record");1098    kw_synchronized = &IdentTable.get("synchronized");1099    kw_throws = &IdentTable.get("throws");1100    kw___except = &IdentTable.get("__except");1101    kw___has_include = &IdentTable.get("__has_include");1102    kw___has_include_next = &IdentTable.get("__has_include_next");1103 1104    kw_mark = &IdentTable.get("mark");1105    kw_region = &IdentTable.get("region");1106 1107    kw_extend = &IdentTable.get("extend");1108    kw_option = &IdentTable.get("option");1109    kw_optional = &IdentTable.get("optional");1110    kw_repeated = &IdentTable.get("repeated");1111    kw_required = &IdentTable.get("required");1112    kw_returns = &IdentTable.get("returns");1113 1114    kw_signals = &IdentTable.get("signals");1115    kw_qsignals = &IdentTable.get("Q_SIGNALS");1116    kw_slots = &IdentTable.get("slots");1117    kw_qslots = &IdentTable.get("Q_SLOTS");1118 1119    // For internal clang-format use.1120    kw_internal_ident_after_define =1121        &IdentTable.get("__CLANG_FORMAT_INTERNAL_IDENT_AFTER_DEFINE__");1122 1123    // C# keywords1124    kw_dollar = &IdentTable.get("dollar");1125    kw_base = &IdentTable.get("base");1126    kw_byte = &IdentTable.get("byte");1127    kw_checked = &IdentTable.get("checked");1128    kw_decimal = &IdentTable.get("decimal");1129    kw_delegate = &IdentTable.get("delegate");1130    kw_event = &IdentTable.get("event");1131    kw_fixed = &IdentTable.get("fixed");1132    kw_foreach = &IdentTable.get("foreach");1133    kw_init = &IdentTable.get("init");1134    kw_implicit = &IdentTable.get("implicit");1135    kw_internal = &IdentTable.get("internal");1136    kw_lock = &IdentTable.get("lock");1137    kw_null = &IdentTable.get("null");1138    kw_object = &IdentTable.get("object");1139    kw_out = &IdentTable.get("out");1140    kw_params = &IdentTable.get("params");1141    kw_ref = &IdentTable.get("ref");1142    kw_string = &IdentTable.get("string");1143    kw_stackalloc = &IdentTable.get("stackalloc");1144    kw_sbyte = &IdentTable.get("sbyte");1145    kw_sealed = &IdentTable.get("sealed");1146    kw_uint = &IdentTable.get("uint");1147    kw_ulong = &IdentTable.get("ulong");1148    kw_unchecked = &IdentTable.get("unchecked");1149    kw_unsafe = &IdentTable.get("unsafe");1150    kw_ushort = &IdentTable.get("ushort");1151    kw_when = &IdentTable.get("when");1152    kw_where = &IdentTable.get("where");1153 1154    // Verilog keywords1155    kw_always = &IdentTable.get("always");1156    kw_always_comb = &IdentTable.get("always_comb");1157    kw_always_ff = &IdentTable.get("always_ff");1158    kw_always_latch = &IdentTable.get("always_latch");1159    kw_assign = &IdentTable.get("assign");1160    kw_assume = &IdentTable.get("assume");1161    kw_automatic = &IdentTable.get("automatic");1162    kw_before = &IdentTable.get("before");1163    kw_begin = &IdentTable.get("begin");1164    kw_begin_keywords = &IdentTable.get("begin_keywords");1165    kw_bins = &IdentTable.get("bins");1166    kw_binsof = &IdentTable.get("binsof");1167    kw_casex = &IdentTable.get("casex");1168    kw_casez = &IdentTable.get("casez");1169    kw_celldefine = &IdentTable.get("celldefine");1170    kw_checker = &IdentTable.get("checker");1171    kw_clocking = &IdentTable.get("clocking");1172    kw_constraint = &IdentTable.get("constraint");1173    kw_context = &IdentTable.get("context");1174    kw_cover = &IdentTable.get("cover");1175    kw_covergroup = &IdentTable.get("covergroup");1176    kw_coverpoint = &IdentTable.get("coverpoint");1177    kw_default_decay_time = &IdentTable.get("default_decay_time");1178    kw_default_nettype = &IdentTable.get("default_nettype");1179    kw_default_trireg_strength = &IdentTable.get("default_trireg_strength");1180    kw_delay_mode_distributed = &IdentTable.get("delay_mode_distributed");1181    kw_delay_mode_path = &IdentTable.get("delay_mode_path");1182    kw_delay_mode_unit = &IdentTable.get("delay_mode_unit");1183    kw_delay_mode_zero = &IdentTable.get("delay_mode_zero");1184    kw_disable = &IdentTable.get("disable");1185    kw_dist = &IdentTable.get("dist");1186    kw_edge = &IdentTable.get("edge");1187    kw_elsif = &IdentTable.get("elsif");1188    kw_end = &IdentTable.get("end");1189    kw_end_keywords = &IdentTable.get("end_keywords");1190    kw_endcase = &IdentTable.get("endcase");1191    kw_endcelldefine = &IdentTable.get("endcelldefine");1192    kw_endchecker = &IdentTable.get("endchecker");1193    kw_endclass = &IdentTable.get("endclass");1194    kw_endclocking = &IdentTable.get("endclocking");1195    kw_endfunction = &IdentTable.get("endfunction");1196    kw_endgenerate = &IdentTable.get("endgenerate");1197    kw_endgroup = &IdentTable.get("endgroup");1198    kw_endinterface = &IdentTable.get("endinterface");1199    kw_endmodule = &IdentTable.get("endmodule");1200    kw_endpackage = &IdentTable.get("endpackage");1201    kw_endprimitive = &IdentTable.get("endprimitive");1202    kw_endprogram = &IdentTable.get("endprogram");1203    kw_endproperty = &IdentTable.get("endproperty");1204    kw_endsequence = &IdentTable.get("endsequence");1205    kw_endspecify = &IdentTable.get("endspecify");1206    kw_endtable = &IdentTable.get("endtable");1207    kw_endtask = &IdentTable.get("endtask");1208    kw_forever = &IdentTable.get("forever");1209    kw_fork = &IdentTable.get("fork");1210    kw_generate = &IdentTable.get("generate");1211    kw_highz0 = &IdentTable.get("highz0");1212    kw_highz1 = &IdentTable.get("highz1");1213    kw_iff = &IdentTable.get("iff");1214    kw_ifnone = &IdentTable.get("ifnone");1215    kw_ignore_bins = &IdentTable.get("ignore_bins");1216    kw_illegal_bins = &IdentTable.get("illegal_bins");1217    kw_initial = &IdentTable.get("initial");1218    kw_inout = &IdentTable.get("inout");1219    kw_input = &IdentTable.get("input");1220    kw_inside = &IdentTable.get("inside");1221    kw_interconnect = &IdentTable.get("interconnect");1222    kw_intersect = &IdentTable.get("intersect");1223    kw_join = &IdentTable.get("join");1224    kw_join_any = &IdentTable.get("join_any");1225    kw_join_none = &IdentTable.get("join_none");1226    kw_large = &IdentTable.get("large");1227    kw_local = &IdentTable.get("local");1228    kw_localparam = &IdentTable.get("localparam");1229    kw_macromodule = &IdentTable.get("macromodule");1230    kw_matches = &IdentTable.get("matches");1231    kw_medium = &IdentTable.get("medium");1232    kw_negedge = &IdentTable.get("negedge");1233    kw_nounconnected_drive = &IdentTable.get("nounconnected_drive");1234    kw_output = &IdentTable.get("output");1235    kw_packed = &IdentTable.get("packed");1236    kw_parameter = &IdentTable.get("parameter");1237    kw_posedge = &IdentTable.get("posedge");1238    kw_primitive = &IdentTable.get("primitive");1239    kw_priority = &IdentTable.get("priority");1240    kw_program = &IdentTable.get("program");1241    kw_property = &IdentTable.get("property");1242    kw_pull0 = &IdentTable.get("pull0");1243    kw_pull1 = &IdentTable.get("pull1");1244    kw_pure = &IdentTable.get("pure");1245    kw_rand = &IdentTable.get("rand");1246    kw_randc = &IdentTable.get("randc");1247    kw_randcase = &IdentTable.get("randcase");1248    kw_randsequence = &IdentTable.get("randsequence");1249    kw_repeat = &IdentTable.get("repeat");1250    kw_resetall = &IdentTable.get("resetall");1251    kw_sample = &IdentTable.get("sample");1252    kw_scalared = &IdentTable.get("scalared");1253    kw_sequence = &IdentTable.get("sequence");1254    kw_small = &IdentTable.get("small");1255    kw_soft = &IdentTable.get("soft");1256    kw_solve = &IdentTable.get("solve");1257    kw_specify = &IdentTable.get("specify");1258    kw_specparam = &IdentTable.get("specparam");1259    kw_strong0 = &IdentTable.get("strong0");1260    kw_strong1 = &IdentTable.get("strong1");1261    kw_supply0 = &IdentTable.get("supply0");1262    kw_supply1 = &IdentTable.get("supply1");1263    kw_table = &IdentTable.get("table");1264    kw_tagged = &IdentTable.get("tagged");1265    kw_task = &IdentTable.get("task");1266    kw_timescale = &IdentTable.get("timescale");1267    kw_tri = &IdentTable.get("tri");1268    kw_tri0 = &IdentTable.get("tri0");1269    kw_tri1 = &IdentTable.get("tri1");1270    kw_triand = &IdentTable.get("triand");1271    kw_trior = &IdentTable.get("trior");1272    kw_trireg = &IdentTable.get("trireg");1273    kw_unconnected_drive = &IdentTable.get("unconnected_drive");1274    kw_undefineall = &IdentTable.get("undefineall");1275    kw_unique = &IdentTable.get("unique");1276    kw_unique0 = &IdentTable.get("unique0");1277    kw_uwire = &IdentTable.get("uwire");1278    kw_vectored = &IdentTable.get("vectored");1279    kw_wait = &IdentTable.get("wait");1280    kw_wand = &IdentTable.get("wand");1281    kw_weak0 = &IdentTable.get("weak0");1282    kw_weak1 = &IdentTable.get("weak1");1283    kw_wildcard = &IdentTable.get("wildcard");1284    kw_wire = &IdentTable.get("wire");1285    kw_with = &IdentTable.get("with");1286    kw_wor = &IdentTable.get("wor");1287 1288    // Symbols that are treated as keywords.1289    kw_verilogHash = &IdentTable.get("#");1290    kw_verilogHashHash = &IdentTable.get("##");1291    kw_apostrophe = &IdentTable.get("\'");1292 1293    // TableGen keywords.1294    kw_bit = &IdentTable.get("bit");1295    kw_bits = &IdentTable.get("bits");1296    kw_code = &IdentTable.get("code");1297    kw_dag = &IdentTable.get("dag");1298    kw_def = &IdentTable.get("def");1299    kw_defm = &IdentTable.get("defm");1300    kw_defset = &IdentTable.get("defset");1301    kw_defvar = &IdentTable.get("defvar");1302    kw_dump = &IdentTable.get("dump");1303    kw_include = &IdentTable.get("include");1304    kw_list = &IdentTable.get("list");1305    kw_multiclass = &IdentTable.get("multiclass");1306    kw_then = &IdentTable.get("then");1307 1308    // Keep this at the end of the constructor to make sure everything here is1309    // already initialized.1310    JsExtraKeywords = std::unordered_set<IdentifierInfo *>(1311        {kw_as, kw_async, kw_await, kw_declare, kw_finally, kw_from,1312         kw_function, kw_get, kw_import, kw_is, kw_let, kw_module, kw_override,1313         kw_readonly, kw_set, kw_type, kw_typeof, kw_var, kw_yield,1314         // Keywords from the Java section.1315         kw_abstract, kw_extends, kw_implements, kw_instanceof, kw_interface});1316 1317    CSharpExtraKeywords = JsExtraKeywords;1318    CSharpExtraKeywords.insert(1319        {kw_base,   kw_byte,     kw_checked, kw_decimal,  kw_delegate,1320         kw_event,  kw_fixed,    kw_foreach, kw_implicit, kw_in,1321         kw_init,   kw_internal, kw_lock,    kw_null,     kw_object,1322         kw_out,    kw_params,   kw_ref,     kw_string,   kw_stackalloc,1323         kw_sbyte,  kw_sealed,   kw_uint,    kw_ulong,    kw_unchecked,1324         kw_unsafe, kw_ushort,   kw_when,    kw_where});1325 1326    // Some keywords are not included here because they don't need special1327    // treatment like `showcancelled` or they should be treated as identifiers1328    // like `int` and `logic`.1329    VerilogExtraKeywords =1330        std::unordered_set<IdentifierInfo *>({kw_always,1331                                              kw_always_comb,1332                                              kw_always_ff,1333                                              kw_always_latch,1334                                              kw_assert,1335                                              kw_assign,1336                                              kw_assume,1337                                              kw_automatic,1338                                              kw_before,1339                                              kw_begin,1340                                              kw_bins,1341                                              kw_binsof,1342                                              kw_casex,1343                                              kw_casez,1344                                              kw_celldefine,1345                                              kw_checker,1346                                              kw_clocking,1347                                              kw_constraint,1348                                              kw_context,1349                                              kw_cover,1350                                              kw_covergroup,1351                                              kw_coverpoint,1352                                              kw_disable,1353                                              kw_dist,1354                                              kw_edge,1355                                              kw_end,1356                                              kw_endcase,1357                                              kw_endchecker,1358                                              kw_endclass,1359                                              kw_endclocking,1360                                              kw_endfunction,1361                                              kw_endgenerate,1362                                              kw_endgroup,1363                                              kw_endinterface,1364                                              kw_endmodule,1365                                              kw_endpackage,1366                                              kw_endprimitive,1367                                              kw_endprogram,1368                                              kw_endproperty,1369                                              kw_endsequence,1370                                              kw_endspecify,1371                                              kw_endtable,1372                                              kw_endtask,1373                                              kw_extends,1374                                              kw_final,1375                                              kw_foreach,1376                                              kw_forever,1377                                              kw_fork,1378                                              kw_function,1379                                              kw_generate,1380                                              kw_highz0,1381                                              kw_highz1,1382                                              kw_iff,1383                                              kw_ifnone,1384                                              kw_ignore_bins,1385                                              kw_illegal_bins,1386                                              kw_implements,1387                                              kw_import,1388                                              kw_initial,1389                                              kw_inout,1390                                              kw_input,1391                                              kw_inside,1392                                              kw_interconnect,1393                                              kw_interface,1394                                              kw_intersect,1395                                              kw_join,1396                                              kw_join_any,1397                                              kw_join_none,1398                                              kw_large,1399                                              kw_let,1400                                              kw_local,1401                                              kw_localparam,1402                                              kw_macromodule,1403                                              kw_matches,1404                                              kw_medium,1405                                              kw_module,1406                                              kw_negedge,1407                                              kw_output,1408                                              kw_package,1409                                              kw_packed,1410                                              kw_parameter,1411                                              kw_posedge,1412                                              kw_primitive,1413                                              kw_priority,1414                                              kw_program,1415                                              kw_property,1416                                              kw_pull0,1417                                              kw_pull1,1418                                              kw_pure,1419                                              kw_rand,1420                                              kw_randc,1421                                              kw_randcase,1422                                              kw_randsequence,1423                                              kw_ref,1424                                              kw_repeat,1425                                              kw_sample,1426                                              kw_scalared,1427                                              kw_sequence,1428                                              kw_small,1429                                              kw_soft,1430                                              kw_solve,1431                                              kw_specify,1432                                              kw_specparam,1433                                              kw_strong0,1434                                              kw_strong1,1435                                              kw_supply0,1436                                              kw_supply1,1437                                              kw_table,1438                                              kw_tagged,1439                                              kw_task,1440                                              kw_tri,1441                                              kw_tri0,1442                                              kw_tri1,1443                                              kw_triand,1444                                              kw_trior,1445                                              kw_trireg,1446                                              kw_unique,1447                                              kw_unique0,1448                                              kw_uwire,1449                                              kw_var,1450                                              kw_vectored,1451                                              kw_wait,1452                                              kw_wand,1453                                              kw_weak0,1454                                              kw_weak1,1455                                              kw_wildcard,1456                                              kw_wire,1457                                              kw_with,1458                                              kw_wor,1459                                              kw_verilogHash,1460                                              kw_verilogHashHash});1461 1462    TableGenExtraKeywords = std::unordered_set<IdentifierInfo *>({1463        kw_assert,1464        kw_bit,1465        kw_bits,1466        kw_code,1467        kw_dag,1468        kw_def,1469        kw_defm,1470        kw_defset,1471        kw_defvar,1472        kw_dump,1473        kw_foreach,1474        kw_in,1475        kw_include,1476        kw_let,1477        kw_list,1478        kw_multiclass,1479        kw_string,1480        kw_then,1481    });1482  }1483 1484  // Context sensitive keywords.1485  IdentifierInfo *kw_final;1486  IdentifierInfo *kw_override;1487  IdentifierInfo *kw_in;1488  IdentifierInfo *kw_of;1489  IdentifierInfo *kw_CF_CLOSED_ENUM;1490  IdentifierInfo *kw_CF_ENUM;1491  IdentifierInfo *kw_CF_OPTIONS;1492  IdentifierInfo *kw_NS_CLOSED_ENUM;1493  IdentifierInfo *kw_NS_ENUM;1494  IdentifierInfo *kw_NS_ERROR_ENUM;1495  IdentifierInfo *kw_NS_OPTIONS;1496  IdentifierInfo *kw___except;1497  IdentifierInfo *kw___has_include;1498  IdentifierInfo *kw___has_include_next;1499 1500  // JavaScript keywords.1501  IdentifierInfo *kw_as;1502  IdentifierInfo *kw_async;1503  IdentifierInfo *kw_await;1504  IdentifierInfo *kw_declare;1505  IdentifierInfo *kw_finally;1506  IdentifierInfo *kw_from;1507  IdentifierInfo *kw_function;1508  IdentifierInfo *kw_get;1509  IdentifierInfo *kw_import;1510  IdentifierInfo *kw_infer;1511  IdentifierInfo *kw_is;1512  IdentifierInfo *kw_let;1513  IdentifierInfo *kw_module;1514  IdentifierInfo *kw_readonly;1515  IdentifierInfo *kw_set;1516  IdentifierInfo *kw_type;1517  IdentifierInfo *kw_typeof;1518  IdentifierInfo *kw_var;1519  IdentifierInfo *kw_yield;1520 1521  // Java keywords.1522  IdentifierInfo *kw_abstract;1523  IdentifierInfo *kw_assert;1524  IdentifierInfo *kw_extends;1525  IdentifierInfo *kw_implements;1526  IdentifierInfo *kw_instanceof;1527  IdentifierInfo *kw_interface;1528  IdentifierInfo *kw_native;1529  IdentifierInfo *kw_package;1530  IdentifierInfo *kw_record;1531  IdentifierInfo *kw_synchronized;1532  IdentifierInfo *kw_throws;1533 1534  // Pragma keywords.1535  IdentifierInfo *kw_mark;1536  IdentifierInfo *kw_region;1537 1538  // Proto keywords.1539  IdentifierInfo *kw_extend;1540  IdentifierInfo *kw_option;1541  IdentifierInfo *kw_optional;1542  IdentifierInfo *kw_repeated;1543  IdentifierInfo *kw_required;1544  IdentifierInfo *kw_returns;1545 1546  // QT keywords.1547  IdentifierInfo *kw_signals;1548  IdentifierInfo *kw_qsignals;1549  IdentifierInfo *kw_slots;1550  IdentifierInfo *kw_qslots;1551 1552  // For internal use by clang-format.1553  IdentifierInfo *kw_internal_ident_after_define;1554 1555  // C# keywords1556  IdentifierInfo *kw_dollar;1557  IdentifierInfo *kw_base;1558  IdentifierInfo *kw_byte;1559  IdentifierInfo *kw_checked;1560  IdentifierInfo *kw_decimal;1561  IdentifierInfo *kw_delegate;1562  IdentifierInfo *kw_event;1563  IdentifierInfo *kw_fixed;1564  IdentifierInfo *kw_foreach;1565  IdentifierInfo *kw_implicit;1566  IdentifierInfo *kw_init;1567  IdentifierInfo *kw_internal;1568 1569  IdentifierInfo *kw_lock;1570  IdentifierInfo *kw_null;1571  IdentifierInfo *kw_object;1572  IdentifierInfo *kw_out;1573 1574  IdentifierInfo *kw_params;1575 1576  IdentifierInfo *kw_ref;1577  IdentifierInfo *kw_string;1578  IdentifierInfo *kw_stackalloc;1579  IdentifierInfo *kw_sbyte;1580  IdentifierInfo *kw_sealed;1581  IdentifierInfo *kw_uint;1582  IdentifierInfo *kw_ulong;1583  IdentifierInfo *kw_unchecked;1584  IdentifierInfo *kw_unsafe;1585  IdentifierInfo *kw_ushort;1586  IdentifierInfo *kw_when;1587  IdentifierInfo *kw_where;1588 1589  // Verilog keywords1590  IdentifierInfo *kw_always;1591  IdentifierInfo *kw_always_comb;1592  IdentifierInfo *kw_always_ff;1593  IdentifierInfo *kw_always_latch;1594  IdentifierInfo *kw_assign;1595  IdentifierInfo *kw_assume;1596  IdentifierInfo *kw_automatic;1597  IdentifierInfo *kw_before;1598  IdentifierInfo *kw_begin;1599  IdentifierInfo *kw_begin_keywords;1600  IdentifierInfo *kw_bins;1601  IdentifierInfo *kw_binsof;1602  IdentifierInfo *kw_casex;1603  IdentifierInfo *kw_casez;1604  IdentifierInfo *kw_celldefine;1605  IdentifierInfo *kw_checker;1606  IdentifierInfo *kw_clocking;1607  IdentifierInfo *kw_constraint;1608  IdentifierInfo *kw_context;1609  IdentifierInfo *kw_cover;1610  IdentifierInfo *kw_covergroup;1611  IdentifierInfo *kw_coverpoint;1612  IdentifierInfo *kw_default_decay_time;1613  IdentifierInfo *kw_default_nettype;1614  IdentifierInfo *kw_default_trireg_strength;1615  IdentifierInfo *kw_delay_mode_distributed;1616  IdentifierInfo *kw_delay_mode_path;1617  IdentifierInfo *kw_delay_mode_unit;1618  IdentifierInfo *kw_delay_mode_zero;1619  IdentifierInfo *kw_disable;1620  IdentifierInfo *kw_dist;1621  IdentifierInfo *kw_elsif;1622  IdentifierInfo *kw_edge;1623  IdentifierInfo *kw_end;1624  IdentifierInfo *kw_end_keywords;1625  IdentifierInfo *kw_endcase;1626  IdentifierInfo *kw_endcelldefine;1627  IdentifierInfo *kw_endchecker;1628  IdentifierInfo *kw_endclass;1629  IdentifierInfo *kw_endclocking;1630  IdentifierInfo *kw_endfunction;1631  IdentifierInfo *kw_endgenerate;1632  IdentifierInfo *kw_endgroup;1633  IdentifierInfo *kw_endinterface;1634  IdentifierInfo *kw_endmodule;1635  IdentifierInfo *kw_endpackage;1636  IdentifierInfo *kw_endprimitive;1637  IdentifierInfo *kw_endprogram;1638  IdentifierInfo *kw_endproperty;1639  IdentifierInfo *kw_endsequence;1640  IdentifierInfo *kw_endspecify;1641  IdentifierInfo *kw_endtable;1642  IdentifierInfo *kw_endtask;1643  IdentifierInfo *kw_forever;1644  IdentifierInfo *kw_fork;1645  IdentifierInfo *kw_generate;1646  IdentifierInfo *kw_highz0;1647  IdentifierInfo *kw_highz1;1648  IdentifierInfo *kw_iff;1649  IdentifierInfo *kw_ifnone;1650  IdentifierInfo *kw_ignore_bins;1651  IdentifierInfo *kw_illegal_bins;1652  IdentifierInfo *kw_initial;1653  IdentifierInfo *kw_inout;1654  IdentifierInfo *kw_input;1655  IdentifierInfo *kw_inside;1656  IdentifierInfo *kw_interconnect;1657  IdentifierInfo *kw_intersect;1658  IdentifierInfo *kw_join;1659  IdentifierInfo *kw_join_any;1660  IdentifierInfo *kw_join_none;1661  IdentifierInfo *kw_large;1662  IdentifierInfo *kw_local;1663  IdentifierInfo *kw_localparam;1664  IdentifierInfo *kw_macromodule;1665  IdentifierInfo *kw_matches;1666  IdentifierInfo *kw_medium;1667  IdentifierInfo *kw_negedge;1668  IdentifierInfo *kw_nounconnected_drive;1669  IdentifierInfo *kw_output;1670  IdentifierInfo *kw_packed;1671  IdentifierInfo *kw_parameter;1672  IdentifierInfo *kw_posedge;1673  IdentifierInfo *kw_primitive;1674  IdentifierInfo *kw_priority;1675  IdentifierInfo *kw_program;1676  IdentifierInfo *kw_property;1677  IdentifierInfo *kw_pull0;1678  IdentifierInfo *kw_pull1;1679  IdentifierInfo *kw_pure;1680  IdentifierInfo *kw_rand;1681  IdentifierInfo *kw_randc;1682  IdentifierInfo *kw_randcase;1683  IdentifierInfo *kw_randsequence;1684  IdentifierInfo *kw_repeat;1685  IdentifierInfo *kw_resetall;1686  IdentifierInfo *kw_sample;1687  IdentifierInfo *kw_scalared;1688  IdentifierInfo *kw_sequence;1689  IdentifierInfo *kw_small;1690  IdentifierInfo *kw_soft;1691  IdentifierInfo *kw_solve;1692  IdentifierInfo *kw_specify;1693  IdentifierInfo *kw_specparam;1694  IdentifierInfo *kw_strong0;1695  IdentifierInfo *kw_strong1;1696  IdentifierInfo *kw_supply0;1697  IdentifierInfo *kw_supply1;1698  IdentifierInfo *kw_table;1699  IdentifierInfo *kw_tagged;1700  IdentifierInfo *kw_task;1701  IdentifierInfo *kw_timescale;1702  IdentifierInfo *kw_tri0;1703  IdentifierInfo *kw_tri1;1704  IdentifierInfo *kw_tri;1705  IdentifierInfo *kw_triand;1706  IdentifierInfo *kw_trior;1707  IdentifierInfo *kw_trireg;1708  IdentifierInfo *kw_unconnected_drive;1709  IdentifierInfo *kw_undefineall;1710  IdentifierInfo *kw_unique;1711  IdentifierInfo *kw_unique0;1712  IdentifierInfo *kw_uwire;1713  IdentifierInfo *kw_vectored;1714  IdentifierInfo *kw_wait;1715  IdentifierInfo *kw_wand;1716  IdentifierInfo *kw_weak0;1717  IdentifierInfo *kw_weak1;1718  IdentifierInfo *kw_wildcard;1719  IdentifierInfo *kw_wire;1720  IdentifierInfo *kw_with;1721  IdentifierInfo *kw_wor;1722 1723  // Workaround for hashes and backticks in Verilog.1724  IdentifierInfo *kw_verilogHash;1725  IdentifierInfo *kw_verilogHashHash;1726 1727  // Symbols in Verilog that don't exist in C++.1728  IdentifierInfo *kw_apostrophe;1729 1730  // TableGen keywords1731  IdentifierInfo *kw_bit;1732  IdentifierInfo *kw_bits;1733  IdentifierInfo *kw_code;1734  IdentifierInfo *kw_dag;1735  IdentifierInfo *kw_def;1736  IdentifierInfo *kw_defm;1737  IdentifierInfo *kw_defset;1738  IdentifierInfo *kw_defvar;1739  IdentifierInfo *kw_dump;1740  IdentifierInfo *kw_include;1741  IdentifierInfo *kw_list;1742  IdentifierInfo *kw_multiclass;1743  IdentifierInfo *kw_then;1744 1745  /// Returns \c true if \p Tok is a keyword or an identifier.1746  bool isWordLike(const FormatToken &Tok, bool IsVerilog = true) const {1747    // getIdentifierinfo returns non-null for keywords as well as identifiers.1748    return Tok.Tok.getIdentifierInfo() &&1749           (!IsVerilog || !isVerilogKeywordSymbol(Tok));1750  }1751 1752  /// Returns \c true if \p Tok is a true JavaScript identifier, returns1753  /// \c false if it is a keyword or a pseudo keyword.1754  /// If \c AcceptIdentifierName is true, returns true not only for keywords,1755  // but also for IdentifierName tokens (aka pseudo-keywords), such as1756  // ``yield``.1757  bool isJavaScriptIdentifier(const FormatToken &Tok,1758                              bool AcceptIdentifierName = true) const {1759    // Based on the list of JavaScript & TypeScript keywords here:1760    // https://github.com/microsoft/TypeScript/blob/main/src/compiler/scanner.ts#L741761    if (Tok.isAccessSpecifierKeyword())1762      return false;1763    switch (Tok.Tok.getKind()) {1764    case tok::kw_break:1765    case tok::kw_case:1766    case tok::kw_catch:1767    case tok::kw_class:1768    case tok::kw_continue:1769    case tok::kw_const:1770    case tok::kw_default:1771    case tok::kw_delete:1772    case tok::kw_do:1773    case tok::kw_else:1774    case tok::kw_enum:1775    case tok::kw_export:1776    case tok::kw_false:1777    case tok::kw_for:1778    case tok::kw_if:1779    case tok::kw_import:1780    case tok::kw_module:1781    case tok::kw_new:1782    case tok::kw_return:1783    case tok::kw_static:1784    case tok::kw_switch:1785    case tok::kw_this:1786    case tok::kw_throw:1787    case tok::kw_true:1788    case tok::kw_try:1789    case tok::kw_typeof:1790    case tok::kw_void:1791    case tok::kw_while:1792      // These are JS keywords that are lexed by LLVM/clang as keywords.1793      return false;1794    case tok::identifier: {1795      // For identifiers, make sure they are true identifiers, excluding the1796      // JavaScript pseudo-keywords (not lexed by LLVM/clang as keywords).1797      bool IsPseudoKeyword =1798          JsExtraKeywords.find(Tok.Tok.getIdentifierInfo()) !=1799          JsExtraKeywords.end();1800      return AcceptIdentifierName || !IsPseudoKeyword;1801    }1802    default:1803      // Other keywords are handled in the switch below, to avoid problems due1804      // to duplicate case labels when using the #include trick.1805      break;1806    }1807 1808    switch (Tok.Tok.getKind()) {1809      // Handle C++ keywords not included above: these are all JS identifiers.1810#define KEYWORD(X, Y) case tok::kw_##X:1811#include "clang/Basic/TokenKinds.def"1812      // #undef KEYWORD is not needed -- it's #undef-ed at the end of1813      // TokenKinds.def1814      return true;1815    default:1816      // All other tokens (punctuation etc) are not JS identifiers.1817      return false;1818    }1819  }1820 1821  /// Returns \c true if \p Tok is a C# keyword, returns \c false if it is1822  /// anything else.1823  bool isCSharpKeyword(const FormatToken &Tok) const {1824    if (Tok.isAccessSpecifierKeyword())1825      return true;1826    switch (Tok.Tok.getKind()) {1827    case tok::kw_bool:1828    case tok::kw_break:1829    case tok::kw_case:1830    case tok::kw_catch:1831    case tok::kw_char:1832    case tok::kw_class:1833    case tok::kw_const:1834    case tok::kw_continue:1835    case tok::kw_default:1836    case tok::kw_do:1837    case tok::kw_double:1838    case tok::kw_else:1839    case tok::kw_enum:1840    case tok::kw_explicit:1841    case tok::kw_extern:1842    case tok::kw_false:1843    case tok::kw_float:1844    case tok::kw_for:1845    case tok::kw_goto:1846    case tok::kw_if:1847    case tok::kw_int:1848    case tok::kw_long:1849    case tok::kw_namespace:1850    case tok::kw_new:1851    case tok::kw_operator:1852    case tok::kw_return:1853    case tok::kw_short:1854    case tok::kw_sizeof:1855    case tok::kw_static:1856    case tok::kw_struct:1857    case tok::kw_switch:1858    case tok::kw_this:1859    case tok::kw_throw:1860    case tok::kw_true:1861    case tok::kw_try:1862    case tok::kw_typeof:1863    case tok::kw_using:1864    case tok::kw_virtual:1865    case tok::kw_void:1866    case tok::kw_volatile:1867    case tok::kw_while:1868      return true;1869    default:1870      return Tok.is(tok::identifier) &&1871             CSharpExtraKeywords.find(Tok.Tok.getIdentifierInfo()) ==1872                 CSharpExtraKeywords.end();1873    }1874  }1875 1876  bool isVerilogKeywordSymbol(const FormatToken &Tok) const {1877    return Tok.isOneOf(kw_verilogHash, kw_verilogHashHash, kw_apostrophe);1878  }1879 1880  bool isVerilogWordOperator(const FormatToken &Tok) const {1881    return Tok.isOneOf(kw_before, kw_intersect, kw_dist, kw_iff, kw_inside,1882                       kw_with);1883  }1884 1885  bool isVerilogIdentifier(const FormatToken &Tok) const {1886    switch (Tok.Tok.getKind()) {1887    case tok::kw_case:1888    case tok::kw_class:1889    case tok::kw_const:1890    case tok::kw_continue:1891    case tok::kw_default:1892    case tok::kw_do:1893    case tok::kw_else:1894    case tok::kw_enum:1895    case tok::kw_export:1896    case tok::kw_extern:1897    case tok::kw_for:1898    case tok::kw_if:1899    case tok::kw_import:1900    case tok::kw_restrict:1901    case tok::kw_signed:1902    case tok::kw_static:1903    case tok::kw_struct:1904    case tok::kw_typedef:1905    case tok::kw_union:1906    case tok::kw_unsigned:1907    case tok::kw_virtual:1908    case tok::kw_while:1909      return false;1910    case tok::identifier:1911      return isWordLike(Tok) &&1912             VerilogExtraKeywords.find(Tok.Tok.getIdentifierInfo()) ==1913                 VerilogExtraKeywords.end();1914    default:1915      // getIdentifierInfo returns non-null for both identifiers and keywords.1916      return Tok.Tok.getIdentifierInfo();1917    }1918  }1919 1920  /// Returns whether \p Tok is a Verilog preprocessor directive.  This is1921  /// needed because macro expansions start with a backtick as well and they1922  /// need to be treated differently.1923  bool isVerilogPPDirective(const FormatToken &Tok) const {1924    auto Info = Tok.Tok.getIdentifierInfo();1925    if (!Info)1926      return false;1927    switch (Info->getPPKeywordID()) {1928    case tok::pp_define:1929    case tok::pp_else:1930    case tok::pp_endif:1931    case tok::pp_ifdef:1932    case tok::pp_ifndef:1933    case tok::pp_include:1934    case tok::pp_line:1935    case tok::pp_pragma:1936    case tok::pp_undef:1937      return true;1938    default:1939      return Tok.isOneOf(kw_begin_keywords, kw_celldefine,1940                         kw_default_decay_time, kw_default_nettype,1941                         kw_default_trireg_strength, kw_delay_mode_distributed,1942                         kw_delay_mode_path, kw_delay_mode_unit,1943                         kw_delay_mode_zero, kw_elsif, kw_end_keywords,1944                         kw_endcelldefine, kw_nounconnected_drive, kw_resetall,1945                         kw_timescale, kw_unconnected_drive, kw_undefineall);1946    }1947  }1948 1949  /// Returns whether \p Tok is a Verilog keyword that opens a block.1950  bool isVerilogBegin(const FormatToken &Tok) const {1951    // `table` is not included since it needs to be treated specially.1952    if (Tok.isOneOf(kw_begin, kw_generate, kw_specify))1953      return true;1954    if (Tok.isNot(kw_fork))1955      return false;1956    const auto *Prev = Tok.getPreviousNonComment();1957    return !(Prev && Prev->isOneOf(kw_disable, kw_wait));1958  }1959 1960  /// Returns whether \p Tok is a Verilog keyword that closes a block.1961  bool isVerilogEnd(const FormatToken &Tok) const {1962    return !Tok.endsSequence(kw_join, kw_rand) &&1963           Tok.isOneOf(TT_MacroBlockEnd, kw_end, kw_endcase, kw_endclass,1964                       kw_endclocking, kw_endchecker, kw_endfunction,1965                       kw_endgenerate, kw_endgroup, kw_endinterface,1966                       kw_endmodule, kw_endpackage, kw_endprimitive,1967                       kw_endprogram, kw_endproperty, kw_endsequence,1968                       kw_endspecify, kw_endtable, kw_endtask, kw_join,1969                       kw_join_any, kw_join_none);1970  }1971 1972  /// Returns whether \p Tok is a Verilog keyword that opens a module, etc.1973  bool isVerilogHierarchy(const FormatToken &Tok) const {1974    if (Tok.endsSequence(kw_function, kw_with))1975      return false;1976    if (Tok.is(kw_property)) {1977      const FormatToken *Prev = Tok.getPreviousNonComment();1978      return !(Prev &&1979               Prev->isOneOf(tok::kw_restrict, kw_assert, kw_assume, kw_cover));1980    }1981    return Tok.isOneOf(tok::kw_case, tok::kw_class, kw_function, kw_module,1982                       kw_interface, kw_package, kw_casex, kw_casez, kw_checker,1983                       kw_clocking, kw_covergroup, kw_macromodule, kw_primitive,1984                       kw_program, kw_property, kw_randcase, kw_randsequence,1985                       kw_task);1986  }1987 1988  bool isVerilogEndOfLabel(const FormatToken &Tok) const {1989    const FormatToken *Next = Tok.getNextNonComment();1990    // In Verilog the colon in a default label is optional.1991    return Tok.is(TT_CaseLabelColon) ||1992           (Tok.is(tok::kw_default) &&1993            !(Next && Next->isOneOf(tok::colon, tok::semi, kw_clocking, kw_iff,1994                                    kw_input, kw_output, kw_sequence)));1995  }1996 1997  /// Returns whether \p Tok is a Verilog keyword that starts a1998  /// structured procedure like 'always'.1999  bool isVerilogStructuredProcedure(const FormatToken &Tok) const {2000    return Tok.isOneOf(kw_always, kw_always_comb, kw_always_ff, kw_always_latch,2001                       kw_final, kw_forever, kw_initial);2002  }2003 2004  bool isVerilogQualifier(const FormatToken &Tok) const {2005    switch (Tok.Tok.getKind()) {2006    case tok::kw_extern:2007    case tok::kw_signed:2008    case tok::kw_static:2009    case tok::kw_unsigned:2010    case tok::kw_virtual:2011      return true;2012    case tok::identifier:2013      return Tok.isOneOf(2014          kw_let, kw_var, kw_ref, kw_automatic, kw_bins, kw_coverpoint,2015          kw_ignore_bins, kw_illegal_bins, kw_inout, kw_input, kw_interconnect,2016          kw_local, kw_localparam, kw_output, kw_parameter, kw_pure, kw_rand,2017          kw_randc, kw_scalared, kw_specparam, kw_tri, kw_tri0, kw_tri1,2018          kw_triand, kw_trior, kw_trireg, kw_uwire, kw_vectored, kw_wand,2019          kw_wildcard, kw_wire, kw_wor);2020    default:2021      return false;2022    }2023  }2024 2025  bool isTableGenDefinition(const FormatToken &Tok) const {2026    return Tok.isOneOf(kw_def, kw_defm, kw_defset, kw_defvar, kw_multiclass,2027                       kw_let, tok::kw_class);2028  }2029 2030  bool isTableGenKeyword(const FormatToken &Tok) const {2031    switch (Tok.Tok.getKind()) {2032    case tok::kw_class:2033    case tok::kw_else:2034    case tok::kw_false:2035    case tok::kw_if:2036    case tok::kw_int:2037    case tok::kw_true:2038      return true;2039    default:2040      return Tok.is(tok::identifier) &&2041             TableGenExtraKeywords.find(Tok.Tok.getIdentifierInfo()) !=2042                 TableGenExtraKeywords.end();2043    }2044  }2045 2046private:2047  /// The JavaScript keywords beyond the C++ keyword set.2048  std::unordered_set<IdentifierInfo *> JsExtraKeywords;2049 2050  /// The C# keywords beyond the C++ keyword set.2051  std::unordered_set<IdentifierInfo *> CSharpExtraKeywords;2052 2053  /// The Verilog keywords beyond the C++ keyword set.2054  std::unordered_set<IdentifierInfo *> VerilogExtraKeywords;2055 2056  /// The TableGen keywords beyond the C++ keyword set.2057  std::unordered_set<IdentifierInfo *> TableGenExtraKeywords;2058};2059 2060inline bool isLineComment(const FormatToken &FormatTok) {2061  return FormatTok.is(tok::comment) && !FormatTok.TokenText.starts_with("/*");2062}2063 2064// Checks if \p FormatTok is a line comment that continues the line comment2065// \p Previous. The original column of \p MinColumnToken is used to determine2066// whether \p FormatTok is indented enough to the right to continue \p Previous.2067inline bool continuesLineComment(const FormatToken &FormatTok,2068                                 const FormatToken *Previous,2069                                 const FormatToken *MinColumnToken) {2070  if (!Previous || !MinColumnToken)2071    return false;2072  unsigned MinContinueColumn =2073      MinColumnToken->OriginalColumn + (isLineComment(*MinColumnToken) ? 0 : 1);2074  return isLineComment(FormatTok) && FormatTok.NewlinesBefore == 1 &&2075         isLineComment(*Previous) &&2076         FormatTok.OriginalColumn >= MinContinueColumn;2077}2078 2079// Returns \c true if \c Current starts a new parameter.2080bool startsNextParameter(const FormatToken &Current, const FormatStyle &Style);2081 2082} // namespace format2083} // namespace clang2084 2085#endif2086