LiteralSupport.h revision c69a505cfa318d571ce8a0cd038c8d958585a735
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 23namespace clang { 24 25class Diagnostic; 26class Preprocessor; 27class Token; 28class SourceLocation; 29class TargetInfo; 30class SourceManager; 31class 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. 36class 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 48public: 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 84private: 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. 124class CharLiteralParser { 125 uint64_t Value; 126 bool IsWide; 127 bool IsMultiChar; 128 bool HadError; 129public: 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). 142class 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 153public: 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 init(StringToks, NumStringToks); 161 } 162 163 164 bool hadError; 165 bool AnyWide; 166 bool Pascal; 167 168 const char *GetString() { return &ResultBuf[0]; } 169 unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; } 170 171 unsigned GetNumStringChars() const { 172 if (AnyWide) 173 return GetStringLength() / wchar_tByteWidth; 174 return GetStringLength(); 175 } 176 /// getOffsetOfStringByte - This function returns the offset of the 177 /// specified byte of the string data represented by Token. This handles 178 /// advancing over escape sequences in the string. 179 /// 180 /// If the Diagnostics pointer is non-null, then this will do semantic 181 /// checking of the string literal and emit errors and warnings. 182 unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const; 183 184private: 185 void init(const Token *StringToks, unsigned NumStringToks); 186}; 187 188} // end namespace clang 189 190#endif 191