LiteralSupport.h revision 4bc11af9bed1d4a247e3db1fcb754d410ad99099
1//===--- LiteralSupport.h ---------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the NumericLiteralParser, CharLiteralParser, and 11// StringLiteralParser interfaces. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef CLANG_LITERALSUPPORT_H 16#define CLANG_LITERALSUPPORT_H 17 18#include <string> 19#include "llvm/ADT/SmallString.h" 20 21namespace llvm { 22 class APInt; 23 class APFloat; 24 struct fltSemantics; 25} 26 27namespace clang { 28 29class Diagnostic; 30class Preprocessor; 31class Token; 32class SourceLocation; 33class TargetInfo; 34 35/// NumericLiteralParser - This performs strict semantic analysis of the content 36/// of a ppnumber, classifying it as either integer, floating, or erroneous, 37/// determines the radix of the value and can convert it to a useful value. 38class NumericLiteralParser { 39 Preprocessor &PP; // needed for diagnostics 40 41 const char *const ThisTokBegin; 42 const char *const ThisTokEnd; 43 const char *DigitsBegin, *SuffixBegin; // markers 44 const char *s; // cursor 45 46 unsigned radix; 47 48 bool saw_exponent, saw_period; 49 50public: 51 NumericLiteralParser(const char *begin, const char *end, 52 SourceLocation Loc, Preprocessor &PP); 53 bool hadError; 54 bool isUnsigned; 55 bool isLong; // This is *not* set for long long. 56 bool isLongLong; 57 bool isFloat; // 1.0f 58 bool isImaginary; // 1.0i 59 60 bool isIntegerLiteral() const { 61 return !saw_period && !saw_exponent; 62 } 63 bool isFloatingLiteral() const { 64 return saw_period || saw_exponent; 65 } 66 bool hasSuffix() const { 67 return SuffixBegin != ThisTokEnd; 68 } 69 70 unsigned getRadix() const { return radix; } 71 72 /// GetIntegerValue - Convert this numeric literal value to an APInt that 73 /// matches Val's input width. If there is an overflow (i.e., if the unsigned 74 /// value read is larger than the APInt's bits will hold), set Val to the low 75 /// bits of the result and return true. Otherwise, return false. 76 bool GetIntegerValue(llvm::APInt &Val); 77 78 /// GetFloatValue - Convert this numeric literal to a floating value, using 79 /// the specified APFloat fltSemantics (specifying float, double, etc). 80 /// The optional bool isExact (passed-by-reference) has its value 81 /// set to true if the returned APFloat can represent the number in the 82 /// literal exactly, and false otherwise. 83 llvm::APFloat GetFloatValue(const llvm::fltSemantics &Format, 84 bool* isExact = NULL); 85 86private: 87 88 void ParseNumberStartingWithZero(SourceLocation TokLoc); 89 90 /// SkipHexDigits - Read and skip over any hex digits, up to End. 91 /// Return a pointer to the first non-hex digit or End. 92 const char *SkipHexDigits(const char *ptr) { 93 while (ptr != ThisTokEnd && isxdigit(*ptr)) 94 ptr++; 95 return ptr; 96 } 97 98 /// SkipOctalDigits - Read and skip over any octal digits, up to End. 99 /// Return a pointer to the first non-hex digit or End. 100 const char *SkipOctalDigits(const char *ptr) { 101 while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7'))) 102 ptr++; 103 return ptr; 104 } 105 106 /// SkipDigits - Read and skip over any digits, up to End. 107 /// Return a pointer to the first non-hex digit or End. 108 const char *SkipDigits(const char *ptr) { 109 while (ptr != ThisTokEnd && isdigit(*ptr)) 110 ptr++; 111 return ptr; 112 } 113 114 /// SkipBinaryDigits - Read and skip over any binary digits, up to End. 115 /// Return a pointer to the first non-binary digit or End. 116 const char *SkipBinaryDigits(const char *ptr) { 117 while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1')) 118 ptr++; 119 return ptr; 120 } 121 122}; 123 124/// CharLiteralParser - Perform interpretation and semantic analysis of a 125/// character literal. 126class CharLiteralParser { 127 uint64_t Value; 128 bool IsWide; 129 bool HadError; 130public: 131 CharLiteralParser(const char *begin, const char *end, 132 SourceLocation Loc, Preprocessor &PP); 133 134 bool hadError() const { return HadError; } 135 bool isWide() const { return IsWide; } 136 uint64_t getValue() const { return Value; } 137}; 138 139/// StringLiteralParser - This decodes string escape characters and performs 140/// wide string analysis and Translation Phase #6 (concatenation of string 141/// literals) (C99 5.1.1.2p1). 142class StringLiteralParser { 143 Preprocessor &PP; 144 145 unsigned MaxTokenLength; 146 unsigned SizeBound; 147 unsigned wchar_tByteWidth; 148 llvm::SmallString<512> ResultBuf; 149 char *ResultPtr; // cursor 150public: 151 StringLiteralParser(const Token *StringToks, unsigned NumStringToks, 152 Preprocessor &PP); 153 bool hadError; 154 bool AnyWide; 155 bool Pascal; 156 157 const char *GetString() { return &ResultBuf[0]; } 158 unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; } 159 160 unsigned GetNumStringChars() const { 161 if (AnyWide) 162 return GetStringLength() / wchar_tByteWidth; 163 return GetStringLength(); 164 } 165 /// getOffsetOfStringByte - This function returns the offset of the 166 /// specified byte of the string data represented by Token. This handles 167 /// advancing over escape sequences in the string. 168 static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo, 169 Preprocessor &PP); 170}; 171 172} // end namespace clang 173 174#endif 175