Clang Project

clang_source_code/include/clang/Lex/LiteralSupport.h
1//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the NumericLiteralParser, CharLiteralParser, and
10// StringLiteralParser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LEX_LITERALSUPPORT_H
15#define LLVM_CLANG_LEX_LITERALSUPPORT_H
16
17#include "clang/Basic/CharInfo.h"
18#include "clang/Basic/LLVM.h"
19#include "clang/Basic/TokenKinds.h"
20#include "llvm/ADT/APFloat.h"
21#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/SmallString.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/DataTypes.h"
25
26namespace clang {
27
28class DiagnosticsEngine;
29class Preprocessor;
30class Token;
31class SourceLocation;
32class TargetInfo;
33class SourceManager;
34class LangOptions;
35
36/// Copy characters from Input to Buf, expanding any UCNs.
37void expandUCNs(SmallVectorImpl<char> &BufStringRef Input);
38
39/// NumericLiteralParser - This performs strict semantic analysis of the content
40/// of a ppnumber, classifying it as either integer, floating, or erroneous,
41/// determines the radix of the value and can convert it to a useful value.
42class NumericLiteralParser {
43  Preprocessor &PP// needed for diagnostics
44
45  const char *const ThisTokBegin;
46  const char *const ThisTokEnd;
47  const char *DigitsBegin, *SuffixBegin// markers
48  const char *s// cursor
49
50  unsigned radix;
51
52  bool saw_exponentsaw_periodsaw_ud_suffixsaw_fixed_point_suffix;
53
54  SmallString<32UDSuffixBuf;
55
56public:
57  NumericLiteralParser(StringRef TokSpelling,
58                       SourceLocation TokLoc,
59                       Preprocessor &PP);
60  bool hadError : 1;
61  bool isUnsigned : 1;
62  bool isLong : 1;          // This is *not* set for long long.
63  bool isLongLong : 1;
64  bool isHalf : 1;          // 1.0h
65  bool isFloat : 1;         // 1.0f
66  bool isImaginary : 1;     // 1.0i
67  bool isFloat16 : 1;       // 1.0f16
68  bool isFloat128 : 1;      // 1.0q
69  uint8_t MicrosoftInteger// Microsoft suffix extension i8, i16, i32, or i64.
70
71  bool isFract : 1;         // 1.0hr/r/lr/uhr/ur/ulr
72  bool isAccum : 1;         // 1.0hk/k/lk/uhk/uk/ulk
73
74  bool isFixedPointLiteral() const { return saw_fixed_point_suffix; }
75
76  bool isIntegerLiteral() const {
77    return !saw_period && !saw_exponent && !isFixedPointLiteral();
78  }
79  bool isFloatingLiteral() const {
80    return (saw_period || saw_exponent) && !isFixedPointLiteral();
81  }
82
83  bool hasUDSuffix() const {
84    return saw_ud_suffix;
85  }
86  StringRef getUDSuffix() const {
87    assert(saw_ud_suffix);
88    return UDSuffixBuf;
89  }
90  unsigned getUDSuffixOffset() const {
91    assert(saw_ud_suffix);
92    return SuffixBegin - ThisTokBegin;
93  }
94
95  static bool isValidUDSuffix(const LangOptions &LangOptsStringRef Suffix);
96
97  unsigned getRadix() const { return radix; }
98
99  /// GetIntegerValue - Convert this numeric literal value to an APInt that
100  /// matches Val's input width.  If there is an overflow (i.e., if the unsigned
101  /// value read is larger than the APInt's bits will hold), set Val to the low
102  /// bits of the result and return true.  Otherwise, return false.
103  bool GetIntegerValue(llvm::APInt &Val);
104
105  /// GetFloatValue - Convert this numeric literal to a floating value, using
106  /// the specified APFloat fltSemantics (specifying float, double, etc).
107  /// The optional bool isExact (passed-by-reference) has its value
108  /// set to true if the returned APFloat can represent the number in the
109  /// literal exactly, and false otherwise.
110  llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result);
111
112  /// GetFixedPointValue - Convert this numeric literal value into a
113  /// scaled integer that represents this value. Returns true if an overflow
114  /// occurred when calculating the integral part of the scaled integer or
115  /// calculating the digit sequence of the exponent.
116  bool GetFixedPointValue(llvm::APInt &StoreValunsigned Scale);
117
118private:
119
120  void ParseNumberStartingWithZero(SourceLocation TokLoc);
121  void ParseDecimalOrOctalCommon(SourceLocation TokLoc);
122
123  static bool isDigitSeparator(char C) { return C == '\''; }
124
125  /// Determine whether the sequence of characters [Start, End) contains
126  /// any real digits (not digit separators).
127  bool containsDigits(const char *Startconst char *End) {
128    return Start != End && (Start + 1 != End || !isDigitSeparator(Start[0]));
129  }
130
131  enum CheckSeparatorKind { CSK_BeforeDigitsCSK_AfterDigits };
132
133  /// Ensure that we don't have a digit separator here.
134  void checkSeparator(SourceLocation TokLocconst char *Pos,
135                      CheckSeparatorKind IsAfterDigits);
136
137  /// SkipHexDigits - Read and skip over any hex digits, up to End.
138  /// Return a pointer to the first non-hex digit or End.
139  const char *SkipHexDigits(const char *ptr) {
140    while (ptr != ThisTokEnd && (isHexDigit(*ptr) || isDigitSeparator(*ptr)))
141      ptr++;
142    return ptr;
143  }
144
145  /// SkipOctalDigits - Read and skip over any octal digits, up to End.
146  /// Return a pointer to the first non-hex digit or End.
147  const char *SkipOctalDigits(const char *ptr) {
148    while (ptr != ThisTokEnd &&
149           ((*ptr >= '0' && *ptr <= '7') || isDigitSeparator(*ptr)))
150      ptr++;
151    return ptr;
152  }
153
154  /// SkipDigits - Read and skip over any digits, up to End.
155  /// Return a pointer to the first non-hex digit or End.
156  const char *SkipDigits(const char *ptr) {
157    while (ptr != ThisTokEnd && (isDigit(*ptr) || isDigitSeparator(*ptr)))
158      ptr++;
159    return ptr;
160  }
161
162  /// SkipBinaryDigits - Read and skip over any binary digits, up to End.
163  /// Return a pointer to the first non-binary digit or End.
164  const char *SkipBinaryDigits(const char *ptr) {
165    while (ptr != ThisTokEnd &&
166           (*ptr == '0' || *ptr == '1' || isDigitSeparator(*ptr)))
167      ptr++;
168    return ptr;
169  }
170
171};
172
173/// CharLiteralParser - Perform interpretation and semantic analysis of a
174/// character literal.
175class CharLiteralParser {
176  uint64_t Value;
177  tok::TokenKind Kind;
178  bool IsMultiChar;
179  bool HadError;
180  SmallString<32UDSuffixBuf;
181  unsigned UDSuffixOffset;
182public:
183  CharLiteralParser(const char *beginconst char *end,
184                    SourceLocation LocPreprocessor &PP,
185                    tok::TokenKind kind);
186
187  bool hadError() const { return HadError; }
188  bool isAscii() const { return Kind == tok::char_constant; }
189  bool isWide() const { return Kind == tok::wide_char_constant; }
190  bool isUTF8() const { return Kind == tok::utf8_char_constant; }
191  bool isUTF16() const { return Kind == tok::utf16_char_constant; }
192  bool isUTF32() const { return Kind == tok::utf32_char_constant; }
193  bool isMultiChar() const { return IsMultiChar; }
194  uint64_t getValue() const { return Value; }
195  StringRef getUDSuffix() const { return UDSuffixBuf; }
196  unsigned getUDSuffixOffset() const {
197     (0) . __assert_fail ("!UDSuffixBuf.empty() && \"no ud-suffix\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/LiteralSupport.h", 197, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!UDSuffixBuf.empty() && "no ud-suffix");
198    return UDSuffixOffset;
199  }
200};
201
202/// StringLiteralParser - This decodes string escape characters and performs
203/// wide string analysis and Translation Phase #6 (concatenation of string
204/// literals) (C99 5.1.1.2p1).
205class StringLiteralParser {
206  const SourceManager &SM;
207  const LangOptions &Features;
208  const TargetInfo &Target;
209  DiagnosticsEngine *Diags;
210
211  unsigned MaxTokenLength;
212  unsigned SizeBound;
213  unsigned CharByteWidth;
214  tok::TokenKind Kind;
215  SmallString<512ResultBuf;
216  char *ResultPtr// cursor
217  SmallString<32UDSuffixBuf;
218  unsigned UDSuffixToken;
219  unsigned UDSuffixOffset;
220public:
221  StringLiteralParser(ArrayRef<TokenStringToks,
222                      Preprocessor &PPbool Complain = true);
223  StringLiteralParser(ArrayRef<TokenStringToks,
224                      const SourceManager &smconst LangOptions &features,
225                      const TargetInfo &target,
226                      DiagnosticsEngine *diags = nullptr)
227    : SM(sm), Features(features), Target(target), Diags(diags),
228      MaxTokenLength(0), SizeBound(0), CharByteWidth(0), Kind(tok::unknown),
229      ResultPtr(ResultBuf.data()), hadError(false), Pascal(false) {
230    init(StringToks);
231  }
232
233
234  bool hadError;
235  bool Pascal;
236
237  StringRef GetString() const {
238    return StringRef(ResultBuf.data(), GetStringLength());
239  }
240  unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); }
241
242  unsigned GetNumStringChars() const {
243    return GetStringLength() / CharByteWidth;
244  }
245  /// getOffsetOfStringByte - This function returns the offset of the
246  /// specified byte of the string data represented by Token.  This handles
247  /// advancing over escape sequences in the string.
248  ///
249  /// If the Diagnostics pointer is non-null, then this will do semantic
250  /// checking of the string literal and emit errors and warnings.
251  unsigned getOffsetOfStringByte(const Token &TheTokunsigned ByteNoconst;
252
253  bool isAscii() const { return Kind == tok::string_literal; }
254  bool isWide() const { return Kind == tok::wide_string_literal; }
255  bool isUTF8() const { return Kind == tok::utf8_string_literal; }
256  bool isUTF16() const { return Kind == tok::utf16_string_literal; }
257  bool isUTF32() const { return Kind == tok::utf32_string_literal; }
258  bool isPascal() const { return Pascal; }
259
260  StringRef getUDSuffix() const { return UDSuffixBuf; }
261
262  /// Get the index of a token containing a ud-suffix.
263  unsigned getUDSuffixToken() const {
264     (0) . __assert_fail ("!UDSuffixBuf.empty() && \"no ud-suffix\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/LiteralSupport.h", 264, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!UDSuffixBuf.empty() && "no ud-suffix");
265    return UDSuffixToken;
266  }
267  /// Get the spelling offset of the first byte of the ud-suffix.
268  unsigned getUDSuffixOffset() const {
269     (0) . __assert_fail ("!UDSuffixBuf.empty() && \"no ud-suffix\"", "/home/seafit/code_projects/clang_source/clang/include/clang/Lex/LiteralSupport.h", 269, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!UDSuffixBuf.empty() && "no ud-suffix");
270    return UDSuffixOffset;
271  }
272
273  static bool isValidUDSuffix(const LangOptions &LangOptsStringRef Suffix);
274
275private:
276  void init(ArrayRef<TokenStringToks);
277  bool CopyStringFragment(const Token &Tokconst char *TokBegin,
278                          StringRef Fragment);
279  void DiagnoseLexingError(SourceLocation Loc);
280};
281
282}  // end namespace clang
283
284#endif
285
clang::NumericLiteralParser::PP
clang::NumericLiteralParser::ThisTokBegin
clang::NumericLiteralParser::ThisTokEnd
clang::NumericLiteralParser::DigitsBegin
clang::NumericLiteralParser::SuffixBegin
clang::NumericLiteralParser::s
clang::NumericLiteralParser::radix
clang::NumericLiteralParser::saw_exponent
clang::NumericLiteralParser::saw_period
clang::NumericLiteralParser::saw_ud_suffix
clang::NumericLiteralParser::saw_fixed_point_suffix
clang::NumericLiteralParser::UDSuffixBuf
clang::NumericLiteralParser::hadError
clang::NumericLiteralParser::isUnsigned
clang::NumericLiteralParser::isLong
clang::NumericLiteralParser::isLongLong
clang::NumericLiteralParser::isHalf
clang::NumericLiteralParser::isFloat
clang::NumericLiteralParser::isImaginary
clang::NumericLiteralParser::isFloat16
clang::NumericLiteralParser::isFloat128
clang::NumericLiteralParser::MicrosoftInteger
clang::NumericLiteralParser::isFract
clang::NumericLiteralParser::isAccum
clang::NumericLiteralParser::isFixedPointLiteral
clang::NumericLiteralParser::isIntegerLiteral
clang::NumericLiteralParser::isFloatingLiteral
clang::NumericLiteralParser::hasUDSuffix
clang::NumericLiteralParser::getUDSuffix
clang::NumericLiteralParser::getUDSuffixOffset
clang::NumericLiteralParser::isValidUDSuffix
clang::NumericLiteralParser::getRadix
clang::NumericLiteralParser::GetIntegerValue
clang::NumericLiteralParser::GetFloatValue
clang::NumericLiteralParser::GetFixedPointValue
clang::NumericLiteralParser::ParseNumberStartingWithZero
clang::NumericLiteralParser::ParseDecimalOrOctalCommon
clang::NumericLiteralParser::isDigitSeparator
clang::NumericLiteralParser::containsDigits
clang::NumericLiteralParser::CheckSeparatorKind
clang::NumericLiteralParser::checkSeparator
clang::NumericLiteralParser::SkipHexDigits
clang::NumericLiteralParser::SkipOctalDigits
clang::NumericLiteralParser::SkipDigits
clang::NumericLiteralParser::SkipBinaryDigits
clang::CharLiteralParser::Value
clang::CharLiteralParser::Kind
clang::CharLiteralParser::IsMultiChar
clang::CharLiteralParser::HadError
clang::CharLiteralParser::UDSuffixBuf
clang::CharLiteralParser::UDSuffixOffset
clang::CharLiteralParser::hadError
clang::CharLiteralParser::isAscii
clang::CharLiteralParser::isWide
clang::CharLiteralParser::isUTF8
clang::CharLiteralParser::isUTF16
clang::CharLiteralParser::isUTF32
clang::CharLiteralParser::isMultiChar
clang::CharLiteralParser::getValue
clang::CharLiteralParser::getUDSuffix
clang::CharLiteralParser::getUDSuffixOffset
clang::StringLiteralParser::SM
clang::StringLiteralParser::Features
clang::StringLiteralParser::Target
clang::StringLiteralParser::Diags
clang::StringLiteralParser::MaxTokenLength
clang::StringLiteralParser::SizeBound
clang::StringLiteralParser::CharByteWidth
clang::StringLiteralParser::Kind
clang::StringLiteralParser::ResultBuf
clang::StringLiteralParser::ResultPtr
clang::StringLiteralParser::UDSuffixBuf
clang::StringLiteralParser::UDSuffixToken
clang::StringLiteralParser::UDSuffixOffset
clang::StringLiteralParser::hadError
clang::StringLiteralParser::Pascal
clang::StringLiteralParser::GetString
clang::StringLiteralParser::GetStringLength
clang::StringLiteralParser::GetNumStringChars
clang::StringLiteralParser::getOffsetOfStringByte
clang::StringLiteralParser::isAscii
clang::StringLiteralParser::isWide
clang::StringLiteralParser::isUTF8
clang::StringLiteralParser::isUTF16
clang::StringLiteralParser::isUTF32
clang::StringLiteralParser::isPascal
clang::StringLiteralParser::getUDSuffix
clang::StringLiteralParser::getUDSuffixToken
clang::StringLiteralParser::getUDSuffixOffset
clang::StringLiteralParser::isValidUDSuffix
clang::StringLiteralParser::init
clang::StringLiteralParser::CopyStringFragment
clang::StringLiteralParser::DiagnoseLexingError