LiteralSupport.h revision 686775deca8b8685eb90801495880e3abdd844c2
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 "clang/Basic/LLVM.h" 19#include "llvm/ADT/APFloat.h" 20#include "llvm/ADT/SmallString.h" 21#include "llvm/Support/DataTypes.h" 22#include <cctype> 23 24namespace clang { 25 26class Diagnostic; 27class Preprocessor; 28class Token; 29class SourceLocation; 30class TargetInfo; 31class SourceManager; 32class LangOptions; 33 34/// NumericLiteralParser - This performs strict semantic analysis of the content 35/// of a ppnumber, classifying it as either integer, floating, or erroneous, 36/// determines the radix of the value and can convert it to a useful value. 37class NumericLiteralParser { 38 Preprocessor &PP; // needed for diagnostics 39 40 const char *const ThisTokBegin; 41 const char *const ThisTokEnd; 42 const char *DigitsBegin, *SuffixBegin; // markers 43 const char *s; // cursor 44 45 unsigned radix; 46 47 bool saw_exponent, saw_period; 48 49public: 50 NumericLiteralParser(const char *begin, const char *end, 51 SourceLocation Loc, Preprocessor &PP); 52 bool hadError; 53 bool isUnsigned; 54 bool isLong; // This is *not* set for long long. 55 bool isLongLong; 56 bool isFloat; // 1.0f 57 bool isImaginary; // 1.0i 58 bool isMicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. 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::opStatus GetFloatValue(llvm::APFloat &Result); 84 85private: 86 87 void ParseNumberStartingWithZero(SourceLocation TokLoc); 88 89 /// SkipHexDigits - Read and skip over any hex digits, up to End. 90 /// Return a pointer to the first non-hex digit or End. 91 const char *SkipHexDigits(const char *ptr) { 92 while (ptr != ThisTokEnd && isxdigit(*ptr)) 93 ptr++; 94 return ptr; 95 } 96 97 /// SkipOctalDigits - Read and skip over any octal digits, up to End. 98 /// Return a pointer to the first non-hex digit or End. 99 const char *SkipOctalDigits(const char *ptr) { 100 while (ptr != ThisTokEnd && ((*ptr >= '0') && (*ptr <= '7'))) 101 ptr++; 102 return ptr; 103 } 104 105 /// SkipDigits - Read and skip over any digits, up to End. 106 /// Return a pointer to the first non-hex digit or End. 107 const char *SkipDigits(const char *ptr) { 108 while (ptr != ThisTokEnd && isdigit(*ptr)) 109 ptr++; 110 return ptr; 111 } 112 113 /// SkipBinaryDigits - Read and skip over any binary digits, up to End. 114 /// Return a pointer to the first non-binary digit or End. 115 const char *SkipBinaryDigits(const char *ptr) { 116 while (ptr != ThisTokEnd && (*ptr == '0' || *ptr == '1')) 117 ptr++; 118 return ptr; 119 } 120 121}; 122 123/// CharLiteralParser - Perform interpretation and semantic analysis of a 124/// character literal. 125class CharLiteralParser { 126 uint64_t Value; 127 bool IsWide; 128 bool IsMultiChar; 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 bool isMultiChar() const { return IsMultiChar; } 137 uint64_t getValue() const { return Value; } 138}; 139 140/// StringLiteralParser - This decodes string escape characters and performs 141/// wide string analysis and Translation Phase #6 (concatenation of string 142/// literals) (C99 5.1.1.2p1). 143class StringLiteralParser { 144 const SourceManager &SM; 145 const LangOptions &Features; 146 const TargetInfo &Target; 147 Diagnostic *Diags; 148 149 unsigned MaxTokenLength; 150 unsigned SizeBound; 151 unsigned wchar_tByteWidth; 152 llvm::SmallString<512> ResultBuf; 153 char *ResultPtr; // cursor 154public: 155 StringLiteralParser(const Token *StringToks, unsigned NumStringToks, 156 Preprocessor &PP, bool Complain = true); 157 StringLiteralParser(const Token *StringToks, unsigned NumStringToks, 158 const SourceManager &sm, const LangOptions &features, 159 const TargetInfo &target, Diagnostic *diags = 0) 160 : SM(sm), Features(features), Target(target), Diags(diags), 161 MaxTokenLength(0), SizeBound(0), wchar_tByteWidth(0), 162 ResultPtr(ResultBuf.data()), hadError(false), AnyWide(false), Pascal(false) { 163 init(StringToks, NumStringToks); 164 } 165 166 167 bool hadError; 168 bool AnyWide; 169 bool Pascal; 170 171 StringRef GetString() const { 172 return StringRef(ResultBuf.data(), GetStringLength()); 173 } 174 unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); } 175 176 unsigned GetNumStringChars() const { 177 if (AnyWide) 178 return GetStringLength() / wchar_tByteWidth; 179 return GetStringLength(); 180 } 181 /// getOffsetOfStringByte - This function returns the offset of the 182 /// specified byte of the string data represented by Token. This handles 183 /// advancing over escape sequences in the string. 184 /// 185 /// If the Diagnostics pointer is non-null, then this will do semantic 186 /// checking of the string literal and emit errors and warnings. 187 unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const; 188 189private: 190 void init(const Token *StringToks, unsigned NumStringToks); 191}; 192 193} // end namespace clang 194 195#endif 196