1*06f32e7eSjoerg //===--- Token.h - Token interface ------------------------------*- C++ -*-===// 2*06f32e7eSjoerg // 3*06f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 5*06f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06f32e7eSjoerg // 7*06f32e7eSjoerg //===----------------------------------------------------------------------===// 8*06f32e7eSjoerg // 9*06f32e7eSjoerg // This file defines the Token interface. 10*06f32e7eSjoerg // 11*06f32e7eSjoerg //===----------------------------------------------------------------------===// 12*06f32e7eSjoerg 13*06f32e7eSjoerg #ifndef LLVM_CLANG_LEX_TOKEN_H 14*06f32e7eSjoerg #define LLVM_CLANG_LEX_TOKEN_H 15*06f32e7eSjoerg 16*06f32e7eSjoerg #include "clang/Basic/SourceLocation.h" 17*06f32e7eSjoerg #include "clang/Basic/TokenKinds.h" 18*06f32e7eSjoerg #include "llvm/ADT/StringRef.h" 19*06f32e7eSjoerg #include <cassert> 20*06f32e7eSjoerg 21*06f32e7eSjoerg namespace clang { 22*06f32e7eSjoerg 23*06f32e7eSjoerg class IdentifierInfo; 24*06f32e7eSjoerg 25*06f32e7eSjoerg /// Token - This structure provides full information about a lexed token. 26*06f32e7eSjoerg /// It is not intended to be space efficient, it is intended to return as much 27*06f32e7eSjoerg /// information as possible about each returned token. This is expected to be 28*06f32e7eSjoerg /// compressed into a smaller form if memory footprint is important. 29*06f32e7eSjoerg /// 30*06f32e7eSjoerg /// The parser can create a special "annotation token" representing a stream of 31*06f32e7eSjoerg /// tokens that were parsed and semantically resolved, e.g.: "foo::MyClass<int>" 32*06f32e7eSjoerg /// can be represented by a single typename annotation token that carries 33*06f32e7eSjoerg /// information about the SourceRange of the tokens and the type object. 34*06f32e7eSjoerg class Token { 35*06f32e7eSjoerg /// The location of the token. This is actually a SourceLocation. 36*06f32e7eSjoerg unsigned Loc; 37*06f32e7eSjoerg 38*06f32e7eSjoerg // Conceptually these next two fields could be in a union. However, this 39*06f32e7eSjoerg // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical 40*06f32e7eSjoerg // routine. Keeping as separate members with casts until a more beautiful fix 41*06f32e7eSjoerg // presents itself. 42*06f32e7eSjoerg 43*06f32e7eSjoerg /// UintData - This holds either the length of the token text, when 44*06f32e7eSjoerg /// a normal token, or the end of the SourceRange when an annotation 45*06f32e7eSjoerg /// token. 46*06f32e7eSjoerg unsigned UintData; 47*06f32e7eSjoerg 48*06f32e7eSjoerg /// PtrData - This is a union of four different pointer types, which depends 49*06f32e7eSjoerg /// on what type of token this is: 50*06f32e7eSjoerg /// Identifiers, keywords, etc: 51*06f32e7eSjoerg /// This is an IdentifierInfo*, which contains the uniqued identifier 52*06f32e7eSjoerg /// spelling. 53*06f32e7eSjoerg /// Literals: isLiteral() returns true. 54*06f32e7eSjoerg /// This is a pointer to the start of the token in a text buffer, which 55*06f32e7eSjoerg /// may be dirty (have trigraphs / escaped newlines). 56*06f32e7eSjoerg /// Annotations (resolved type names, C++ scopes, etc): isAnnotation(). 57*06f32e7eSjoerg /// This is a pointer to sema-specific data for the annotation token. 58*06f32e7eSjoerg /// Eof: 59*06f32e7eSjoerg // This is a pointer to a Decl. 60*06f32e7eSjoerg /// Other: 61*06f32e7eSjoerg /// This is null. 62*06f32e7eSjoerg void *PtrData; 63*06f32e7eSjoerg 64*06f32e7eSjoerg /// Kind - The actual flavor of token this is. 65*06f32e7eSjoerg tok::TokenKind Kind; 66*06f32e7eSjoerg 67*06f32e7eSjoerg /// Flags - Bits we track about this token, members of the TokenFlags enum. 68*06f32e7eSjoerg unsigned short Flags; 69*06f32e7eSjoerg 70*06f32e7eSjoerg public: 71*06f32e7eSjoerg // Various flags set per token: 72*06f32e7eSjoerg enum TokenFlags { 73*06f32e7eSjoerg StartOfLine = 0x01, // At start of line or only after whitespace 74*06f32e7eSjoerg // (considering the line after macro expansion). 75*06f32e7eSjoerg LeadingSpace = 0x02, // Whitespace exists before this token (considering 76*06f32e7eSjoerg // whitespace after macro expansion). 77*06f32e7eSjoerg DisableExpand = 0x04, // This identifier may never be macro expanded. 78*06f32e7eSjoerg NeedsCleaning = 0x08, // Contained an escaped newline or trigraph. 79*06f32e7eSjoerg LeadingEmptyMacro = 0x10, // Empty macro exists before this token. 80*06f32e7eSjoerg HasUDSuffix = 0x20, // This string or character literal has a ud-suffix. 81*06f32e7eSjoerg HasUCN = 0x40, // This identifier contains a UCN. 82*06f32e7eSjoerg IgnoredComma = 0x80, // This comma is not a macro argument separator (MS). 83*06f32e7eSjoerg StringifiedInMacro = 0x100, // This string or character literal is formed by 84*06f32e7eSjoerg // macro stringizing or charizing operator. 85*06f32e7eSjoerg CommaAfterElided = 0x200, // The comma following this token was elided (MS). 86*06f32e7eSjoerg IsEditorPlaceholder = 0x400, // This identifier is a placeholder. 87*06f32e7eSjoerg IsReinjected = 0x800, // A phase 4 token that was produced before and 88*06f32e7eSjoerg // re-added, e.g. via EnterTokenStream. Annotation 89*06f32e7eSjoerg // tokens are *not* reinjected. 90*06f32e7eSjoerg }; 91*06f32e7eSjoerg getKind()92*06f32e7eSjoerg tok::TokenKind getKind() const { return Kind; } setKind(tok::TokenKind K)93*06f32e7eSjoerg void setKind(tok::TokenKind K) { Kind = K; } 94*06f32e7eSjoerg 95*06f32e7eSjoerg /// is/isNot - Predicates to check if this token is a specific kind, as in 96*06f32e7eSjoerg /// "if (Tok.is(tok::l_brace)) {...}". is(tok::TokenKind K)97*06f32e7eSjoerg bool is(tok::TokenKind K) const { return Kind == K; } isNot(tok::TokenKind K)98*06f32e7eSjoerg bool isNot(tok::TokenKind K) const { return Kind != K; } isOneOf(tok::TokenKind K1,tok::TokenKind K2)99*06f32e7eSjoerg bool isOneOf(tok::TokenKind K1, tok::TokenKind K2) const { 100*06f32e7eSjoerg return is(K1) || is(K2); 101*06f32e7eSjoerg } 102*06f32e7eSjoerg template <typename... Ts> isOneOf(tok::TokenKind K1,tok::TokenKind K2,Ts...Ks)103*06f32e7eSjoerg bool isOneOf(tok::TokenKind K1, tok::TokenKind K2, Ts... Ks) const { 104*06f32e7eSjoerg return is(K1) || isOneOf(K2, Ks...); 105*06f32e7eSjoerg } 106*06f32e7eSjoerg 107*06f32e7eSjoerg /// Return true if this is a raw identifier (when lexing 108*06f32e7eSjoerg /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode). isAnyIdentifier()109*06f32e7eSjoerg bool isAnyIdentifier() const { 110*06f32e7eSjoerg return tok::isAnyIdentifier(getKind()); 111*06f32e7eSjoerg } 112*06f32e7eSjoerg 113*06f32e7eSjoerg /// Return true if this is a "literal", like a numeric 114*06f32e7eSjoerg /// constant, string, etc. isLiteral()115*06f32e7eSjoerg bool isLiteral() const { 116*06f32e7eSjoerg return tok::isLiteral(getKind()); 117*06f32e7eSjoerg } 118*06f32e7eSjoerg 119*06f32e7eSjoerg /// Return true if this is any of tok::annot_* kind tokens. isAnnotation()120*06f32e7eSjoerg bool isAnnotation() const { 121*06f32e7eSjoerg return tok::isAnnotation(getKind()); 122*06f32e7eSjoerg } 123*06f32e7eSjoerg 124*06f32e7eSjoerg /// Return a source location identifier for the specified 125*06f32e7eSjoerg /// offset in the current file. getLocation()126*06f32e7eSjoerg SourceLocation getLocation() const { 127*06f32e7eSjoerg return SourceLocation::getFromRawEncoding(Loc); 128*06f32e7eSjoerg } getLength()129*06f32e7eSjoerg unsigned getLength() const { 130*06f32e7eSjoerg assert(!isAnnotation() && "Annotation tokens have no length field"); 131*06f32e7eSjoerg return UintData; 132*06f32e7eSjoerg } 133*06f32e7eSjoerg setLocation(SourceLocation L)134*06f32e7eSjoerg void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } setLength(unsigned Len)135*06f32e7eSjoerg void setLength(unsigned Len) { 136*06f32e7eSjoerg assert(!isAnnotation() && "Annotation tokens have no length field"); 137*06f32e7eSjoerg UintData = Len; 138*06f32e7eSjoerg } 139*06f32e7eSjoerg getAnnotationEndLoc()140*06f32e7eSjoerg SourceLocation getAnnotationEndLoc() const { 141*06f32e7eSjoerg assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); 142*06f32e7eSjoerg return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); 143*06f32e7eSjoerg } setAnnotationEndLoc(SourceLocation L)144*06f32e7eSjoerg void setAnnotationEndLoc(SourceLocation L) { 145*06f32e7eSjoerg assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); 146*06f32e7eSjoerg UintData = L.getRawEncoding(); 147*06f32e7eSjoerg } 148*06f32e7eSjoerg getLastLoc()149*06f32e7eSjoerg SourceLocation getLastLoc() const { 150*06f32e7eSjoerg return isAnnotation() ? getAnnotationEndLoc() : getLocation(); 151*06f32e7eSjoerg } 152*06f32e7eSjoerg getEndLoc()153*06f32e7eSjoerg SourceLocation getEndLoc() const { 154*06f32e7eSjoerg return isAnnotation() ? getAnnotationEndLoc() 155*06f32e7eSjoerg : getLocation().getLocWithOffset(getLength()); 156*06f32e7eSjoerg } 157*06f32e7eSjoerg 158*06f32e7eSjoerg /// SourceRange of the group of tokens that this annotation token 159*06f32e7eSjoerg /// represents. getAnnotationRange()160*06f32e7eSjoerg SourceRange getAnnotationRange() const { 161*06f32e7eSjoerg return SourceRange(getLocation(), getAnnotationEndLoc()); 162*06f32e7eSjoerg } setAnnotationRange(SourceRange R)163*06f32e7eSjoerg void setAnnotationRange(SourceRange R) { 164*06f32e7eSjoerg setLocation(R.getBegin()); 165*06f32e7eSjoerg setAnnotationEndLoc(R.getEnd()); 166*06f32e7eSjoerg } 167*06f32e7eSjoerg getName()168*06f32e7eSjoerg const char *getName() const { return tok::getTokenName(Kind); } 169*06f32e7eSjoerg 170*06f32e7eSjoerg /// Reset all flags to cleared. startToken()171*06f32e7eSjoerg void startToken() { 172*06f32e7eSjoerg Kind = tok::unknown; 173*06f32e7eSjoerg Flags = 0; 174*06f32e7eSjoerg PtrData = nullptr; 175*06f32e7eSjoerg UintData = 0; 176*06f32e7eSjoerg Loc = SourceLocation().getRawEncoding(); 177*06f32e7eSjoerg } 178*06f32e7eSjoerg getIdentifierInfo()179*06f32e7eSjoerg IdentifierInfo *getIdentifierInfo() const { 180*06f32e7eSjoerg assert(isNot(tok::raw_identifier) && 181*06f32e7eSjoerg "getIdentifierInfo() on a tok::raw_identifier token!"); 182*06f32e7eSjoerg assert(!isAnnotation() && 183*06f32e7eSjoerg "getIdentifierInfo() on an annotation token!"); 184*06f32e7eSjoerg if (isLiteral()) return nullptr; 185*06f32e7eSjoerg if (is(tok::eof)) return nullptr; 186*06f32e7eSjoerg return (IdentifierInfo*) PtrData; 187*06f32e7eSjoerg } setIdentifierInfo(IdentifierInfo * II)188*06f32e7eSjoerg void setIdentifierInfo(IdentifierInfo *II) { 189*06f32e7eSjoerg PtrData = (void*) II; 190*06f32e7eSjoerg } 191*06f32e7eSjoerg getEofData()192*06f32e7eSjoerg const void *getEofData() const { 193*06f32e7eSjoerg assert(is(tok::eof)); 194*06f32e7eSjoerg return reinterpret_cast<const void *>(PtrData); 195*06f32e7eSjoerg } setEofData(const void * D)196*06f32e7eSjoerg void setEofData(const void *D) { 197*06f32e7eSjoerg assert(is(tok::eof)); 198*06f32e7eSjoerg assert(!PtrData); 199*06f32e7eSjoerg PtrData = const_cast<void *>(D); 200*06f32e7eSjoerg } 201*06f32e7eSjoerg 202*06f32e7eSjoerg /// getRawIdentifier - For a raw identifier token (i.e., an identifier 203*06f32e7eSjoerg /// lexed in raw mode), returns a reference to the text substring in the 204*06f32e7eSjoerg /// buffer if known. getRawIdentifier()205*06f32e7eSjoerg StringRef getRawIdentifier() const { 206*06f32e7eSjoerg assert(is(tok::raw_identifier)); 207*06f32e7eSjoerg return StringRef(reinterpret_cast<const char *>(PtrData), getLength()); 208*06f32e7eSjoerg } setRawIdentifierData(const char * Ptr)209*06f32e7eSjoerg void setRawIdentifierData(const char *Ptr) { 210*06f32e7eSjoerg assert(is(tok::raw_identifier)); 211*06f32e7eSjoerg PtrData = const_cast<char*>(Ptr); 212*06f32e7eSjoerg } 213*06f32e7eSjoerg 214*06f32e7eSjoerg /// getLiteralData - For a literal token (numeric constant, string, etc), this 215*06f32e7eSjoerg /// returns a pointer to the start of it in the text buffer if known, null 216*06f32e7eSjoerg /// otherwise. getLiteralData()217*06f32e7eSjoerg const char *getLiteralData() const { 218*06f32e7eSjoerg assert(isLiteral() && "Cannot get literal data of non-literal"); 219*06f32e7eSjoerg return reinterpret_cast<const char*>(PtrData); 220*06f32e7eSjoerg } setLiteralData(const char * Ptr)221*06f32e7eSjoerg void setLiteralData(const char *Ptr) { 222*06f32e7eSjoerg assert(isLiteral() && "Cannot set literal data of non-literal"); 223*06f32e7eSjoerg PtrData = const_cast<char*>(Ptr); 224*06f32e7eSjoerg } 225*06f32e7eSjoerg getAnnotationValue()226*06f32e7eSjoerg void *getAnnotationValue() const { 227*06f32e7eSjoerg assert(isAnnotation() && "Used AnnotVal on non-annotation token"); 228*06f32e7eSjoerg return PtrData; 229*06f32e7eSjoerg } setAnnotationValue(void * val)230*06f32e7eSjoerg void setAnnotationValue(void *val) { 231*06f32e7eSjoerg assert(isAnnotation() && "Used AnnotVal on non-annotation token"); 232*06f32e7eSjoerg PtrData = val; 233*06f32e7eSjoerg } 234*06f32e7eSjoerg 235*06f32e7eSjoerg /// Set the specified flag. setFlag(TokenFlags Flag)236*06f32e7eSjoerg void setFlag(TokenFlags Flag) { 237*06f32e7eSjoerg Flags |= Flag; 238*06f32e7eSjoerg } 239*06f32e7eSjoerg 240*06f32e7eSjoerg /// Get the specified flag. getFlag(TokenFlags Flag)241*06f32e7eSjoerg bool getFlag(TokenFlags Flag) const { 242*06f32e7eSjoerg return (Flags & Flag) != 0; 243*06f32e7eSjoerg } 244*06f32e7eSjoerg 245*06f32e7eSjoerg /// Unset the specified flag. clearFlag(TokenFlags Flag)246*06f32e7eSjoerg void clearFlag(TokenFlags Flag) { 247*06f32e7eSjoerg Flags &= ~Flag; 248*06f32e7eSjoerg } 249*06f32e7eSjoerg 250*06f32e7eSjoerg /// Return the internal represtation of the flags. 251*06f32e7eSjoerg /// 252*06f32e7eSjoerg /// This is only intended for low-level operations such as writing tokens to 253*06f32e7eSjoerg /// disk. getFlags()254*06f32e7eSjoerg unsigned getFlags() const { 255*06f32e7eSjoerg return Flags; 256*06f32e7eSjoerg } 257*06f32e7eSjoerg 258*06f32e7eSjoerg /// Set a flag to either true or false. setFlagValue(TokenFlags Flag,bool Val)259*06f32e7eSjoerg void setFlagValue(TokenFlags Flag, bool Val) { 260*06f32e7eSjoerg if (Val) 261*06f32e7eSjoerg setFlag(Flag); 262*06f32e7eSjoerg else 263*06f32e7eSjoerg clearFlag(Flag); 264*06f32e7eSjoerg } 265*06f32e7eSjoerg 266*06f32e7eSjoerg /// isAtStartOfLine - Return true if this token is at the start of a line. 267*06f32e7eSjoerg /// isAtStartOfLine()268*06f32e7eSjoerg bool isAtStartOfLine() const { return getFlag(StartOfLine); } 269*06f32e7eSjoerg 270*06f32e7eSjoerg /// Return true if this token has whitespace before it. 271*06f32e7eSjoerg /// hasLeadingSpace()272*06f32e7eSjoerg bool hasLeadingSpace() const { return getFlag(LeadingSpace); } 273*06f32e7eSjoerg 274*06f32e7eSjoerg /// Return true if this identifier token should never 275*06f32e7eSjoerg /// be expanded in the future, due to C99 6.10.3.4p2. isExpandDisabled()276*06f32e7eSjoerg bool isExpandDisabled() const { return getFlag(DisableExpand); } 277*06f32e7eSjoerg 278*06f32e7eSjoerg /// Return true if we have an ObjC keyword identifier. 279*06f32e7eSjoerg bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const; 280*06f32e7eSjoerg 281*06f32e7eSjoerg /// Return the ObjC keyword kind. 282*06f32e7eSjoerg tok::ObjCKeywordKind getObjCKeywordID() const; 283*06f32e7eSjoerg 284*06f32e7eSjoerg /// Return true if this token has trigraphs or escaped newlines in it. needsCleaning()285*06f32e7eSjoerg bool needsCleaning() const { return getFlag(NeedsCleaning); } 286*06f32e7eSjoerg 287*06f32e7eSjoerg /// Return true if this token has an empty macro before it. 288*06f32e7eSjoerg /// hasLeadingEmptyMacro()289*06f32e7eSjoerg bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); } 290*06f32e7eSjoerg 291*06f32e7eSjoerg /// Return true if this token is a string or character literal which 292*06f32e7eSjoerg /// has a ud-suffix. hasUDSuffix()293*06f32e7eSjoerg bool hasUDSuffix() const { return getFlag(HasUDSuffix); } 294*06f32e7eSjoerg 295*06f32e7eSjoerg /// Returns true if this token contains a universal character name. hasUCN()296*06f32e7eSjoerg bool hasUCN() const { return getFlag(HasUCN); } 297*06f32e7eSjoerg 298*06f32e7eSjoerg /// Returns true if this token is formed by macro by stringizing or charizing 299*06f32e7eSjoerg /// operator. stringifiedInMacro()300*06f32e7eSjoerg bool stringifiedInMacro() const { return getFlag(StringifiedInMacro); } 301*06f32e7eSjoerg 302*06f32e7eSjoerg /// Returns true if the comma after this token was elided. commaAfterElided()303*06f32e7eSjoerg bool commaAfterElided() const { return getFlag(CommaAfterElided); } 304*06f32e7eSjoerg 305*06f32e7eSjoerg /// Returns true if this token is an editor placeholder. 306*06f32e7eSjoerg /// 307*06f32e7eSjoerg /// Editor placeholders are produced by the code-completion engine and are 308*06f32e7eSjoerg /// represented as characters between '<#' and '#>' in the source code. The 309*06f32e7eSjoerg /// lexer uses identifier tokens to represent placeholders. isEditorPlaceholder()310*06f32e7eSjoerg bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); } 311*06f32e7eSjoerg }; 312*06f32e7eSjoerg 313*06f32e7eSjoerg /// Information about the conditional stack (\#if directives) 314*06f32e7eSjoerg /// currently active. 315*06f32e7eSjoerg struct PPConditionalInfo { 316*06f32e7eSjoerg /// Location where the conditional started. 317*06f32e7eSjoerg SourceLocation IfLoc; 318*06f32e7eSjoerg 319*06f32e7eSjoerg /// True if this was contained in a skipping directive, e.g., 320*06f32e7eSjoerg /// in a "\#if 0" block. 321*06f32e7eSjoerg bool WasSkipping; 322*06f32e7eSjoerg 323*06f32e7eSjoerg /// True if we have emitted tokens already, and now we're in 324*06f32e7eSjoerg /// an \#else block or something. Only useful in Skipping blocks. 325*06f32e7eSjoerg bool FoundNonSkip; 326*06f32e7eSjoerg 327*06f32e7eSjoerg /// True if we've seen a \#else in this block. If so, 328*06f32e7eSjoerg /// \#elif/\#else directives are not allowed. 329*06f32e7eSjoerg bool FoundElse; 330*06f32e7eSjoerg }; 331*06f32e7eSjoerg 332*06f32e7eSjoerg } // end namespace clang 333*06f32e7eSjoerg 334*06f32e7eSjoerg #endif // LLVM_CLANG_LEX_TOKEN_H 335