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