diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
20 files changed, 1296 insertions, 863 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp index c78a292..242c204 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp @@ -13,8 +13,8 @@ #include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetInfo.h" #include "llvm/ADT/SmallVector.h" using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/Basic/CharInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/CharInfo.cpp new file mode 100644 index 0000000..32b3277 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/CharInfo.cpp @@ -0,0 +1,81 @@ +//===--- CharInfo.cpp - Static Data for Classifying ASCII Characters ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/CharInfo.h" + +using namespace clang::charinfo; + +// Statically initialize CharInfo table based on ASCII character set +// Reference: FreeBSD 7.2 /usr/share/misc/ascii +const uint16_t clang::charinfo::InfoTable[256] = { + // 0 NUL 1 SOH 2 STX 3 ETX + // 4 EOT 5 ENQ 6 ACK 7 BEL + 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , + // 8 BS 9 HT 10 NL 11 VT + //12 NP 13 CR 14 SO 15 SI + 0 , CHAR_HORZ_WS, CHAR_VERT_WS, CHAR_HORZ_WS, + CHAR_HORZ_WS, CHAR_VERT_WS, 0 , 0 , + //16 DLE 17 DC1 18 DC2 19 DC3 + //20 DC4 21 NAK 22 SYN 23 ETB + 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , + //24 CAN 25 EM 26 SUB 27 ESC + //28 FS 29 GS 30 RS 31 US + 0 , 0 , 0 , 0 , + 0 , 0 , 0 , 0 , + //32 SP 33 ! 34 " 35 # + //36 $ 37 % 38 & 39 ' + CHAR_SPACE , CHAR_RAWDEL , CHAR_RAWDEL , CHAR_RAWDEL , + CHAR_PUNCT , CHAR_RAWDEL , CHAR_RAWDEL , CHAR_RAWDEL , + //40 ( 41 ) 42 * 43 + + //44 , 45 - 46 . 47 / + CHAR_PUNCT , CHAR_PUNCT , CHAR_RAWDEL , CHAR_RAWDEL , + CHAR_RAWDEL , CHAR_RAWDEL , CHAR_PERIOD , CHAR_RAWDEL , + //48 0 49 1 50 2 51 3 + //52 4 53 5 54 6 55 7 + CHAR_DIGIT , CHAR_DIGIT , CHAR_DIGIT , CHAR_DIGIT , + CHAR_DIGIT , CHAR_DIGIT , CHAR_DIGIT , CHAR_DIGIT , + //56 8 57 9 58 : 59 ; + //60 < 61 = 62 > 63 ? + CHAR_DIGIT , CHAR_DIGIT , CHAR_RAWDEL , CHAR_RAWDEL , + CHAR_RAWDEL , CHAR_RAWDEL , CHAR_RAWDEL , CHAR_RAWDEL , + //64 @ 65 A 66 B 67 C + //68 D 69 E 70 F 71 G + CHAR_PUNCT , CHAR_XUPPER , CHAR_XUPPER , CHAR_XUPPER , + CHAR_XUPPER , CHAR_XUPPER , CHAR_XUPPER , CHAR_UPPER , + //72 H 73 I 74 J 75 K + //76 L 77 M 78 N 79 O + CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , + CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , + //80 P 81 Q 82 R 83 S + //84 T 85 U 86 V 87 W + CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , + CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , + //88 X 89 Y 90 Z 91 [ + //92 \ 93 ] 94 ^ 95 _ + CHAR_UPPER , CHAR_UPPER , CHAR_UPPER , CHAR_RAWDEL , + CHAR_PUNCT , CHAR_RAWDEL , CHAR_RAWDEL , CHAR_UNDER , + //96 ` 97 a 98 b 99 c + //100 d 101 e 102 f 103 g + CHAR_PUNCT , CHAR_XLOWER , CHAR_XLOWER , CHAR_XLOWER , + CHAR_XLOWER , CHAR_XLOWER , CHAR_XLOWER , CHAR_LOWER , + //104 h 105 i 106 j 107 k + //108 l 109 m 110 n 111 o + CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , + CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , + //112 p 113 q 114 r 115 s + //116 t 117 u 118 v 119 w + CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , + CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , + //120 x 121 y 122 z 123 { + //124 | 125 } 126 ~ 127 DEL + CHAR_LOWER , CHAR_LOWER , CHAR_LOWER , CHAR_RAWDEL , + CHAR_RAWDEL , CHAR_RAWDEL , CHAR_RAWDEL , 0 +}; diff --git a/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c b/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c deleted file mode 100644 index d16965d..0000000 --- a/contrib/llvm/tools/clang/lib/Basic/ConvertUTF.c +++ /dev/null @@ -1,571 +0,0 @@ -/*===--- ConvertUTF.c - Universal Character Names conversions ---------------=== - * - * The LLVM Compiler Infrastructure - * - * This file is distributed under the University of Illinois Open Source - * License. See LICENSE.TXT for details. - * - *===------------------------------------------------------------------------=*/ -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - -/* --------------------------------------------------------------------- - - Conversions between UTF32, UTF-16, and UTF-8. Source code file. - Author: Mark E. Davis, 1994. - Rev History: Rick McGowan, fixes & updates May 2001. - Sept 2001: fixed const & error conditions per - mods suggested by S. Parent & A. Lillich. - June 2002: Tim Dodd added detection and handling of incomplete - source sequences, enhanced error detection, added casts - to eliminate compiler warnings. - July 2003: slight mods to back out aggressive FFFE detection. - Jan 2004: updated switches in from-UTF8 conversions. - Oct 2004: updated to use UNI_MAX_LEGAL_UTF32 in UTF-32 conversions. - - See the header file "ConvertUTF.h" for complete documentation. - ------------------------------------------------------------------------- */ - - -#include "clang/Basic/ConvertUTF.h" -#ifdef CVTUTF_DEBUG -#include <stdio.h> -#endif - -static const int halfShift = 10; /* used for shifting by 10 bits */ - -static const UTF32 halfBase = 0x0010000UL; -static const UTF32 halfMask = 0x3FFUL; - -#define UNI_SUR_HIGH_START (UTF32)0xD800 -#define UNI_SUR_HIGH_END (UTF32)0xDBFF -#define UNI_SUR_LOW_START (UTF32)0xDC00 -#define UNI_SUR_LOW_END (UTF32)0xDFFF -#define false 0 -#define true 1 - -/* --------------------------------------------------------------------- */ - -/* - * Index into the table below with the first byte of a UTF-8 sequence to - * get the number of trailing bytes that are supposed to follow it. - * Note that *legal* UTF-8 values can't have 4 or 5-bytes. The table is - * left as-is for anyone who may want to do such conversion, which was - * allowed in earlier algorithms. - */ -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -/* - * Magic values subtracted from a buffer value during UTF8 conversion. - * This table contains as many values as there might be trailing bytes - * in a UTF-8 sequence. - */ -static const UTF32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -/* - * Once the bits are split out into bytes of UTF-8, this is a mask OR-ed - * into the first byte, depending on how many bytes follow. There are - * as many entries in this table as there are UTF-8 sequence types. - * (I.e., one byte sequence, two byte... etc.). Remember that sequencs - * for *legal* UTF-8 will be 4 or fewer bytes total. - */ -static const UTF8 firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -/* --------------------------------------------------------------------- */ - -/* The interface converts a whole buffer to avoid function-call overhead. - * Constants have been gathered. Loops & conditionals have been removed as - * much as possible for efficiency, in favor of drop-through switches. - * (See "Note A" at the bottom of the file for equivalent code.) - * If your compiler supports it, the "isLegalUTF8" call can be turned - * into an inline function. - */ - - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF16 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - if (target >= targetEnd) { - result = targetExhausted; break; - } - ch = *source++; - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_LEGAL_UTF32) { - if (flags == strictConversion) { - result = sourceIllegal; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - --source; /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF16toUTF32 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF32* target = *targetStart; - UTF32 ch, ch2; - while (source < sourceEnd) { - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - if (target >= targetEnd) { - source = oldSource; /* Back up source pointer! */ - result = targetExhausted; break; - } - *target++ = ch; - } - *sourceStart = source; - *targetStart = target; -#ifdef CVTUTF_DEBUG -if (result == sourceIllegal) { - fprintf(stderr, "ConvertUTF16toUTF32 illegal seq 0x%04x,%04x\n", ch, ch2); - fflush(stderr); -} -#endif - return result; -} -ConversionResult ConvertUTF16toUTF8 ( - const UTF16** sourceStart, const UTF16* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF16* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - const UTF16* oldSource = source; /* In case we have to back up because of target overflow. */ - ch = *source++; - /* If we have a surrogate pair, convert to UTF32 first. */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_HIGH_END) { - /* If the 16 bits following the high surrogate are in the source buffer... */ - if (source < sourceEnd) { - UTF32 ch2 = *source; - /* If it's a low surrogate, convert to UTF32. */ - if (ch2 >= UNI_SUR_LOW_START && ch2 <= UNI_SUR_LOW_END) { - ch = ((ch - UNI_SUR_HIGH_START) << halfShift) - + (ch2 - UNI_SUR_LOW_START) + halfBase; - ++source; - } else if (flags == strictConversion) { /* it's an unpaired high surrogate */ - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } else { /* We don't have the 16 bits following the high surrogate. */ - --source; /* return to the high surrogate */ - result = sourceExhausted; - break; - } - } else if (flags == strictConversion) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_LOW_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* Figure out how many bytes the result will require */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch < (UTF32)0x110000) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF32toUTF8 ( - const UTF32** sourceStart, const UTF32* sourceEnd, - UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF32* source = *sourceStart; - UTF8* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch; - unsigned short bytesToWrite = 0; - const UTF32 byteMask = 0xBF; - const UTF32 byteMark = 0x80; - ch = *source++; - if (flags == strictConversion ) { - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - --source; /* return to the illegal value itself */ - result = sourceIllegal; - break; - } - } - /* - * Figure out how many bytes the result will require. Turn any - * illegally large UTF32 things (> Plane 17) into replacement chars. - */ - if (ch < (UTF32)0x80) { bytesToWrite = 1; - } else if (ch < (UTF32)0x800) { bytesToWrite = 2; - } else if (ch < (UTF32)0x10000) { bytesToWrite = 3; - } else if (ch <= UNI_MAX_LEGAL_UTF32) { bytesToWrite = 4; - } else { bytesToWrite = 3; - ch = UNI_REPLACEMENT_CHAR; - result = sourceIllegal; - } - - target += bytesToWrite; - if (target > targetEnd) { - --source; /* Back up source pointer! */ - target -= bytesToWrite; result = targetExhausted; break; - } - switch (bytesToWrite) { /* note: everything falls through. */ - case 4: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (UTF8)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (UTF8) (ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -/* - * Utility routine to tell whether a sequence of bytes is legal UTF-8. - * This must be called with the length pre-determined by the first byte. - * If not calling this from ConvertUTF8to*, then the length can be set by: - * length = trailingBytesForUTF8[*source]+1; - * and the sequence is illegal right away if there aren't that many bytes - * available. - * If presented with a length > 4, this returns false. The Unicode - * definition of UTF-8 goes up to 4-byte sequences. - */ - -static Boolean isLegalUTF8(const UTF8 *source, int length) { - UTF8 a; - const UTF8 *srcptr = source+length; - switch (length) { - default: return false; - /* Everything else falls through when "true"... */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) return false; - return true; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 sequence is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd) { - int length = trailingBytesForUTF8[*source]+1; - if (length > sourceEnd - source) { - return false; - } - return isLegalUTF8(source, length); -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return the total number of bytes in a codepoint - * represented in UTF-8, given the value of the first byte. - */ -unsigned getNumBytesForUTF8(UTF8 first) { - return trailingBytesForUTF8[first] + 1; -} - -/* --------------------------------------------------------------------- */ - -/* - * Exported function to return whether a UTF-8 string is legal or not. - * This is not used here; it's just exported. - */ -Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd) { - while (*source != sourceEnd) { - int length = trailingBytesForUTF8[**source] + 1; - if (length > sourceEnd - *source || !isLegalUTF8(*source, length)) - return false; - *source += length; - } - return true; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF16 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF16* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (extraBytesToRead >= sourceEnd - source) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */ - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */ - /* UTF-16 surrogate values are illegal in UTF-32 */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = (UTF16)ch; /* normal case */ - } - } else if (ch > UNI_MAX_UTF16) { - if (flags == strictConversion) { - result = sourceIllegal; - source -= (extraBytesToRead+1); /* return to the start */ - break; /* Bail out; shouldn't continue */ - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - /* target is a character in range 0xFFFF - 0x10FFFF. */ - if (target + 1 >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up source pointer! */ - result = targetExhausted; break; - } - ch -= halfBase; - *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START); - *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START); - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- */ - -ConversionResult ConvertUTF8toUTF32 ( - const UTF8** sourceStart, const UTF8* sourceEnd, - UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) { - ConversionResult result = conversionOK; - const UTF8* source = *sourceStart; - UTF32* target = *targetStart; - while (source < sourceEnd) { - UTF32 ch = 0; - unsigned short extraBytesToRead = trailingBytesForUTF8[*source]; - if (extraBytesToRead >= sourceEnd - source) { - result = sourceExhausted; break; - } - /* Do this check whether lenient or strict */ - if (!isLegalUTF8(source, extraBytesToRead+1)) { - result = sourceIllegal; - break; - } - /* - * The cases all fall through. See "Note A" below. - */ - switch (extraBytesToRead) { - case 5: ch += *source++; ch <<= 6; - case 4: ch += *source++; ch <<= 6; - case 3: ch += *source++; ch <<= 6; - case 2: ch += *source++; ch <<= 6; - case 1: ch += *source++; ch <<= 6; - case 0: ch += *source++; - } - ch -= offsetsFromUTF8[extraBytesToRead]; - - if (target >= targetEnd) { - source -= (extraBytesToRead+1); /* Back up the source pointer! */ - result = targetExhausted; break; - } - if (ch <= UNI_MAX_LEGAL_UTF32) { - /* - * UTF-16 surrogate values are illegal in UTF-32, and anything - * over Plane 17 (> 0x10FFFF) is illegal. - */ - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) { - if (flags == strictConversion) { - source -= (extraBytesToRead+1); /* return to the illegal value itself */ - result = sourceIllegal; - break; - } else { - *target++ = UNI_REPLACEMENT_CHAR; - } - } else { - *target++ = ch; - } - } else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */ - result = sourceIllegal; - *target++ = UNI_REPLACEMENT_CHAR; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -/* --------------------------------------------------------------------- - - Note A. - The fall-through switches in UTF-8 reading code save a - temp variable, some decrements & conditionals. The switches - are equivalent to the following loop: - { - int tmpBytesToRead = extraBytesToRead+1; - do { - ch += *source++; - --tmpBytesToRead; - if (tmpBytesToRead) ch <<= 6; - } while (tmpBytesToRead > 0); - } - In UTF-8 writing code, the switches on "bytesToWrite" are - similarly unrolled loops. - - --------------------------------------------------------------------- */ diff --git a/contrib/llvm/tools/clang/lib/Basic/ConvertUTFWrapper.cpp b/contrib/llvm/tools/clang/lib/Basic/ConvertUTFWrapper.cpp deleted file mode 100644 index 6be3828..0000000 --- a/contrib/llvm/tools/clang/lib/Basic/ConvertUTFWrapper.cpp +++ /dev/null @@ -1,76 +0,0 @@ -//===-- ConvertUTFWrapper.cpp - Wrap ConvertUTF.h with clang data types -----=== -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "clang/Basic/ConvertUTF.h" -#include "clang/Basic/LLVM.h" - -namespace clang { - -bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source, - char *&ResultPtr, const UTF8 *&ErrorPtr) { - assert(WideCharWidth == 1 || WideCharWidth == 2 || WideCharWidth == 4); - ConversionResult result = conversionOK; - // Copy the character span over. - if (WideCharWidth == 1) { - const UTF8 *Pos = reinterpret_cast<const UTF8*>(Source.begin()); - if (!isLegalUTF8String(&Pos, reinterpret_cast<const UTF8*>(Source.end()))) { - result = sourceIllegal; - ErrorPtr = Pos; - } else { - memcpy(ResultPtr, Source.data(), Source.size()); - ResultPtr += Source.size(); - } - } else if (WideCharWidth == 2) { - const UTF8 *sourceStart = (const UTF8*)Source.data(); - // FIXME: Make the type of the result buffer correct instead of - // using reinterpret_cast. - UTF16 *targetStart = reinterpret_cast<UTF16*>(ResultPtr); - ConversionFlags flags = strictConversion; - result = ConvertUTF8toUTF16( - &sourceStart, sourceStart + Source.size(), - &targetStart, targetStart + 2*Source.size(), flags); - if (result == conversionOK) - ResultPtr = reinterpret_cast<char*>(targetStart); - else - ErrorPtr = sourceStart; - } else if (WideCharWidth == 4) { - const UTF8 *sourceStart = (const UTF8*)Source.data(); - // FIXME: Make the type of the result buffer correct instead of - // using reinterpret_cast. - UTF32 *targetStart = reinterpret_cast<UTF32*>(ResultPtr); - ConversionFlags flags = strictConversion; - result = ConvertUTF8toUTF32( - &sourceStart, sourceStart + Source.size(), - &targetStart, targetStart + 4*Source.size(), flags); - if (result == conversionOK) - ResultPtr = reinterpret_cast<char*>(targetStart); - else - ErrorPtr = sourceStart; - } - assert((result != targetExhausted) - && "ConvertUTF8toUTFXX exhausted target buffer"); - return result == conversionOK; -} - -bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr) { - const UTF32 *SourceStart = &Source; - const UTF32 *SourceEnd = SourceStart + 1; - UTF8 *TargetStart = reinterpret_cast<UTF8 *>(ResultPtr); - UTF8 *TargetEnd = TargetStart + 4; - ConversionResult CR = ConvertUTF32toUTF8(&SourceStart, SourceEnd, - &TargetStart, TargetEnd, - strictConversion); - if (CR != conversionOK) - return false; - - ResultPtr = reinterpret_cast<char*>(TargetStart); - return true; -} - -} // end namespace clang diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp index 854c4c5..842bacb 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp @@ -11,15 +11,15 @@ // //===----------------------------------------------------------------------===// +#include "clang/Basic/CharInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/PartialDiagnostic.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/CrashRecoveryContext.h" -#include <cctype> +#include "llvm/Support/raw_ostream.h" using namespace clang; @@ -97,6 +97,7 @@ bool DiagnosticsEngine::popMappings(SourceLocation Loc) { void DiagnosticsEngine::Reset() { ErrorOccurred = false; + UncompilableErrorOccurred = false; FatalErrorOccurred = false; UnrecoverableErrorOccurred = false; @@ -107,11 +108,7 @@ void DiagnosticsEngine::Reset() { TrapNumUnrecoverableErrorsOccurred = 0; CurDiagID = ~0U; - // Set LastDiagLevel to an "unset" state. If we set it to 'Ignored', notes - // using a DiagnosticsEngine associated to a translation unit that follow - // diagnostics from a DiagnosticsEngine associated to anoter t.u. will not be - // displayed. - LastDiagLevel = (DiagnosticIDs::Level)-1; + LastDiagLevel = DiagnosticIDs::Ignored; DelayedDiagID = 0; // Clear state related to #pragma diagnostic. @@ -237,7 +234,7 @@ bool DiagnosticsEngine::setDiagnosticGroupMapping( StringRef Group, diag::Mapping Map, SourceLocation Loc) { // Get the diagnostics in this group. - llvm::SmallVector<diag::kind, 8> GroupDiags; + SmallVector<diag::kind, 8> GroupDiags; if (Diags->getDiagnosticsInGroup(Group, GroupDiags)) return true; @@ -277,7 +274,7 @@ bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group, // potentially downgrade anything already mapped to be a warning. // Get the diagnostics in this group. - llvm::SmallVector<diag::kind, 8> GroupDiags; + SmallVector<diag::kind, 8> GroupDiags; if (Diags->getDiagnosticsInGroup(Group, GroupDiags)) return true; @@ -324,7 +321,7 @@ bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, // potentially downgrade anything already mapped to be an error. // Get the diagnostics in this group. - llvm::SmallVector<diag::kind, 8> GroupDiags; + SmallVector<diag::kind, 8> GroupDiags; if (Diags->getDiagnosticsInGroup(Group, GroupDiags)) return true; @@ -345,7 +342,7 @@ bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group, void DiagnosticsEngine::setMappingToAllDiagnostics(diag::Mapping Map, SourceLocation Loc) { // Get all the diagnostics. - llvm::SmallVector<diag::kind, 64> AllDiags; + SmallVector<diag::kind, 64> AllDiags; Diags->getAllDiagnostics(AllDiags); // Set the mapping. @@ -460,8 +457,8 @@ static const char *ScanFormat(const char *I, const char *E, char Target) { // Escaped characters get implicitly skipped here. // Format specifier. - if (!isdigit(*I) && !ispunct(*I)) { - for (I++; I != E && !isdigit(*I) && *I != '{'; I++) ; + if (!isDigit(*I) && !isPunctuation(*I)) { + for (I++; I != E && !isDigit(*I) && *I != '{'; I++) ; if (I == E) break; if (*I == '{') Depth++; @@ -685,7 +682,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr.append(DiagStr, StrEnd); DiagStr = StrEnd; continue; - } else if (ispunct(DiagStr[1])) { + } else if (isPunctuation(DiagStr[1])) { OutStr.push_back(DiagStr[1]); // %% -> %. DiagStr += 2; continue; @@ -703,7 +700,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, unsigned ModifierLen = 0, ArgumentLen = 0; // Check to see if we have a modifier. If so eat it. - if (!isdigit(DiagStr[0])) { + if (!isDigit(DiagStr[0])) { Modifier = DiagStr; while (DiagStr[0] == '-' || (DiagStr[0] >= 'a' && DiagStr[0] <= 'z')) @@ -722,22 +719,40 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, } } - assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic"); + assert(isDigit(*DiagStr) && "Invalid format for argument in diagnostic"); unsigned ArgNo = *DiagStr++ - '0'; // Only used for type diffing. unsigned ArgNo2 = ArgNo; DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo); - if (Kind == DiagnosticsEngine::ak_qualtype && - ModifierIs(Modifier, ModifierLen, "diff")) { - Kind = DiagnosticsEngine::ak_qualtype_pair; - assert(*DiagStr == ',' && isdigit(*(DiagStr + 1)) && + if (ModifierIs(Modifier, ModifierLen, "diff")) { + assert(*DiagStr == ',' && isDigit(*(DiagStr + 1)) && "Invalid format for diff modifier"); ++DiagStr; // Comma. ArgNo2 = *DiagStr++ - '0'; - assert(getArgKind(ArgNo2) == DiagnosticsEngine::ak_qualtype && - "Second value of type diff must be a qualtype"); + DiagnosticsEngine::ArgumentKind Kind2 = getArgKind(ArgNo2); + if (Kind == DiagnosticsEngine::ak_qualtype && + Kind2 == DiagnosticsEngine::ak_qualtype) + Kind = DiagnosticsEngine::ak_qualtype_pair; + else { + // %diff only supports QualTypes. For other kinds of arguments, + // use the default printing. For example, if the modifier is: + // "%diff{compare $ to $|other text}1,2" + // treat it as: + // "compare %1 to %2" + const char *Pipe = ScanFormat(Argument, Argument + ArgumentLen, '|'); + const char *FirstDollar = ScanFormat(Argument, Pipe, '$'); + const char *SecondDollar = ScanFormat(FirstDollar + 1, Pipe, '$'); + const char ArgStr1[] = { '%', static_cast<char>('0' + ArgNo) }; + const char ArgStr2[] = { '%', static_cast<char>('0' + ArgNo2) }; + FormatDiagnostic(Argument, FirstDollar, OutStr); + FormatDiagnostic(ArgStr1, ArgStr1 + 2, OutStr); + FormatDiagnostic(FirstDollar + 1, SecondDollar, OutStr); + FormatDiagnostic(ArgStr2, ArgStr2 + 2, OutStr); + FormatDiagnostic(SecondDollar + 1, Pipe, OutStr); + continue; + } } switch (Kind) { @@ -940,11 +955,10 @@ StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, StringRef Message, FullSourceLoc Loc, ArrayRef<CharSourceRange> Ranges, - ArrayRef<FixItHint> Fixits) - : ID(ID), Level(Level), Loc(Loc), Message(Message) + ArrayRef<FixItHint> FixIts) + : ID(ID), Level(Level), Loc(Loc), Message(Message), + Ranges(Ranges.begin(), Ranges.end()), FixIts(FixIts.begin(), FixIts.end()) { - this->Ranges.assign(Ranges.begin(), Ranges.end()); - this->FixIts.assign(FixIts.begin(), FixIts.end()); } StoredDiagnostic::~StoredDiagnostic() { } diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp index ed97643..353af4b 100644 --- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp @@ -17,7 +17,6 @@ #include "clang/Basic/SourceManager.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" - #include <map> using namespace clang; @@ -108,16 +107,51 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) { } #endif - // Search the diagnostic table with a binary search. - StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID), - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + // Out of bounds diag. Can't be in the table. + using namespace diag; + if (DiagID >= DIAG_UPPER_LIMIT) + return 0; - const StaticDiagInfoRec *Found = - std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find); - if (Found == StaticDiagInfo + StaticDiagInfoSize || - Found->DiagID != DiagID) + // Compute the index of the requested diagnostic in the static table. + // 1. Add the number of diagnostics in each category preceeding the + // diagnostic and of the category the diagnostic is in. This gives us + // the offset of the category in the table. + // 2. Subtract the number of IDs in each category from our ID. This gives us + // the offset of the diagnostic in the category. + // This is cheaper than a binary search on the table as it doesn't touch + // memory at all. + unsigned Offset = 0; + unsigned ID = DiagID; +#define DIAG_START_COMMON 0 // Sentinel value. +#define CATEGORY(NAME, PREV) \ + if (DiagID > DIAG_START_##NAME) { \ + Offset += NUM_BUILTIN_##PREV##_DIAGNOSTICS - DIAG_START_##PREV - 1; \ + ID -= DIAG_START_##NAME - DIAG_START_##PREV; \ + } +CATEGORY(DRIVER, COMMON) +CATEGORY(FRONTEND, DRIVER) +CATEGORY(SERIALIZATION, FRONTEND) +CATEGORY(LEX, SERIALIZATION) +CATEGORY(PARSE, LEX) +CATEGORY(AST, PARSE) +CATEGORY(COMMENT, AST) +CATEGORY(SEMA, COMMENT) +CATEGORY(ANALYSIS, SEMA) +#undef CATEGORY +#undef DIAG_START_COMMON + + // Avoid out of bounds reads. + if (ID + Offset >= StaticDiagInfoSize) return 0; + assert(ID < StaticDiagInfoSize && Offset < StaticDiagInfoSize); + + const StaticDiagInfoRec *Found = &StaticDiagInfo[ID + Offset]; + // If the diag id doesn't match we found a different diag, abort. This can + // happen when this function is called with an ID that points into a hole in + // the diagID space. + if (Found->DiagID != DiagID) + return 0; return Found; } @@ -247,14 +281,14 @@ namespace clang { /// diagnostic. StringRef getDescription(unsigned DiagID) const { assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && - "Invalid diagnosic ID"); + "Invalid diagnostic ID"); return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second; } /// getLevel - Return the level of the specified custom diagnostic. DiagnosticIDs::Level getLevel(unsigned DiagID) const { assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() && - "Invalid diagnosic ID"); + "Invalid diagnostic ID"); return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first; } @@ -291,7 +325,7 @@ DiagnosticIDs::~DiagnosticIDs() { } /// getCustomDiagID - Return an ID for a diagnostic with the specified message -/// and level. If this is the first request for this diagnosic, it is +/// and level. If this is the first request for this diagnostic, it is /// registered and created, otherwise the existing ID is returned. unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef Message) { if (CustomDiagInfo == 0) @@ -512,9 +546,8 @@ StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) { } void DiagnosticIDs::getDiagnosticsInGroup( - const WarningOption *Group, - llvm::SmallVectorImpl<diag::kind> &Diags) const -{ + const WarningOption *Group, + SmallVectorImpl<diag::kind> &Diags) const { // Add the members of the option diagnostic set. if (const short *Member = Group->Members) { for (; *Member != -1; ++Member) @@ -529,9 +562,8 @@ void DiagnosticIDs::getDiagnosticsInGroup( } bool DiagnosticIDs::getDiagnosticsInGroup( - StringRef Group, - llvm::SmallVectorImpl<diag::kind> &Diags) const -{ + StringRef Group, + SmallVectorImpl<diag::kind> &Diags) const { WarningOption Key = { Group.size(), Group.data(), 0, 0 }; const WarningOption *Found = std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key, @@ -545,7 +577,7 @@ bool DiagnosticIDs::getDiagnosticsInGroup( } void DiagnosticIDs::getAllDiagnostics( - llvm::SmallVectorImpl<diag::kind> &Diags) const { + SmallVectorImpl<diag::kind> &Diags) const { for (unsigned i = 0; i != StaticDiagInfoSize; ++i) Diags.push_back(StaticDiagInfo[i].DiagID); } @@ -629,6 +661,10 @@ bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const { if (isUnrecoverable(DiagID)) Diag.UnrecoverableErrorOccurred = true; + // Warnings which have been upgraded to errors do not prevent compilation. + if (isDefaultMappingAsError(DiagID)) + Diag.UncompilableErrorOccurred = true; + Diag.ErrorOccurred = true; if (Diag.Client->IncludeInDiagnosticCounts()) { ++Diag.NumErrors; diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp index a816969..9cc5902 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp @@ -20,12 +20,12 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" #include "llvm/ADT/SmallString.h" +#include "llvm/Config/llvm-config.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -#include "llvm/Config/llvm-config.h" #include <map> #include <set> #include <string> @@ -40,6 +40,9 @@ #define S_ISFIFO(x) (0) #endif #endif +#if defined(LLVM_ON_UNIX) +#include <limits.h> +#endif using namespace clang; // FIXME: Enhance libsystem to support inode and other fields. @@ -311,7 +314,7 @@ const DirectoryEntry *FileManager::getDirectory(StringRef DirName, // Check to see if the directory exists. struct stat StatBuf; - if (getStatValue(InterndDirName, StatBuf, 0/*directory lookup*/)) { + if (getStatValue(InterndDirName, StatBuf, false, 0/*directory lookup*/)) { // There's no real directory at the given path. if (!CacheFailure) SeenDirEntries.erase(DirName); @@ -376,7 +379,8 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile, // Nope, there isn't. Check to see if the file exists. int FileDescriptor = -1; struct stat StatBuf; - if (getStatValue(InterndFileName, StatBuf, &FileDescriptor)) { + if (getStatValue(InterndFileName, StatBuf, true, + openFile ? &FileDescriptor : 0)) { // There's no real file at the given path. if (!CacheFailure) SeenFileEntries.erase(Filename); @@ -444,14 +448,9 @@ FileManager::getVirtualFile(StringRef Filename, off_t Size, "The directory of a virtual file should already be in the cache."); // Check to see if the file exists. If so, drop the virtual file - int FileDescriptor = -1; struct stat StatBuf; const char *InterndFileName = NamedFileEnt.getKeyData(); - if (getStatValue(InterndFileName, StatBuf, &FileDescriptor) == 0) { - // If the stat process opened the file, close it to avoid a FD leak. - if (FileDescriptor != -1) - close(FileDescriptor); - + if (getStatValue(InterndFileName, StatBuf, true, 0) == 0) { StatBuf.st_size = Size; StatBuf.st_mtime = ModificationTime; UFE = &UniqueRealFiles.getFile(InterndFileName, StatBuf); @@ -564,18 +563,18 @@ getBufferForFile(StringRef Filename, std::string *ErrorStr) { /// false if it's an existent real file. If FileDescriptor is NULL, /// do directory look-up instead of file look-up. bool FileManager::getStatValue(const char *Path, struct stat &StatBuf, - int *FileDescriptor) { + bool isFile, int *FileDescriptor) { // FIXME: FileSystemOpts shouldn't be passed in here, all paths should be // absolute! if (FileSystemOpts.WorkingDir.empty()) - return FileSystemStatCache::get(Path, StatBuf, FileDescriptor, + return FileSystemStatCache::get(Path, StatBuf, isFile, FileDescriptor, StatCache.get()); SmallString<128> FilePath(Path); FixupRelativePath(FilePath); - return FileSystemStatCache::get(FilePath.c_str(), StatBuf, FileDescriptor, - StatCache.get()); + return FileSystemStatCache::get(FilePath.c_str(), StatBuf, + isFile, FileDescriptor, StatCache.get()); } bool FileManager::getNoncachedStatValue(StringRef Path, @@ -624,6 +623,29 @@ void FileManager::modifyFileEntry(FileEntry *File, File->ModTime = ModificationTime; } +StringRef FileManager::getCanonicalName(const DirectoryEntry *Dir) { + // FIXME: use llvm::sys::fs::canonical() when it gets implemented +#ifdef LLVM_ON_UNIX + llvm::DenseMap<const DirectoryEntry *, llvm::StringRef>::iterator Known + = CanonicalDirNames.find(Dir); + if (Known != CanonicalDirNames.end()) + return Known->second; + + StringRef CanonicalName(Dir->getName()); + char CanonicalNameBuf[PATH_MAX]; + if (realpath(Dir->getName(), CanonicalNameBuf)) { + unsigned Len = strlen(CanonicalNameBuf); + char *Mem = static_cast<char *>(CanonicalNameStorage.Allocate(Len, 1)); + memcpy(Mem, CanonicalNameBuf, Len); + CanonicalName = StringRef(Mem, Len); + } + + CanonicalDirNames.insert(std::make_pair(Dir, CanonicalName)); + return CanonicalName; +#else + return StringRef(Dir->getName()); +#endif +} void FileManager::PrintStats() const { llvm::errs() << "\n*** File Manager Stats:\n"; diff --git a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp index 875d397..38c4629 100644 --- a/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/FileSystemStatCache.cpp @@ -34,21 +34,23 @@ void FileSystemStatCache::anchor() { } /// path, using the cache to accelerate it if possible. This returns true if /// the path does not exist or false if it exists. /// -/// If FileDescriptor is non-null, then this lookup should only return success -/// for files (not directories). If it is null this lookup should only return +/// If isFile is true, then this lookup should only return success for files +/// (not directories). If it is false this lookup should only return /// success for directories (not files). On a successful file lookup, the /// implementation can optionally fill in FileDescriptor with a valid /// descriptor and the client guarantees that it will close it. bool FileSystemStatCache::get(const char *Path, struct stat &StatBuf, - int *FileDescriptor, FileSystemStatCache *Cache) { + bool isFile, int *FileDescriptor, + FileSystemStatCache *Cache) { LookupResult R; - bool isForDir = FileDescriptor == 0; + bool isForDir = !isFile; // If we have a cache, use it to resolve the stat query. if (Cache) - R = Cache->getStat(Path, StatBuf, FileDescriptor); - else if (isForDir) { - // If this is a directory and we have no cache, just go to the file system. + R = Cache->getStat(Path, StatBuf, isFile, FileDescriptor); + else if (isForDir || !FileDescriptor) { + // If this is a directory or a file descriptor is not needed and we have + // no cache, just go to the file system. R = ::stat(Path, &StatBuf) != 0 ? CacheMissing : CacheExists; } else { // Otherwise, we have to go to the filesystem. We can always just use @@ -104,8 +106,8 @@ bool FileSystemStatCache::get(const char *Path, struct stat &StatBuf, MemorizeStatCalls::LookupResult MemorizeStatCalls::getStat(const char *Path, struct stat &StatBuf, - int *FileDescriptor) { - LookupResult Result = statChained(Path, StatBuf, FileDescriptor); + bool isFile, int *FileDescriptor) { + LookupResult Result = statChained(Path, StatBuf, isFile, FileDescriptor); // Do not cache failed stats, it is easy to construct common inconsistent // situations if we do, and they are not important for PCH performance (which diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp index 1965bf9..429d9d8 100644 --- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp @@ -13,13 +13,13 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" -#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/ErrorHandling.h" -#include <cctype> +#include "llvm/Support/raw_ostream.h" #include <cstdio> using namespace clang; @@ -82,7 +82,7 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts, // Add the '_experimental_modules_import' contextual keyword. - get("__experimental_modules_import").setModulesImport(true); + get("import").setModulesImport(true); } //===----------------------------------------------------------------------===// @@ -94,7 +94,7 @@ namespace { enum { KEYC99 = 0x1, KEYCXX = 0x2, - KEYCXX0X = 0x4, + KEYCXX11 = 0x4, KEYGNU = 0x8, KEYMS = 0x10, BOOLSUPPORT = 0x20, @@ -124,7 +124,7 @@ static void AddKeyword(StringRef Keyword, unsigned AddResult = 0; if (Flags == KEYALL) AddResult = 2; else if (LangOpts.CPlusPlus && (Flags & KEYCXX)) AddResult = 2; - else if (LangOpts.CPlusPlus0x && (Flags & KEYCXX0X)) AddResult = 2; + else if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) AddResult = 2; else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2; else if (LangOpts.GNUKeywords && (Flags & KEYGNU)) AddResult = 1; else if (LangOpts.MicrosoftExt && (Flags & KEYMS)) AddResult = 1; @@ -138,7 +138,7 @@ static void AddKeyword(StringRef Keyword, // We treat bridge casts as objective-C keywords so we can warn on them // in non-arc mode. else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2; - else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3; + else if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) AddResult = 3; // Don't add this keyword under MicrosoftMode. if (LangOpts.MicrosoftMode && (Flags & KEYNOMS)) @@ -404,9 +404,8 @@ std::string Selector::getAsString() const { /// given "word", which is assumed to end in a lowercase letter. static bool startsWithWord(StringRef name, StringRef word) { if (name.size() < word.size()) return false; - return ((name.size() == word.size() || - !islower(name[word.size()])) - && name.startswith(word)); + return ((name.size() == word.size() || !isLowercase(name[word.size()])) && + name.startswith(word)); } ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { @@ -472,7 +471,7 @@ SelectorTable::constructSetterName(IdentifierTable &Idents, SmallString<100> SelectorName; SelectorName = "set"; SelectorName += Name->getName(); - SelectorName[3] = toupper(SelectorName[3]); + SelectorName[3] = toUppercase(SelectorName[3]); IdentifierInfo *SetterName = &Idents.get(SelectorName); return SelTable.getUnarySelector(SetterName); } diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp index 991992a..f8714b2 100644 --- a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp @@ -14,10 +14,14 @@ using namespace clang; +const SanitizerOptions SanitizerOptions::Disabled = {}; + LangOptions::LangOptions() { #define LANGOPT(Name, Bits, Default, Description) Name = Default; #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default); #include "clang/Basic/LangOptions.def" + + Sanitize = SanitizerOptions::Disabled; } void LangOptions::resetNonModularOptions() { @@ -26,7 +30,11 @@ void LangOptions::resetNonModularOptions() { #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ Name = Default; #include "clang/Basic/LangOptions.def" - + + // FIXME: This should not be reset; modules can be different with different + // sanitizer options (this affects __has_feature(address_sanitizer) etc). + Sanitize = SanitizerOptions::Disabled; + CurrentModule.clear(); } diff --git a/contrib/llvm/tools/clang/lib/Basic/Module.cpp b/contrib/llvm/tools/clang/lib/Basic/Module.cpp index 76c7f8b..13518cd 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Module.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Module.cpp @@ -1,4 +1,4 @@ -//===--- Module.h - Describe a module ---------------------------*- C++ -*-===// +//===--- Module.cpp - Describe a module -----------------------------------===// // // The LLVM Compiler Infrastructure // @@ -15,10 +15,11 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, @@ -27,7 +28,8 @@ Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false), InferSubmodules(false), InferExplicitSubmodules(false), - InferExportWildcard(false), NameVisibility(Hidden) + InferExportWildcard(false), ConfigMacrosExhaustive(false), + NameVisibility(Hidden) { if (Parent) { if (!Parent->isAvailable()) @@ -45,7 +47,6 @@ Module::~Module() { I != IEnd; ++I) { delete *I; } - } /// \brief Determine whether a translation unit built using the current @@ -56,7 +57,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, .Case("altivec", LangOpts.AltiVec) .Case("blocks", LangOpts.Blocks) .Case("cplusplus", LangOpts.CPlusPlus) - .Case("cplusplus11", LangOpts.CPlusPlus0x) + .Case("cplusplus11", LangOpts.CPlusPlus11) .Case("objc", LangOpts.ObjC1) .Case("objc_arc", LangOpts.ObjCAutoRefCount) .Case("opencl", LangOpts.OpenCL) @@ -103,15 +104,15 @@ const Module *Module::getTopLevelModule() const { } std::string Module::getFullModuleName() const { - llvm::SmallVector<StringRef, 2> Names; + SmallVector<StringRef, 2> Names; // Build up the set of module names (from innermost to outermost). for (const Module *M = this; M; M = M->Parent) Names.push_back(M->Name); std::string Result; - for (llvm::SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), - IEnd = Names.rend(); + for (SmallVector<StringRef, 2>::reverse_iterator I = Names.rbegin(), + IEnd = Names.rend(); I != IEnd; ++I) { if (!Result.empty()) Result += '.'; @@ -129,6 +130,19 @@ const DirectoryEntry *Module::getUmbrellaDir() const { return Umbrella.dyn_cast<const DirectoryEntry *>(); } +ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { + if (!TopHeaderNames.empty()) { + for (std::vector<std::string>::iterator + I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) { + if (const FileEntry *FE = FileMgr.getFile(*I)) + TopHeaders.insert(FE); + } + TopHeaderNames.clear(); + } + + return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); +} + void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target) { Requires.push_back(Feature); @@ -140,7 +154,7 @@ void Module::addRequirement(StringRef Feature, const LangOptions &LangOpts, if (!IsAvailable) return; - llvm::SmallVector<Module *, 2> Stack; + SmallVector<Module *, 2> Stack; Stack.push_back(this); while (!Stack.empty()) { Module *Current = Stack.back(); @@ -167,7 +181,7 @@ Module *Module::findSubmodule(StringRef Name) const { return SubModules[Pos->getValue()]; } -static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { +static void printModuleId(raw_ostream &OS, const ModuleId &Id) { for (unsigned I = 0, N = Id.size(); I != N; ++I) { if (I) OS << "."; @@ -175,7 +189,60 @@ static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) { } } -void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { +void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { + bool AnyWildcard = false; + bool UnrestrictedWildcard = false; + SmallVector<Module *, 4> WildcardRestrictions; + for (unsigned I = 0, N = Exports.size(); I != N; ++I) { + Module *Mod = Exports[I].getPointer(); + if (!Exports[I].getInt()) { + // Export a named module directly; no wildcards involved. + Exported.push_back(Mod); + + continue; + } + + // Wildcard export: export all of the imported modules that match + // the given pattern. + AnyWildcard = true; + if (UnrestrictedWildcard) + continue; + + if (Module *Restriction = Exports[I].getPointer()) + WildcardRestrictions.push_back(Restriction); + else { + WildcardRestrictions.clear(); + UnrestrictedWildcard = true; + } + } + + // If there were any wildcards, push any imported modules that were + // re-exported by the wildcard restriction. + if (!AnyWildcard) + return; + + for (unsigned I = 0, N = Imports.size(); I != N; ++I) { + Module *Mod = Imports[I]; + bool Acceptable = UnrestrictedWildcard; + if (!Acceptable) { + // Check whether this module meets one of the restrictions. + for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) { + Module *Restriction = WildcardRestrictions[R]; + if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { + Acceptable = true; + break; + } + } + } + + if (!Acceptable) + continue; + + Exported.push_back(Mod); + } +} + +void Module::print(raw_ostream &OS, unsigned Indent) const { OS.indent(Indent); if (IsFramework) OS << "framework "; @@ -212,7 +279,20 @@ void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { OS.write_escaped(UmbrellaDir->getName()); OS << "\"\n"; } - + + if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { + OS.indent(Indent + 2); + OS << "config_macros "; + if (ConfigMacrosExhaustive) + OS << "[exhaustive]"; + for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { + if (I) + OS << ", "; + OS << ConfigMacros[I]; + } + OS << "\n"; + } + for (unsigned I = 0, N = Headers.size(); I != N; ++I) { OS.indent(Indent + 2); OS << "header \""; @@ -257,6 +337,34 @@ void Module::print(llvm::raw_ostream &OS, unsigned Indent) const { OS << "\n"; } + for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "link "; + if (LinkLibraries[I].IsFramework) + OS << "framework "; + OS << "\""; + OS.write_escaped(LinkLibraries[I].Library); + OS << "\""; + } + + for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "conflict "; + printModuleId(OS, UnresolvedConflicts[I].Id); + OS << ", \""; + OS.write_escaped(UnresolvedConflicts[I].Message); + OS << "\"\n"; + } + + for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) { + OS.indent(Indent + 2); + OS << "conflict "; + OS << Conflicts[I].Other->getFullModuleName(); + OS << ", \""; + OS.write_escaped(Conflicts[I].Message); + OS << "\"\n"; + } + if (InferSubmodules) { OS.indent(Indent + 2); if (InferExplicitSubmodules) diff --git a/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp new file mode 100644 index 0000000..835908d --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/OpenMPKinds.cpp @@ -0,0 +1,43 @@ +//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// \brief This file implements the OpenMP enum and support functions. +/// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/IdentifierTable.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> + +using namespace clang; + +OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) { + return llvm::StringSwitch<OpenMPDirectiveKind>(Str) +#define OPENMP_DIRECTIVE(Name) \ + .Case(#Name, OMPD_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPD_unknown); +} + +const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) { + assert(Kind < NUM_OPENMP_DIRECTIVES); + switch (Kind) { + case OMPD_unknown: + return ("unknown"); +#define OPENMP_DIRECTIVE(Name) \ + case OMPD_##Name : return #Name; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + llvm_unreachable("Invalid OpenMP directive kind"); +} diff --git a/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp new file mode 100644 index 0000000..f9de231 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Basic/OperatorPrecedence.cpp @@ -0,0 +1,76 @@ +//===--- OperatorPrecedence.cpp ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines and computes precedence levels for binary/ternary operators. +/// +//===----------------------------------------------------------------------===// +#include "clang/Basic/OperatorPrecedence.h" + +namespace clang { + +prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, + bool CPlusPlus11) { + switch (Kind) { + case tok::greater: + // C++ [temp.names]p3: + // [...] When parsing a template-argument-list, the first + // non-nested > is taken as the ending delimiter rather than a + // greater-than operator. [...] + if (GreaterThanIsOperator) + return prec::Relational; + return prec::Unknown; + + case tok::greatergreater: + // C++0x [temp.names]p3: + // + // [...] Similarly, the first non-nested >> is treated as two + // consecutive but distinct > tokens, the first of which is + // taken as the end of the template-argument-list and completes + // the template-id. [...] + if (GreaterThanIsOperator || !CPlusPlus11) + return prec::Shift; + return prec::Unknown; + + default: return prec::Unknown; + case tok::comma: return prec::Comma; + case tok::equal: + case tok::starequal: + case tok::slashequal: + case tok::percentequal: + case tok::plusequal: + case tok::minusequal: + case tok::lesslessequal: + case tok::greatergreaterequal: + case tok::ampequal: + case tok::caretequal: + case tok::pipeequal: return prec::Assignment; + case tok::question: return prec::Conditional; + case tok::pipepipe: return prec::LogicalOr; + case tok::ampamp: return prec::LogicalAnd; + case tok::pipe: return prec::InclusiveOr; + case tok::caret: return prec::ExclusiveOr; + case tok::amp: return prec::And; + case tok::exclaimequal: + case tok::equalequal: return prec::Equality; + case tok::lessequal: + case tok::less: + case tok::greaterequal: return prec::Relational; + case tok::lessless: return prec::Shift; + case tok::plus: + case tok::minus: return prec::Additive; + case tok::percent: + case tok::slash: + case tok::star: return prec::Multiplicative; + case tok::periodstar: + case tok::arrowstar: return prec::PointerToMember; + } +} + +} // namespace clang diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp index 0d62f7b..1822091 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp @@ -65,7 +65,7 @@ std::string SourceLocation::printToString(const SourceManager &SM) const { std::string S; llvm::raw_string_ostream OS(S); print(OS, SM); - return S; + return OS.str(); } void SourceLocation::dump(const SourceManager &SM) const { diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp index cd0284a..1b8383b 100644 --- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp @@ -12,20 +12,20 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/SourceManager.h" -#include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" -#include "llvm/ADT/StringSwitch.h" +#include "clang/Basic/SourceManagerInternals.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Capacity.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Path.h" -#include "llvm/Support/Capacity.h" +#include "llvm/Support/raw_ostream.h" #include <algorithm> -#include <string> #include <cstring> +#include <string> #include <sys/stat.h> using namespace clang; @@ -721,7 +721,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { // See if this is near the file point - worst case we start scanning from the // most newly created FileID. - std::vector<SrcMgr::SLocEntry>::const_iterator I; + const SrcMgr::SLocEntry *I; if (LastFileIDLookup.ID < 0 || LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { @@ -840,10 +840,17 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { ++NumProbes; unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex; const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex); + if (E.getOffset() == 0) + return FileID(); // invalid entry. ++NumProbes; if (E.getOffset() > SLocOffset) { + // Sanity checking, otherwise a bug may lead to hanging in release build. + if (GreaterIndex == MiddleIndex) { + assert(0 && "binary search missed the entry"); + return FileID(); + } GreaterIndex = MiddleIndex; continue; } @@ -856,6 +863,11 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { return Res; } + // Sanity checking, otherwise a bug may lead to hanging in release build. + if (LessIndex == MiddleIndex) { + assert(0 && "binary search missed the entry"); + return FileID(); + } LessIndex = MiddleIndex; } } @@ -974,11 +986,18 @@ bool SourceManager::isMacroArgExpansion(SourceLocation Loc) const { if (!Loc.isMacroID()) return false; FileID FID = getFileID(Loc); - const SrcMgr::SLocEntry *E = &getSLocEntry(FID); - const SrcMgr::ExpansionInfo &Expansion = E->getExpansion(); + const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion(); return Expansion.isMacroArgExpansion(); } +bool SourceManager::isMacroBodyExpansion(SourceLocation Loc) const { + if (!Loc.isMacroID()) return false; + + FileID FID = getFileID(Loc); + const SrcMgr::ExpansionInfo &Expansion = getSLocEntry(FID).getExpansion(); + return Expansion.isMacroBodyExpansion(); +} + //===----------------------------------------------------------------------===// // Queries about the code at a SourceLocation. @@ -1032,7 +1051,8 @@ unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, // See if we just calculated the line number for this FilePos and can use // that to lookup the start of the line instead of searching for it. if (LastLineNoFileIDQuery == FID && - LastLineNoContentCache->SourceLineCache != 0) { + LastLineNoContentCache->SourceLineCache != 0 && + LastLineNoResult < LastLineNoContentCache->NumLines) { unsigned *SourceLineCache = LastLineNoContentCache->SourceLineCache; unsigned LineStart = SourceLineCache[LastLineNoResult - 1]; unsigned LineEnd = SourceLineCache[LastLineNoResult]; @@ -1361,7 +1381,8 @@ const char *SourceManager::getBufferName(SourceLocation Loc, /// /// Note that a presumed location is always given as the expansion point of an /// expansion location, not at the spelling location. -PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { +PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc, + bool UseLineDirectives) const { if (Loc.isInvalid()) return PresumedLoc(); // Presumed locations are always for expansion points. @@ -1395,7 +1416,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { // If we have #line directives in this file, update and overwrite the physical // location info if appropriate. - if (FI.hasLineDirectives()) { + if (UseLineDirectives && FI.hasLineDirectives()) { assert(LineTable && "Can't have linetable entries without a LineTable!"); // See if there is a #line directive before this. If so, get it. if (const LineEntry *Entry = @@ -1451,13 +1472,13 @@ unsigned SourceManager::getFileIDSize(FileID FID) const { /// /// This routine involves a system call, and therefore should only be used /// in non-performance-critical code. -static llvm::Optional<ino_t> getActualFileInode(const FileEntry *File) { +static Optional<ino_t> getActualFileInode(const FileEntry *File) { if (!File) - return llvm::Optional<ino_t>(); + return None; struct stat StatBuf; if (::stat(File->getName(), &StatBuf)) - return llvm::Optional<ino_t>(); + return None; return StatBuf.st_ino; } @@ -1488,8 +1509,8 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { // First, check the main file ID, since it is common to look for a // location in the main file. - llvm::Optional<ino_t> SourceFileInode; - llvm::Optional<StringRef> SourceFileName; + Optional<ino_t> SourceFileInode; + Optional<StringRef> SourceFileName; if (!MainFileID.isInvalid()) { bool Invalid = false; const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid); @@ -1511,8 +1532,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { if (*SourceFileName == llvm::sys::path::filename(MainFile->getName())) { SourceFileInode = getActualFileInode(SourceFile); if (SourceFileInode) { - if (llvm::Optional<ino_t> MainFileInode - = getActualFileInode(MainFile)) { + if (Optional<ino_t> MainFileInode = getActualFileInode(MainFile)) { if (*SourceFileInode == *MainFileInode) { FirstFID = MainFileID; SourceFile = MainFile; @@ -1576,7 +1596,7 @@ FileID SourceManager::translateFile(const FileEntry *SourceFile) const { const FileEntry *Entry =FileContentCache? FileContentCache->OrigEntry : 0; if (Entry && *SourceFileName == llvm::sys::path::filename(Entry->getName())) { - if (llvm::Optional<ino_t> EntryInode = getActualFileInode(Entry)) { + if (Optional<ino_t> EntryInode = getActualFileInode(Entry)) { if (*SourceFileInode == *EntryInode) { FirstFID = FileID::get(I); SourceFile = Entry; @@ -1847,7 +1867,32 @@ static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc, Loc = SM.getDecomposedLoc(UpperLoc); return false; } - + +/// Return the cache entry for comparing the given file IDs +/// for isBeforeInTranslationUnit. +InBeforeInTUCacheEntry &SourceManager::getInBeforeInTUCache(FileID LFID, + FileID RFID) const { + // This is a magic number for limiting the cache size. It was experimentally + // derived from a small Objective-C project (where the cache filled + // out to ~250 items). We can make it larger if necessary. + enum { MagicCacheSize = 300 }; + IsBeforeInTUCacheKey Key(LFID, RFID); + + // If the cache size isn't too large, do a lookup and if necessary default + // construct an entry. We can then return it to the caller for direct + // use. When they update the value, the cache will get automatically + // updated as well. + if (IBTUCache.size() < MagicCacheSize) + return IBTUCache[Key]; + + // Otherwise, do a lookup that will not construct a new value. + InBeforeInTUCache::iterator I = IBTUCache.find(Key); + if (I != IBTUCache.end()) + return I->second; + + // Fall back to the overflow value. + return IBTUCacheOverflow; +} /// \brief Determines the order of 2 source locations in the translation unit. /// @@ -1867,6 +1912,11 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS, // If we are comparing a source location with multiple locations in the same // file, we get a big win by caching the result. + InBeforeInTUCacheEntry &IsBeforeInTUCache = + getInBeforeInTUCache(LOffs.first, ROffs.first); + + // If we are comparing a source location with multiple locations in the same + // file, we get a big win by caching the result. if (IsBeforeInTUCache.isCacheValid(LOffs.first, ROffs.first)) return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second); diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp index 83d4e2b..70ea235 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp @@ -11,13 +11,13 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/AddressSpaces.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" -#include <cctype> #include <cstdlib> using namespace clang; @@ -84,7 +84,7 @@ TargetInfo::TargetInfo(const std::string &T) : TargetOpts(), Triple(T) ComplexLongDoubleUsesFP2Ret = false; // Default to using the Itanium ABI. - CXXABI = CXXABI_Itanium; + TheCXXABI.set(TargetCXXABI::GenericItanium); // Default to an empty address space map. AddrSpaceMap = &DefaultAddrSpaceMap; @@ -223,7 +223,7 @@ bool TargetInfo::isValidGCCRegisterName(StringRef Name) const { getGCCRegNames(Names, NumNames); // If we have a number it maps to an entry in the register name array. - if (isdigit(Name[0])) { + if (isDigit(Name[0])) { int n; if (!Name.getAsInteger(0, n)) return n >= 0 && (unsigned)n < NumNames; @@ -279,7 +279,7 @@ TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const { getGCCRegNames(Names, NumNames); // First, check if we have a number. - if (isdigit(Name[0])) { + if (isDigit(Name[0])) { int n; if (!Name.getAsInteger(0, n)) { assert(n >= 0 && (unsigned)n < NumNames && @@ -496,3 +496,17 @@ bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints, return true; } + +bool TargetCXXABI::tryParse(llvm::StringRef name) { + const Kind unknown = static_cast<Kind>(-1); + Kind kind = llvm::StringSwitch<Kind>(name) + .Case("arm", GenericARM) + .Case("ios", iOS) + .Case("itanium", GenericItanium) + .Case("microsoft", Microsoft) + .Default(unknown); + if (kind == unknown) return false; + + set(kind); + return true; +} diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp index 84a6daf..3eda9d8 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp @@ -25,9 +25,9 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/Type.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Type.h" #include <algorithm> using namespace clang; @@ -94,7 +94,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts, Builder.defineMacro("OBJC_NEW_PROPERTIES"); // AddressSanitizer doesn't play well with source fortification, which is on // by default on Darwin. - if (Opts.SanitizeAddress) Builder.defineMacro("_FORTIFY_SOURCE", "0"); + if (Opts.Sanitize.Address) Builder.defineMacro("_FORTIFY_SOURCE", "0"); if (!Opts.ObjCAutoRefCount) { // __weak is always defined, for use in blocks and with objc pointers. @@ -384,13 +384,13 @@ public: case llvm::Triple::x86: case llvm::Triple::x86_64: case llvm::Triple::arm: - case llvm::Triple::sparc: + case llvm::Triple::sparc: this->MCountName = "__mcount"; break; case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::ppc: - case llvm::Triple::sparcv9: + case llvm::Triple::sparcv9: this->MCountName = "_mcount"; break; } @@ -575,7 +575,7 @@ protected: if (Opts.MicrosoftExt) { Builder.defineMacro("_MSC_EXTENSIONS"); - if (Opts.CPlusPlus0x) { + if (Opts.CPlusPlus11) { Builder.defineMacro("_RVALUE_REFERENCES_V2_SUPPORTED"); Builder.defineMacro("_RVALUE_REFERENCES_SUPPORTED"); Builder.defineMacro("_NATIVE_NULLPTR_SUPPORTED"); @@ -661,9 +661,19 @@ public: ArchDefine603 = 1 << 4, ArchDefine604 = 1 << 5, ArchDefinePwr4 = 1 << 6, - ArchDefinePwr6 = 1 << 7 + ArchDefinePwr5 = 1 << 7, + ArchDefinePwr5x = 1 << 8, + ArchDefinePwr6 = 1 << 9, + ArchDefinePwr6x = 1 << 10, + ArchDefinePwr7 = 1 << 11, + ArchDefineA2 = 1 << 12, + ArchDefineA2q = 1 << 13 } ArchDefineTypes; + // Note: GCC recognizes the following additional cpus: + // 401, 403, 405, 405fp, 440fp, 464, 464fp, 476, 476fp, 505, 740, 801, + // 821, 823, 8540, 8548, e300c2, e300c3, e500mc64, e6500, 860, cell, + // titan, rs64. virtual bool setCPU(const std::string &Name) { bool CPUKnown = llvm::StringSwitch<bool>(Name) .Case("generic", true) @@ -677,6 +687,7 @@ public: .Case("604", true) .Case("604e", true) .Case("620", true) + .Case("630", true) .Case("g3", true) .Case("7400", true) .Case("g4", true) @@ -686,11 +697,26 @@ public: .Case("970", true) .Case("g5", true) .Case("a2", true) + .Case("a2q", true) .Case("e500mc", true) .Case("e5500", true) + .Case("power3", true) + .Case("pwr3", true) + .Case("power4", true) + .Case("pwr4", true) + .Case("power5", true) + .Case("pwr5", true) + .Case("power5x", true) + .Case("pwr5x", true) + .Case("power6", true) .Case("pwr6", true) + .Case("power6x", true) + .Case("pwr6x", true) + .Case("power7", true) .Case("pwr7", true) + .Case("powerpc", true) .Case("ppc", true) + .Case("powerpc64", true) .Case("ppc64", true) .Default(false); @@ -711,6 +737,12 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const; + virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const; + + virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, + bool Enabled) const; + virtual bool hasFeature(StringRef Feature) const; virtual void getGCCRegNames(const char * const *&Names, @@ -818,6 +850,11 @@ public: virtual const char *getClobbers() const { return ""; } + int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 3; + if (RegNo == 1) return 4; + return -1; + } }; const Builtin::Info PPCTargetInfo::BuiltinInfo[] = { @@ -875,14 +912,42 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, .Case("604", ArchDefineName | ArchDefinePpcgr) .Case("604e", ArchDefineName | ArchDefine604 | ArchDefinePpcgr) .Case("620", ArchDefineName | ArchDefinePpcgr) + .Case("630", ArchDefineName | ArchDefinePpcgr) .Case("7400", ArchDefineName | ArchDefinePpcgr) .Case("7450", ArchDefineName | ArchDefinePpcgr) .Case("750", ArchDefineName | ArchDefinePpcgr) .Case("970", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr6", ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq) - .Case("pwr7", ArchDefineName | ArchDefinePwr6 | ArchDefinePpcgr + .Case("a2", ArchDefineA2) + .Case("a2q", ArchDefineName | ArchDefineA2 | ArchDefineA2q) + .Case("pwr3", ArchDefinePpcgr) + .Case("pwr4", ArchDefineName | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("pwr5", ArchDefineName | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("pwr5x", ArchDefineName | ArchDefinePwr5 | ArchDefinePwr4 + | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("pwr6", ArchDefineName | ArchDefinePwr5x | ArchDefinePwr5 + | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("pwr6x", ArchDefineName | ArchDefinePwr6 | ArchDefinePwr5x + | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr + | ArchDefinePpcsq) + .Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6 + | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 + | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("power3", ArchDefinePpcgr) + .Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr + | ArchDefinePpcsq) + .Case("power5x", ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 + | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("power6", ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5 + | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq) + .Case("power6x", ArchDefinePwr6x | ArchDefinePwr6 | ArchDefinePwr5x + | ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr + | ArchDefinePpcsq) + .Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6 + | ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4 + | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq) .Default(ArchDefineNone); if (defs & ArchDefineName) @@ -897,12 +962,80 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("_ARCH_603"); if (defs & ArchDefine604) Builder.defineMacro("_ARCH_604"); - if (defs & (ArchDefinePwr4 | ArchDefinePwr6)) + if (defs & ArchDefinePwr4) Builder.defineMacro("_ARCH_PWR4"); - if (defs & ArchDefinePwr6) { + if (defs & ArchDefinePwr5) Builder.defineMacro("_ARCH_PWR5"); + if (defs & ArchDefinePwr5x) + Builder.defineMacro("_ARCH_PWR5X"); + if (defs & ArchDefinePwr6) Builder.defineMacro("_ARCH_PWR6"); + if (defs & ArchDefinePwr6x) + Builder.defineMacro("_ARCH_PWR6X"); + if (defs & ArchDefinePwr7) + Builder.defineMacro("_ARCH_PWR7"); + if (defs & ArchDefineA2) + Builder.defineMacro("_ARCH_A2"); + if (defs & ArchDefineA2q) { + Builder.defineMacro("_ARCH_A2Q"); + Builder.defineMacro("_ARCH_QP"); + } + + if (getTriple().getVendor() == llvm::Triple::BGQ) { + Builder.defineMacro("__bg__"); + Builder.defineMacro("__THW_BLUEGENE__"); + Builder.defineMacro("__bgq__"); + Builder.defineMacro("__TOS_BGQ__"); + } + + // FIXME: The following are not yet generated here by Clang, but are + // generated by GCC: + // + // _SOFT_FLOAT_ + // __RECIP_PRECISION__ + // __APPLE_ALTIVEC__ + // __VSX__ + // __RECIP__ + // __RECIPF__ + // __RSQRTE__ + // __RSQRTEF__ + // _SOFT_DOUBLE_ + // __NO_LWSYNC__ + // __HAVE_BSWAP__ + // __LONGDOUBLE128 + // __CMODEL_MEDIUM__ + // __CMODEL_LARGE__ + // _CALL_SYSV + // _CALL_DARWIN + // __NO_FPRS__ +} + +void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { + Features["altivec"] = llvm::StringSwitch<bool>(CPU) + .Case("7400", true) + .Case("g4", true) + .Case("7450", true) + .Case("g4+", true) + .Case("970", true) + .Case("g5", true) + .Case("pwr6", true) + .Case("pwr7", true) + .Case("ppc64", true) + .Default(false); + + Features["qpx"] = (CPU == "a2q"); +} + +bool PPCTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, + StringRef Name, + bool Enabled) const { + if (Name == "altivec" || Name == "fprnd" || Name == "mfocrf" || + Name == "popcntd" || Name == "qpx") { + Features[Name] = Enabled; + return true; } + + return false; } bool PPCTargetInfo::hasFeature(StringRef Feature) const { @@ -1122,7 +1255,7 @@ namespace { class NVPTXTargetInfo : public TargetInfo { static const char * const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; - std::vector<llvm::StringRef> AvailableFeatures; + std::vector<StringRef> AvailableFeatures; public: NVPTXTargetInfo(const std::string& triple) : TargetInfo(triple) { BigEndian = false; @@ -1169,7 +1302,14 @@ namespace { return TargetInfo::CharPtrBuiltinVaList; } virtual bool setCPU(const std::string &Name) { - return Name == "sm_10" || Name == "sm_13" || Name == "sm_20"; + bool Valid = llvm::StringSwitch<bool>(Name) + .Case("sm_20", true) + .Case("sm_21", true) + .Case("sm_30", true) + .Case("sm_35", true) + .Default(false); + + return Valid; } virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features, StringRef Name, @@ -1241,16 +1381,50 @@ static const unsigned R600AddrSpaceMap[] = { 3 // cuda_shared }; +static const char *DescriptionStringR600 = + "e" + "-p:32:32:32" + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32" + "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" + "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" + "-n32:64"; + +static const char *DescriptionStringR600DoubleOps = + "e" + "-p:32:32:32" + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64" + "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" + "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" + "-n32:64"; + +static const char *DescriptionStringSI = + "e" + "-p:64:64:64" + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64" + "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64-v96:128:128-v128:128:128" + "-v192:256:256-v256:256:256-v512:512:512-v1024:1024:1024-v2048:2048:2048" + "-n32:64"; + class R600TargetInfo : public TargetInfo { + /// \brief The GPU profiles supported by the R600 target. + enum GPUKind { + GK_NONE, + GK_R600, + GK_R600_DOUBLE_OPS, + GK_R700, + GK_R700_DOUBLE_OPS, + GK_EVERGREEN, + GK_EVERGREEN_DOUBLE_OPS, + GK_NORTHERN_ISLANDS, + GK_CAYMAN, + GK_SOUTHERN_ISLANDS + } GPU; + public: - R600TargetInfo(const std::string& triple) : TargetInfo(triple) { - DescriptionString = - "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16" - "-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f80:32:32" - "-v16:16:16-v24:32:32-v32:32:32-v48:64:64-v64:64:64" - "-v96:128:128-v128:128:128-v192:256:256-v256:256:256" - "-v512:512:512-v1024:1024:1024-v2048:2048:2048" - "-n8:16:32:64"; + R600TargetInfo(const std::string& triple) + : TargetInfo(triple), + GPU(GK_R600) { + DescriptionString = DescriptionStringR600; AddrSpaceMap = &R600AddrSpaceMap; } @@ -1291,6 +1465,65 @@ public: return TargetInfo::CharPtrBuiltinVaList; } + virtual bool setCPU(const std::string &Name) { + GPU = llvm::StringSwitch<GPUKind>(Name) + .Case("r600" , GK_R600) + .Case("rv610", GK_R600) + .Case("rv620", GK_R600) + .Case("rv630", GK_R600) + .Case("rv635", GK_R600) + .Case("rs780", GK_R600) + .Case("rs880", GK_R600) + .Case("rv670", GK_R600_DOUBLE_OPS) + .Case("rv710", GK_R700) + .Case("rv730", GK_R700) + .Case("rv740", GK_R700_DOUBLE_OPS) + .Case("rv770", GK_R700_DOUBLE_OPS) + .Case("palm", GK_EVERGREEN) + .Case("cedar", GK_EVERGREEN) + .Case("sumo", GK_EVERGREEN) + .Case("sumo2", GK_EVERGREEN) + .Case("redwood", GK_EVERGREEN) + .Case("juniper", GK_EVERGREEN) + .Case("hemlock", GK_EVERGREEN_DOUBLE_OPS) + .Case("cypress", GK_EVERGREEN_DOUBLE_OPS) + .Case("barts", GK_NORTHERN_ISLANDS) + .Case("turks", GK_NORTHERN_ISLANDS) + .Case("caicos", GK_NORTHERN_ISLANDS) + .Case("cayman", GK_CAYMAN) + .Case("aruba", GK_CAYMAN) + .Case("tahiti", GK_SOUTHERN_ISLANDS) + .Case("pitcairn", GK_SOUTHERN_ISLANDS) + .Case("verde", GK_SOUTHERN_ISLANDS) + .Case("oland", GK_SOUTHERN_ISLANDS) + .Default(GK_NONE); + + if (GPU == GK_NONE) { + return false; + } + + // Set the correct data layout + switch (GPU) { + case GK_NONE: + case GK_R600: + case GK_R700: + case GK_EVERGREEN: + case GK_NORTHERN_ISLANDS: + DescriptionString = DescriptionStringR600; + break; + case GK_R600_DOUBLE_OPS: + case GK_R700_DOUBLE_OPS: + case GK_EVERGREEN_DOUBLE_OPS: + case GK_CAYMAN: + DescriptionString = DescriptionStringR600DoubleOps; + break; + case GK_SOUTHERN_ISLANDS: + DescriptionString = DescriptionStringSI; + break; + } + + return true; + } }; } // end anonymous namespace @@ -1476,6 +1709,8 @@ class X86TargetInfo : public TargetInfo { bool HasBMI2; bool HasPOPCNT; bool HasRTM; + bool HasPRFCHW; + bool HasRDSEED; bool HasSSE4a; bool HasFMA4; bool HasFMA; @@ -1627,8 +1862,8 @@ public: : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow), HasAES(false), HasPCLMUL(false), HasLZCNT(false), HasRDRND(false), HasBMI(false), HasBMI2(false), HasPOPCNT(false), HasRTM(false), - HasSSE4a(false), HasFMA4(false), HasFMA(false), HasXOP(false), - HasF16C(false), CPU(CK_Generic) { + HasPRFCHW(false), HasRDSEED(false), HasSSE4a(false), HasFMA4(false), + HasFMA(false), HasXOP(false), HasF16C(false), CPU(CK_Generic) { BigEndian = false; LongDoubleFormat = &llvm::APFloat::x87DoubleExtended; } @@ -1652,7 +1887,7 @@ public: NumAliases = 0; } virtual void getGCCAddlRegNames(const AddlRegName *&Names, - unsigned &NumNames) const { + unsigned &NumNames) const { Names = AddlRegNames; NumNames = llvm::array_lengthof(AddlRegNames); } @@ -1803,11 +2038,12 @@ public: CC == CC_X86FastCall || CC == CC_X86StdCall || CC == CC_C || - CC == CC_X86Pascal) ? CCCR_OK : CCCR_Warning; + CC == CC_X86Pascal || + CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning; } - virtual CallingConv getDefaultCallingConv() const { - return CC_C; + virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { + return MT == CCMT_Member ? CC_X86ThisCall : CC_C; } }; @@ -1833,6 +2069,8 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { Features["bmi2"] = false; Features["popcnt"] = false; Features["rtm"] = false; + Features["prfchw"] = false; + Features["rdseed"] = false; Features["fma4"] = false; Features["fma"] = false; Features["xop"] = false; @@ -1842,7 +2080,7 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { // X86_64 always has SSE2. if (getTriple().getArch() == llvm::Triple::x86_64) - Features["sse2"] = Features["sse"] = Features["mmx"] = true; + setFeatureEnabled(Features, "sse2", true); switch (CPU) { case CK_Generic: @@ -1859,58 +2097,50 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { break; case CK_Pentium3: case CK_Pentium3M: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse", true); break; case CK_PentiumM: case CK_Pentium4: case CK_Pentium4M: case CK_x86_64: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse2", true); break; case CK_Yonah: case CK_Prescott: case CK_Nocona: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse3", true); break; case CK_Core2: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "ssse3", true); break; case CK_Penryn: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse4.1", true); break; case CK_Atom: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "ssse3", true); break; case CK_Corei7: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse4", true); break; case CK_Corei7AVX: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "avx", true); setFeatureEnabled(Features, "aes", true); setFeatureEnabled(Features, "pclmul", true); break; case CK_CoreAVXi: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "avx", true); setFeatureEnabled(Features, "aes", true); setFeatureEnabled(Features, "pclmul", true); setFeatureEnabled(Features, "rdrnd", true); + setFeatureEnabled(Features, "f16c", true); break; case CK_CoreAVX2: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "avx2", true); setFeatureEnabled(Features, "aes", true); setFeatureEnabled(Features, "pclmul", true); setFeatureEnabled(Features, "lzcnt", true); setFeatureEnabled(Features, "rdrnd", true); + setFeatureEnabled(Features, "f16c", true); setFeatureEnabled(Features, "bmi", true); setFeatureEnabled(Features, "bmi2", true); setFeatureEnabled(Features, "rtm", true); @@ -1954,20 +2184,31 @@ void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const { setFeatureEnabled(Features, "sse3", true); setFeatureEnabled(Features, "sse4a", true); setFeatureEnabled(Features, "3dnowa", true); + setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "popcnt", true); break; case CK_BTVER1: setFeatureEnabled(Features, "ssse3", true); setFeatureEnabled(Features, "sse4a", true); + setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "popcnt", true); break; case CK_BDVER1: + setFeatureEnabled(Features, "xop", true); + setFeatureEnabled(Features, "lzcnt", true); + setFeatureEnabled(Features, "aes", true); + setFeatureEnabled(Features, "pclmul", true); + break; case CK_BDVER2: - setFeatureEnabled(Features, "avx", true); setFeatureEnabled(Features, "xop", true); + setFeatureEnabled(Features, "lzcnt", true); setFeatureEnabled(Features, "aes", true); setFeatureEnabled(Features, "pclmul", true); + setFeatureEnabled(Features, "bmi", true); + setFeatureEnabled(Features, "fma", true); + setFeatureEnabled(Features, "f16c", true); break; case CK_C3_2: - setFeatureEnabled(Features, "mmx", true); setFeatureEnabled(Features, "sse", true); break; } @@ -2026,12 +2267,12 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["ssse3"] = Features["sse41"] = Features["sse42"] = Features["popcnt"] = Features["avx"] = Features["fma"] = true; else if (Name == "fma4") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = Features["popcnt"] = Features["avx"] = Features["sse4a"] = Features["fma4"] = true; else if (Name == "xop") - Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = + Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] = Features["ssse3"] = Features["sse41"] = Features["sse42"] = Features["popcnt"] = Features["avx"] = Features["sse4a"] = Features["fma4"] = Features["xop"] = true; @@ -2052,6 +2293,10 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["f16c"] = true; else if (Name == "rtm") Features["rtm"] = true; + else if (Name == "prfchw") + Features["prfchw"] = true; + else if (Name == "rdseed") + Features["rdseed"] = true; } else { if (Name == "mmx") Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false; @@ -2116,6 +2361,10 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features, Features["f16c"] = false; else if (Name == "rtm") Features["rtm"] = false; + else if (Name == "prfchw") + Features["prfchw"] = false; + else if (Name == "rdseed") + Features["rdseed"] = false; } return true; @@ -2172,6 +2421,16 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) { continue; } + if (Feature == "prfchw") { + HasPRFCHW = true; + continue; + } + + if (Feature == "rdseed") { + HasRDSEED = true; + continue; + } + if (Feature == "sse4a") { HasSSE4a = true; continue; @@ -2396,6 +2655,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, if (HasRTM) Builder.defineMacro("__RTM__"); + if (HasPRFCHW) + Builder.defineMacro("__PRFCHW__"); + + if (HasRDSEED) + Builder.defineMacro("__RDSEED__"); + if (HasSSE4a) Builder.defineMacro("__SSE4A__"); @@ -2465,6 +2730,14 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, case NoMMX3DNow: break; } + + if (CPU >= CK_i486) { + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); + } + if (CPU >= CK_i586) + Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); } bool X86TargetInfo::hasFeature(StringRef Feature) const { @@ -2484,6 +2757,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const { .Case("pclmul", HasPCLMUL) .Case("popcnt", HasPOPCNT) .Case("rtm", HasRTM) + .Case("prfchw", HasPRFCHW) + .Case("rdseed", HasRDSEED) .Case("sse", SSELevel >= SSE1) .Case("sse2", SSELevel >= SSE2) .Case("sse3", SSELevel >= SSE3) @@ -2600,6 +2875,19 @@ public: if (RegNo == 1) return 2; return -1; } + virtual bool validateInputSize(StringRef Constraint, + unsigned Size) const { + switch (Constraint[0]) { + default: break; + case 'a': + case 'b': + case 'c': + case 'd': + return Size <= 32; + } + + return true; + } }; } // end anonymous namespace @@ -2747,6 +3035,7 @@ public: virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { X86_32TargetInfo::getTargetDefines(Opts, Builder); + Builder.defineMacro("_X86_"); Builder.defineMacro("__CYGWIN__"); Builder.defineMacro("__CYGWIN32__"); DefineStd(Builder, "unix", Opts); @@ -2877,11 +3166,13 @@ public: } virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { - return TargetInfo::checkCallingConvention(CC); + return (CC == CC_Default || + CC == CC_C || + CC == CC_IntelOclBicc) ? CCCR_OK : CCCR_Warning; } - virtual CallingConv getDefaultCallingConv() const { - return CC_Default; + virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const { + return CC_C; } }; @@ -2995,6 +3286,190 @@ public: Int64Type = SignedLongLong; } }; +} + +namespace { +class AArch64TargetInfo : public TargetInfo { + static const char * const GCCRegNames[]; + static const TargetInfo::GCCRegAlias GCCRegAliases[]; +public: + AArch64TargetInfo(const std::string& triple) : TargetInfo(triple) { + BigEndian = false; + LongWidth = LongAlign = 64; + LongDoubleWidth = LongDoubleAlign = 128; + PointerWidth = PointerAlign = 64; + SuitableAlign = 128; + DescriptionString = "e-p:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" + "i64:64:64-i128:128:128-f32:32:32-f64:64:64-" + "f128:128:128-n32:64-S128"; + + WCharType = UnsignedInt; + LongDoubleFormat = &llvm::APFloat::IEEEquad; + + // AArch64 backend supports 64-bit operations at the moment. In principle + // 128-bit is possible if register-pairs are used. + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; + + TheCXXABI.set(TargetCXXABI::GenericAArch64); + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + // GCC defines theses currently + Builder.defineMacro("__aarch64__"); + Builder.defineMacro("__AARCH64EL__"); + + // ACLE predefines. Many can only have one possible value on v8 AArch64. + + // FIXME: these were written based on an unreleased version of a 32-bit ACLE + // which was intended to be compatible with a 64-bit implementation. They + // will need updating when a real 64-bit ACLE exists. Particularly pressing + // instances are: __AARCH_ISA_A32, __AARCH_ISA_T32, __ARCH_PCS. + Builder.defineMacro("__AARCH_ACLE", "101"); + Builder.defineMacro("__AARCH", "8"); + Builder.defineMacro("__AARCH_PROFILE", "'A'"); + + Builder.defineMacro("__AARCH_FEATURE_UNALIGNED"); + Builder.defineMacro("__AARCH_FEATURE_CLZ"); + Builder.defineMacro("__AARCH_FEATURE_FMA"); + + // FIXME: ACLE 1.1 reserves bit 4. Will almost certainly come to mean + // 128-bit LDXP present, at which point this becomes 0x1f. + Builder.defineMacro("__AARCH_FEATURE_LDREX", "0xf"); + + // 0xe implies support for half, single and double precision operations. + Builder.defineMacro("__AARCH_FP", "0xe"); + + // PCS specifies this for SysV variants, which is all we support. Other ABIs + // may choose __AARCH_FP16_FORMAT_ALTERNATIVE. + Builder.defineMacro("__AARCH_FP16_FORMAT_IEEE"); + + if (Opts.FastMath || Opts.FiniteMathOnly) + Builder.defineMacro("__AARCH_FP_FAST"); + + if ((Opts.C99 || Opts.C11) && !Opts.Freestanding) + Builder.defineMacro("__AARCH_FP_FENV_ROUNDING"); + + Builder.defineMacro("__AARCH_SIZEOF_WCHAR_T", + Opts.ShortWChar ? "2" : "4"); + + Builder.defineMacro("__AARCH_SIZEOF_MINIMAL_ENUM", + Opts.ShortEnums ? "1" : "4"); + + if (BigEndian) + Builder.defineMacro("__AARCH_BIG_ENDIAN"); + } + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const { + Records = 0; + NumRecords = 0; + } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "aarch64"; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const; + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const; + + virtual bool isCLZForZeroUndef() const { return false; } + + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &Info) const { + switch (*Name) { + default: return false; + case 'w': // An FP/SIMD vector register + Info.setAllowsRegister(); + return true; + case 'I': // Constant that can be used with an ADD instruction + case 'J': // Constant that can be used with a SUB instruction + case 'K': // Constant that can be used with a 32-bit logical instruction + case 'L': // Constant that can be used with a 64-bit logical instruction + case 'M': // Constant that can be used as a 32-bit MOV immediate + case 'N': // Constant that can be used as a 64-bit MOV immediate + case 'Y': // Floating point constant zero + case 'Z': // Integer constant zero + return true; + case 'Q': // A memory reference with base register and no offset + Info.setAllowsMemory(); + return true; + case 'S': // A symbolic address + Info.setAllowsRegister(); + return true; + case 'U': + // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes, whatever they may be + // Utf: A memory address suitable for ldp/stp in TF mode, whatever it may be + // Usa: An absolute symbolic address + // Ush: The high part (bits 32:12) of a pc-relative symbolic address + llvm_unreachable("FIXME: Unimplemented support for bizarre constraints"); + } + } + + virtual const char *getClobbers() const { + // There are no AArch64 clobbers shared by all asm statements. + return ""; + } + + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::AArch64ABIBuiltinVaList; + } +}; + +const char * const AArch64TargetInfo::GCCRegNames[] = { + "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", + "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", + "w16", "w17", "w18", "w19", "w20", "w21", "w22", "w23", + "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", "wzr", + + "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", + "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", + "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23", + "x24", "x25", "x26", "x27", "x28", "x29", "x30", "sp", "xzr", + + "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", + "b8", "b9", "b10", "b11", "b12", "b13", "b14", "b15", + "b16", "b17", "b18", "b19", "b20", "b21", "b22", "b23", + "b24", "b25", "b26", "b27", "b28", "b29", "b30", "b31", + + "h0", "h1", "h2", "h3", "h4", "h5", "h6", "h7", + "h8", "h9", "h10", "h11", "h12", "h13", "h14", "h15", + "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23", + "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", + + "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "s12", "s13", "s14", "s15", + "s16", "s17", "s18", "s19", "s20", "s21", "s22", "s23", + "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", + + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", + "d16", "d17", "d18", "d19", "d20", "d21", "d22", "d23", + "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", + + "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", + "q8", "q9", "q10", "q11", "q12", "q13", "q14", "q15", + "q16", "q17", "q18", "q19", "q20", "q21", "q22", "q23", + "q24", "q25", "q26", "q27", "q28", "q29", "q30", "q31" +}; + +void AArch64TargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); +} + +const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { + { { "x16" }, "ip0"}, + { { "x17" }, "ip1"}, + { { "x29" }, "fp" }, + { { "x30" }, "lr" } +}; + +void AArch64TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); + +} } // end anonymous namespace namespace { @@ -3056,7 +3531,7 @@ public: } // ARM targets default to using the ARM C++ ABI. - CXXABI = CXXABI_ARM; + TheCXXABI.set(TargetCXXABI::GenericARM); // ARM has atomics up to 8 bytes // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e @@ -3126,7 +3601,7 @@ public: else if (CPU == "cortex-a8" || CPU == "cortex-a15" || CPU == "cortex-a9" || CPU == "cortex-a9-mp") Features["neon"] = true; - else if (CPU == "swift") { + else if (CPU == "swift" || CPU == "cortex-a7") { Features["vfp4"] = true; Features["neon"] = true; } @@ -3199,7 +3674,9 @@ public: .Cases("arm1176jz-s", "arm1176jzf-s", "6ZK") .Cases("arm1136jf-s", "mpcorenovfp", "mpcore", "6K") .Cases("arm1156t2-s", "arm1156t2f-s", "6T2") - .Cases("cortex-a8", "cortex-a9", "cortex-a15", "7A") + .Cases("cortex-a5", "cortex-a7", "cortex-a8", "7A") + .Cases("cortex-a9", "cortex-a15", "7A") + .Case("cortex-r5", "7R") .Case("cortex-a9-mp", "7F") .Case("swift", "7S") .Cases("cortex-m3", "cortex-m4", "7M") @@ -3210,6 +3687,7 @@ public: return llvm::StringSwitch<const char*>(Name) .Cases("cortex-a8", "cortex-a9", "A") .Cases("cortex-m3", "cortex-m4", "cortex-m0", "M") + .Case("cortex-r5", "R") .Default(""); } virtual bool setCPU(const std::string &Name) { @@ -3320,11 +3798,11 @@ public: case 'v': // ...VFP load/store (reg+constant offset) case 'y': // ...iWMMXt load/store case 't': // address valid for load/store opaque types wider - // than 128-bits + // than 128-bits case 'n': // valid address for Neon doubleword vector load/store case 'm': // valid address for Neon element and structure load/store case 's': // valid address for non-offset loads/stores of quad-word - // values in four ARM registers + // values in four ARM registers Info.setAllowsMemory(); Name++; return true; @@ -3350,6 +3828,9 @@ public: virtual bool validateConstraintModifier(StringRef Constraint, const char Modifier, unsigned Size) const { + bool isOutput = (Constraint[0] == '='); + bool isInOut = (Constraint[0] == '+'); + // Strip off constraint modifiers. while (Constraint[0] == '=' || Constraint[0] == '+' || @@ -3361,7 +3842,8 @@ public: case 'r': { switch (Modifier) { default: - return Size == 32; + return isInOut || (isOutput && Size >= 32) || + (!isOutput && !isInOut && Size <= 32); case 'q': // A register of size 32 cannot fit a vector type. return false; @@ -3379,6 +3861,12 @@ public: virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { return (CC == CC_AAPCS || CC == CC_AAPCS_VFP) ? CCCR_OK : CCCR_Warning; } + + virtual int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 0; + if (RegNo == 1) return 1; + return -1; + } }; const char * const ARMTargetInfo::GCCRegNames[] = { @@ -3460,6 +3948,9 @@ public: // iOS always has 64-bit atomic instructions. // FIXME: This should be based off of the target features in ARMTargetInfo. MaxAtomicInlineWidth = 64; + + // Darwin on iOS uses a variant of the ARM C++ ABI. + TheCXXABI.set(TargetCXXABI::iOS); } }; } // end anonymous namespace. @@ -3476,7 +3967,7 @@ public: HexagonTargetInfo(const std::string& triple) : TargetInfo(triple) { BigEndian = false; DescriptionString = ("e-p:32:32:32-" - "i64:64:64-i32:32:32-i16:16:16-i1:32:32" + "i64:64:64-i32:32:32-i16:16:16-i1:32:32-" "f64:64:64-f32:32:32-a0:0-n32"); // {} in inline assembly are packet specifiers, not assembly variant @@ -3515,8 +4006,6 @@ public: static const char *getHexagonCPUSuffix(StringRef Name) { return llvm::StringSwitch<const char*>(Name) - .Case("hexagonv2", "2") - .Case("hexagonv3", "3") .Case("hexagonv4", "4") .Case("hexagonv5", "5") .Default(0); @@ -4042,6 +4531,9 @@ public: case 'x': // hilo register pair Info.setAllowsRegister(); return true; + case 'R': // An address that can be used in a non-macro load or store + Info.setAllowsMemory(); + return true; } } @@ -4060,6 +4552,12 @@ public: Name == "mips16" || Name == "dsp" || Name == "dspr2") { Features[Name] = Enabled; return true; + } else if (Name == "32") { + Features["o32"] = Enabled; + return true; + } else if (Name == "64") { + Features["n64"] = Enabled; + return true; } return false; } @@ -4089,6 +4587,12 @@ public: if (it != Features.end()) Features.erase(it); } + + virtual int getEHDataRegisterNumber(unsigned RegNo) const { + if (RegNo == 0) return 4; + if (RegNo == 1) return 5; + return -1; + } }; const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = { @@ -4104,11 +4608,15 @@ public: MipsTargetInfoBase(triple, "o32", "mips32") { SizeType = UnsignedInt; PtrDiffType = SignedInt; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; } virtual bool setABI(const std::string &Name) { if ((Name == "o32") || (Name == "eabi")) { ABI = Name; return true; + } else if (Name == "32") { + ABI = "o32"; + return true; } else return false; } @@ -4170,7 +4678,7 @@ class Mips32EBTargetInfo : public Mips32TargetInfoBase { public: Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -4185,7 +4693,7 @@ public: Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) { BigEndian = false; DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" - "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32"; + "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32-S64"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -4204,22 +4712,28 @@ public: PointerWidth = PointerAlign = 64; LongDoubleWidth = LongDoubleAlign = 128; LongDoubleFormat = &llvm::APFloat::IEEEquad; + if (getTriple().getOS() == llvm::Triple::FreeBSD) { + LongDoubleWidth = LongDoubleAlign = 64; + LongDoubleFormat = &llvm::APFloat::IEEEdouble; + } SuitableAlign = 128; + MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; } virtual bool setABI(const std::string &Name) { SetDescriptionString(Name); - - if (Name != "n32" && Name != "n64") - return false; - - ABI = Name; - if (Name == "n32") { LongWidth = LongAlign = 32; PointerWidth = PointerAlign = 32; - } - - return true; + ABI = Name; + return true; + } else if (Name == "n64") { + ABI = Name; + return true; + } else if (Name == "64") { + ABI = "n64"; + return true; + } else + return false; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -4287,14 +4801,14 @@ class Mips64EBTargetInfo : public Mips64TargetInfoBase { if (Name == "n32") DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" - "v64:64:64-n32"; + "v64:64:64-n32:64-S128"; } public: Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { // Default ABI is n64. DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" - "v64:64:64-n32"; + "v64:64:64-n32:64-S128"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -4310,7 +4824,7 @@ class Mips64ELTargetInfo : public Mips64TargetInfoBase { if (Name == "n32") DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-f128:128:128" - "-v64:64:64-n32"; + "-v64:64:64-n32:64-S128"; } public: Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) { @@ -4318,7 +4832,7 @@ public: BigEndian = false; DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-f128:128:128-" - "v64:64:64-n32"; + "v64:64:64-n32:64-S128"; } virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { @@ -4401,6 +4915,97 @@ void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, } } // end anonymous namespace. +namespace { + static const unsigned SPIRAddrSpaceMap[] = { + 1, // opencl_global + 3, // opencl_local + 2, // opencl_constant + 0, // cuda_device + 0, // cuda_constant + 0 // cuda_shared + }; + class SPIRTargetInfo : public TargetInfo { + static const char * const GCCRegNames[]; + static const Builtin::Info BuiltinInfo[]; + std::vector<StringRef> AvailableFeatures; + public: + SPIRTargetInfo(const std::string& triple) : TargetInfo(triple) { + assert(getTriple().getOS() == llvm::Triple::UnknownOS && + "SPIR target must use unknown OS"); + assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && + "SPIR target must use unknown environment type"); + BigEndian = false; + TLSSupported = false; + LongWidth = LongAlign = 64; + AddrSpaceMap = &SPIRAddrSpaceMap; + // Define available target features + // These must be defined in sorted order! + NoAsmVariants = true; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "SPIR", Opts); + } + virtual bool hasFeature(StringRef Feature) const { + return Feature == "spir"; + } + + virtual void getTargetBuiltins(const Builtin::Info *&Records, + unsigned &NumRecords) const {} + virtual const char *getClobbers() const { + return ""; + } + virtual void getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const {} + virtual bool validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const { + return true; + } + virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const {} + virtual BuiltinVaListKind getBuiltinVaListKind() const { + return TargetInfo::VoidPtrBuiltinVaList; + } + }; + + + class SPIR32TargetInfo : public SPIRTargetInfo { + public: + SPIR32TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) { + PointerWidth = PointerAlign = 32; + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = IntPtrType = TargetInfo::SignedInt; + DescriptionString + = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" + "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-" + "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-" + "v512:512:512-v1024:1024:1024"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "SPIR32", Opts); + } + }; + + class SPIR64TargetInfo : public SPIRTargetInfo { + public: + SPIR64TargetInfo(const std::string& triple) : SPIRTargetInfo(triple) { + PointerWidth = PointerAlign = 64; + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = IntPtrType = TargetInfo::SignedLong; + DescriptionString + = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-" + "f32:32:32-f64:64:64-v16:16:16-v24:32:32-v32:32:32-v48:64:64-" + "v64:64:64-v96:128:128-v128:128:128-v192:256:256-v256:256:256-" + "v512:512:512-v1024:1024:1024"; + } + virtual void getTargetDefines(const LangOptions &Opts, + MacroBuilder &Builder) const { + DefineStd(Builder, "SPIR64", Opts); + } + }; +} + //===----------------------------------------------------------------------===// // Driver code @@ -4417,6 +5022,14 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::hexagon: return new HexagonTargetInfo(T); + case llvm::Triple::aarch64: + switch (os) { + case llvm::Triple::Linux: + return new LinuxTargetInfo<AArch64TargetInfo>(T); + default: + return new AArch64TargetInfo(T); + } + case llvm::Triple::arm: case llvm::Triple::thumb: if (Triple.isOSDarwin()) @@ -4435,7 +5048,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new BitrigTargetInfo<ARMTargetInfo>(T); case llvm::Triple::RTEMS: return new RTEMSTargetInfo<ARMTargetInfo>(T); - case llvm::Triple::NativeClient: + case llvm::Triple::NaCl: return new NaClTargetInfo<ARMTargetInfo>(T); default: return new ARMTargetInfo(T); @@ -4506,7 +5119,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { case llvm::Triple::le32: switch (os) { - case llvm::Triple::NativeClient: + case llvm::Triple::NaCl: return new NaClTargetInfo<PNaClTargetInfo>(T); default: return NULL; @@ -4575,10 +5188,6 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new SparcV8TargetInfo(T); } - // FIXME: Need a real SPU target. - case llvm::Triple::cellspu: - return new PS3SPUTargetInfo<PPC64TargetInfo>(T); - case llvm::Triple::tce: return new TCETargetInfo(T); @@ -4615,7 +5224,7 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new HaikuX86_32TargetInfo(T); case llvm::Triple::RTEMS: return new RTEMSX86_32TargetInfo(T); - case llvm::Triple::NativeClient: + case llvm::Triple::NaCl: return new NaClTargetInfo<X86_32TargetInfo>(T); default: return new X86_32TargetInfo(T); @@ -4646,19 +5255,34 @@ static TargetInfo *AllocateTarget(const std::string &T) { return new MinGWX86_64TargetInfo(T); case llvm::Triple::Win32: // This is what Triple.h supports now. return new VisualStudioWindowsX86_64TargetInfo(T); - case llvm::Triple::NativeClient: + case llvm::Triple::NaCl: return new NaClTargetInfo<X86_64TargetInfo>(T); default: return new X86_64TargetInfo(T); } + + case llvm::Triple::spir: { + llvm::Triple Triple(T); + if (Triple.getOS() != llvm::Triple::UnknownOS || + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + return NULL; + return new SPIR32TargetInfo(T); + } + case llvm::Triple::spir64: { + llvm::Triple Triple(T); + if (Triple.getOS() != llvm::Triple::UnknownOS || + Triple.getEnvironment() != llvm::Triple::UnknownEnvironment) + return NULL; + return new SPIR64TargetInfo(T); + } } } /// CreateTargetInfo - Return the target info object for the specified target /// triple. TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, - TargetOptions &Opts) { - llvm::Triple Triple(Opts.Triple); + TargetOptions *Opts) { + llvm::Triple Triple(Opts->Triple); // Construct the target OwningPtr<TargetInfo> Target(AllocateTarget(Triple.str())); @@ -4669,20 +5293,20 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, Target->setTargetOpts(Opts); // Set the target CPU if specified. - if (!Opts.CPU.empty() && !Target->setCPU(Opts.CPU)) { - Diags.Report(diag::err_target_unknown_cpu) << Opts.CPU; + if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) { + Diags.Report(diag::err_target_unknown_cpu) << Opts->CPU; return 0; } // Set the target ABI if specified. - if (!Opts.ABI.empty() && !Target->setABI(Opts.ABI)) { - Diags.Report(diag::err_target_unknown_abi) << Opts.ABI; + if (!Opts->ABI.empty() && !Target->setABI(Opts->ABI)) { + Diags.Report(diag::err_target_unknown_abi) << Opts->ABI; return 0; } // Set the target C++ ABI. - if (!Opts.CXXABI.empty() && !Target->setCXXABI(Opts.CXXABI)) { - Diags.Report(diag::err_target_unknown_cxxabi) << Opts.CXXABI; + if (!Opts->CXXABI.empty() && !Target->setCXXABI(Opts->CXXABI)) { + Diags.Report(diag::err_target_unknown_cxxabi) << Opts->CXXABI; return 0; } @@ -4694,8 +5318,8 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // Apply the user specified deltas. // First the enables. for (std::vector<std::string>::const_iterator - it = Opts.FeaturesAsWritten.begin(), - ie = Opts.FeaturesAsWritten.end(); + it = Opts->FeaturesAsWritten.begin(), + ie = Opts->FeaturesAsWritten.end(); it != ie; ++it) { const char *Name = it->c_str(); @@ -4711,8 +5335,8 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // Then the disables. for (std::vector<std::string>::const_iterator - it = Opts.FeaturesAsWritten.begin(), - ie = Opts.FeaturesAsWritten.end(); + it = Opts->FeaturesAsWritten.begin(), + ie = Opts->FeaturesAsWritten.end(); it != ie; ++it) { const char *Name = it->c_str(); @@ -4731,11 +5355,11 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags, // // FIXME: If we are completely confident that we have the right set, we only // need to pass the minuses. - Opts.Features.clear(); + Opts->Features.clear(); for (llvm::StringMap<bool>::const_iterator it = Features.begin(), ie = Features.end(); it != ie; ++it) - Opts.Features.push_back((it->second ? "+" : "-") + it->first().str()); - Target->HandleTargetFeatures(Opts.Features); + Opts->Features.push_back((it->second ? "+" : "-") + it->first().str()); + Target->HandleTargetFeatures(Opts->Features); return Target.take(); } diff --git a/contrib/llvm/tools/clang/lib/Basic/TokenKinds.cpp b/contrib/llvm/tools/clang/lib/Basic/TokenKinds.cpp index 8cdc1e3..6ce076e 100644 --- a/contrib/llvm/tools/clang/lib/Basic/TokenKinds.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/TokenKinds.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/TokenKinds.h" - #include <cassert> using namespace clang; diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp index 990bd0b..3eccdde 100644 --- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp @@ -13,10 +13,14 @@ #include "clang/Basic/Version.h" #include "clang/Basic/LLVM.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Config/config.h" -#include <cstring> +#include "llvm/Support/raw_ostream.h" #include <cstdlib> +#include <cstring> + +#ifdef HAVE_SVN_VERSION_INC +# include "SVNVersion.inc" +#endif namespace clang { @@ -32,7 +36,7 @@ std::string getClangRepositoryPath() { // If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us // pick up a tag in an SVN export, for example. - static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_32/final/lib/Basic/Version.cpp $"); + static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $"); if (URL.empty()) { URL = SVNRepository.slice(SVNRepository.find(':'), SVNRepository.find("/lib/Basic")); diff --git a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp b/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp index 4f479d0..8b781ab 100644 --- a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp +++ b/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp @@ -28,9 +28,9 @@ std::string VersionTuple::getAsString() const { raw_ostream& clang::operator<<(raw_ostream &Out, const VersionTuple &V) { Out << V.getMajor(); - if (llvm::Optional<unsigned> Minor = V.getMinor()) + if (Optional<unsigned> Minor = V.getMinor()) Out << '.' << *Minor; - if (llvm::Optional<unsigned> Subminor = V.getSubminor()) + if (Optional<unsigned> Subminor = V.getSubminor()) Out << '.' << *Subminor; return Out; } |