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