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