aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Basic
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-04-08 18:45:10 +0000
commit809500fc2c13c8173a16b052304d983864e4a1e1 (patch)
tree4fc2f184c499d106f29a386c452b49e5197bf63d /lib/Basic
parentbe7c9ec198dcdb5bf73a35bfbb00b3333cb87909 (diff)
downloadsrc-809500fc2c13c8173a16b052304d983864e4a1e1.tar.gz
src-809500fc2c13c8173a16b052304d983864e4a1e1.zip
Vendor import of clang trunk r178860:vendor/clang/clang-trunk-r178860
Notes
Notes: svn path=/vendor/clang/dist/; revision=249261 svn path=/vendor/clang/clang-trunk-r178860/; revision=249262; tag=vendor/clang/clang-trunk-r178860
Diffstat (limited to 'lib/Basic')
-rw-r--r--lib/Basic/Builtins.cpp2
-rw-r--r--lib/Basic/CMakeLists.txt30
-rw-r--r--lib/Basic/CharInfo.cpp81
-rw-r--r--lib/Basic/ConvertUTF.c571
-rw-r--r--lib/Basic/ConvertUTFWrapper.cpp76
-rw-r--r--lib/Basic/Diagnostic.cpp66
-rw-r--r--lib/Basic/DiagnosticIDs.cpp72
-rw-r--r--lib/Basic/FileManager.cpp50
-rw-r--r--lib/Basic/FileSystemStatCache.cpp20
-rw-r--r--lib/Basic/IdentifierTable.cpp21
-rw-r--r--lib/Basic/LangOptions.cpp10
-rw-r--r--lib/Basic/Module.cpp134
-rw-r--r--lib/Basic/OpenMPKinds.cpp43
-rw-r--r--lib/Basic/OperatorPrecedence.cpp76
-rw-r--r--lib/Basic/SourceLocation.cpp2
-rw-r--r--lib/Basic/SourceManager.cpp90
-rw-r--r--lib/Basic/TargetInfo.cpp24
-rw-r--r--lib/Basic/Targets.cpp810
-rw-r--r--lib/Basic/TokenKinds.cpp1
-rw-r--r--lib/Basic/Version.cpp10
-rw-r--r--lib/Basic/VersionTuple.cpp4
21 files changed, 1325 insertions, 868 deletions
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index c78a2921d4e5..242c204d6d80 100644
--- a/lib/Basic/Builtins.cpp
+++ b/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/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 73e693befa4f..34111691c82e 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -2,8 +2,7 @@ set(LLVM_LINK_COMPONENTS mc)
add_clang_library(clangBasic
Builtins.cpp
- ConvertUTF.c
- ConvertUTFWrapper.cpp
+ CharInfo.cpp
Diagnostic.cpp
DiagnosticIDs.cpp
FileManager.cpp
@@ -12,6 +11,8 @@ add_clang_library(clangBasic
LangOptions.cpp
Module.cpp
ObjCRuntime.cpp
+ OpenMPKinds.cpp
+ OperatorPrecedence.cpp
SourceLocation.cpp
SourceManager.cpp
TargetInfo.cpp
@@ -28,9 +29,25 @@ if( NOT IS_SYMLINK "${CLANG_SOURCE_DIR}" ) # See PR 8437
find_package(Subversion)
endif()
if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn")
- Subversion_WC_INFO(${CLANG_SOURCE_DIR} CLANG)
+ # Create custom target to generate the Subversion version include.
+ add_custom_target(clang_revision_tag ALL
+ COMMAND ${CMAKE_COMMAND} -DFIRST_SOURCE_DIR=${LLVM_MAIN_SRC_DIR}
+ -DFIRST_REPOSITORY=LLVM_REPOSITORY
+ -DSECOND_SOURCE_DIR=${CLANG_SOURCE_DIR}
+ -DSECOND_REPOSITORY=SVN_REPOSITORY
+ -DHEADER_FILE=${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc
+ -P ${LLVM_MAIN_SRC_DIR}/cmake/modules/GetSVN.cmake)
+
+ # Mark the generated header as being generated.
+message(STATUS "Expecting header to go in ${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc")
+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/SVNVersion.inc
+ PROPERTIES GENERATED TRUE
+ HEADER_FILE_ONLY TRUE)
+
+ # Tell Version.cpp that it needs to build with -DHAVE_SVN_VERSION_INC.
set_source_files_properties(Version.cpp
- PROPERTIES COMPILE_DEFINITIONS "SVN_REVISION=\"${CLANG_WC_REVISION}\"")
+ PROPERTIES COMPILE_DEFINITIONS "HAVE_SVN_VERSION_INC")
+
endif()
add_dependencies(clangBasic
@@ -49,3 +66,8 @@ add_dependencies(clangBasic
ClangDiagnosticSema
ClangDiagnosticSerialization
)
+
+# clangBasic depends on the version.
+if (Subversion_FOUND AND EXISTS "${CLANG_SOURCE_DIR}/.svn")
+ add_dependencies(clangBasic clang_revision_tag)
+endif() \ No newline at end of file
diff --git a/lib/Basic/CharInfo.cpp b/lib/Basic/CharInfo.cpp
new file mode 100644
index 000000000000..32b3277c927b
--- /dev/null
+++ b/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/lib/Basic/ConvertUTF.c b/lib/Basic/ConvertUTF.c
deleted file mode 100644
index d16965ddd872..000000000000
--- a/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/lib/Basic/ConvertUTFWrapper.cpp b/lib/Basic/ConvertUTFWrapper.cpp
deleted file mode 100644
index 6be3828d2868..000000000000
--- a/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/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 854c4c56bb7f..842bacb9a5d0 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/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/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index ed976436e284..353af4bd6df1 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/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/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index a816969b9144..9cc59027ab6e 100644
--- a/lib/Basic/FileManager.cpp
+++ b/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/lib/Basic/FileSystemStatCache.cpp b/lib/Basic/FileSystemStatCache.cpp
index 875d397a1dae..38c46299018c 100644
--- a/lib/Basic/FileSystemStatCache.cpp
+++ b/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/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 1965bf99338b..429d9d8cb21e 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/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/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index 991992a477e4..f8714b2389cb 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/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/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 76c7f8b364eb..13518cde6642 100644
--- a/lib/Basic/Module.cpp
+++ b/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/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
new file mode 100644
index 000000000000..835908d2a1b5
--- /dev/null
+++ b/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/lib/Basic/OperatorPrecedence.cpp b/lib/Basic/OperatorPrecedence.cpp
new file mode 100644
index 000000000000..f9de231c5e77
--- /dev/null
+++ b/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/lib/Basic/SourceLocation.cpp b/lib/Basic/SourceLocation.cpp
index 0d62f7bb4b8c..182209117966 100644
--- a/lib/Basic/SourceLocation.cpp
+++ b/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/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index cd0284a18e5d..1b8383bc4261 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/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/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 83d4e2bf63c9..70ea2351ec35 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/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/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index f36ef826d0b2..3eda9d8c1841 100644
--- a/lib/Basic/Targets.cpp
+++ b/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
@@ -3078,7 +3553,9 @@ public:
// name.
if (Name == "apcs-gnu") {
DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
- SizeType = UnsignedLong;
+ // size_t is unsigned int on FreeBSD.
+ if (getTriple().getOS() != llvm::Triple::FreeBSD)
+ SizeType = UnsignedLong;
// Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
WCharType = SignedInt;
@@ -3124,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;
}
@@ -3197,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")
@@ -3208,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) {
@@ -3318,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;
@@ -3348,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] == '+' ||
@@ -3359,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;
@@ -3377,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[] = {
@@ -3458,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.
@@ -3474,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
@@ -3513,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);
@@ -4040,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;
}
}
@@ -4058,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;
}
@@ -4087,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[] = {
@@ -4102,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;
}
@@ -4168,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 {
@@ -4183,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 {
@@ -4202,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 {
@@ -4285,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 {
@@ -4308,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) {
@@ -4316,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 {
@@ -4399,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
@@ -4415,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())
@@ -4433,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);
@@ -4504,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;
@@ -4573,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);
@@ -4613,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);
@@ -4644,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()));
@@ -4667,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;
}
@@ -4692,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();
@@ -4709,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();
@@ -4729,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/lib/Basic/TokenKinds.cpp b/lib/Basic/TokenKinds.cpp
index 8cdc1e31950c..6ce076e57a6c 100644
--- a/lib/Basic/TokenKinds.cpp
+++ b/lib/Basic/TokenKinds.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/TokenKinds.h"
-
#include <cassert>
using namespace clang;
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index dc7d8d14eefb..7381e7025083 100644
--- a/lib/Basic/Version.cpp
+++ b/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/lib/Basic/VersionTuple.cpp b/lib/Basic/VersionTuple.cpp
index 4f479d00d6cc..8b781ab0a304 100644
--- a/lib/Basic/VersionTuple.cpp
+++ b/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;
}