From f27e5a09a0d815b8a4814152954ff87dadfdefc0 Mon Sep 17 00:00:00 2001 From: ed Date: Tue, 2 Jun 2009 17:58:47 +0000 Subject: Import Clang, at r72732. --- include/clang/Lex/LiteralSupport.h | 176 +++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 include/clang/Lex/LiteralSupport.h (limited to 'include/clang/Lex/LiteralSupport.h') diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h new file mode 100644 index 0000000..8ee8ecf --- /dev/null +++ b/include/clang/Lex/LiteralSupport.h @@ -0,0 +1,176 @@ +//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the NumericLiteralParser, CharLiteralParser, and +// StringLiteralParser interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_LITERALSUPPORT_H +#define CLANG_LITERALSUPPORT_H + +#include +#include "llvm/ADT/SmallString.h" + +namespace llvm { + class APInt; + class APFloat; + struct fltSemantics; +} + +namespace clang { + +class Diagnostic; +class Preprocessor; +class Token; +class SourceLocation; +class TargetInfo; + +/// NumericLiteralParser - This performs strict semantic analysis of the content +/// of a ppnumber, classifying it as either integer, floating, or erroneous, +/// determines the radix of the value and can convert it to a useful value. +class NumericLiteralParser { + Preprocessor &PP; // needed for diagnostics + + const char *const ThisTokBegin; + const char *const ThisTokEnd; + const char *DigitsBegin, *SuffixBegin; // markers + const char *s; // cursor + + unsigned radix; + + bool saw_exponent, saw_period; + +public: + NumericLiteralParser(const char *begin, const char *end, + SourceLocation Loc, Preprocessor &PP); + bool hadError; + bool isUnsigned; + bool isLong; // This is *not* set for long long. + bool isLongLong; + bool isFloat; // 1.0f + bool isImaginary; // 1.0i + + bool isIntegerLiteral() const { + return !saw_period && !saw_exponent; + } + bool isFloatingLiteral() const { + return saw_period || saw_exponent; + } + bool hasSuffix() const { + return SuffixBegin != ThisTokEnd; + } + + unsigned getRadix() const { return radix; } + + /// GetIntegerValue - Convert this numeric literal value to an APInt that + /// matches Val's input width. If there is an overflow (i.e., if the unsigned + /// value read is larger than the APInt's bits will hold), set Val to the low + /// bits of the result and return true. Otherwise, return false. + bool GetIntegerValue(llvm::APInt &Val); + + /// GetFloatValue - Convert this numeric literal to a floating value, using + /// the specified APFloat fltSemantics (specifying float, double, etc). + /// The optional bool isExact (passed-by-reference) has its value + /// set to true if the returned APFloat can represent the number in the + /// literal exactly, and false otherwise. + llvm::APFloat GetFloatValue(const llvm::fltSemantics &Format, + bool* isExact = NULL); + +private: + + void ParseNumberStartingWithZero(SourceLocation TokLoc); + + /// SkipHexDigits - Read and skip over any hex digits, up to End. + /// Return a pointer to the first non-hex digit or End. + const char *SkipHexDigits(const char *ptr) { + while (ptr != ThisTokEnd && isxdigit(*ptr)) + ptr++; + return ptr; + } + + /// SkipOctalDigits - Read and skip over any octal digits, up to End. + /// Return a pointer to the first non-hex digit or End. + const char *SkipOctalDigits(const char *ptr) { + while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7'))) + ptr++; + return ptr; + } + + /// SkipDigits - Read and skip over any digits, up to End. + /// Return a pointer to the first non-hex digit or End. + const char *SkipDigits(const char *ptr) { + while (ptr != ThisTokEnd && isdigit(*ptr)) + ptr++; + return ptr; + } + + /// SkipBinaryDigits - Read and skip over any binary digits, up to End. + /// Return a pointer to the first non-binary digit or End. + const char *SkipBinaryDigits(const char *ptr) { + while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1')) + ptr++; + return ptr; + } + +}; + +/// CharLiteralParser - Perform interpretation and semantic analysis of a +/// character literal. +class CharLiteralParser { + uint64_t Value; + bool IsWide; + bool IsMultiChar; + bool HadError; +public: + CharLiteralParser(const char *begin, const char *end, + SourceLocation Loc, Preprocessor &PP); + + bool hadError() const { return HadError; } + bool isWide() const { return IsWide; } + bool isMultiChar() const { return IsMultiChar; } + uint64_t getValue() const { return Value; } +}; + +/// StringLiteralParser - This decodes string escape characters and performs +/// wide string analysis and Translation Phase #6 (concatenation of string +/// literals) (C99 5.1.1.2p1). +class StringLiteralParser { + Preprocessor &PP; + + unsigned MaxTokenLength; + unsigned SizeBound; + unsigned wchar_tByteWidth; + llvm::SmallString<512> ResultBuf; + char *ResultPtr; // cursor +public: + StringLiteralParser(const Token *StringToks, unsigned NumStringToks, + Preprocessor &PP); + bool hadError; + bool AnyWide; + bool Pascal; + + const char *GetString() { return &ResultBuf[0]; } + unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; } + + unsigned GetNumStringChars() const { + if (AnyWide) + return GetStringLength() / wchar_tByteWidth; + return GetStringLength(); + } + /// getOffsetOfStringByte - This function returns the offset of the + /// specified byte of the string data represented by Token. This handles + /// advancing over escape sequences in the string. + static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo, + Preprocessor &PP); +}; + +} // end namespace clang + +#endif -- cgit v1.1