aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2009-10-14 18:03:49 +0000
commit4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch)
tree137ebebcae16fb0ce7ab4af456992bbd8d22fced /include/clang/Basic
parent5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff)
downloadsrc-4c8b24812ddcd1dedaca343a6d4e76f91f398981.tar.gz
src-4c8b24812ddcd1dedaca343a6d4e76f91f398981.zip
Update clang to r84119.vendor/clang/clang-r84119
Notes
Notes: svn path=/vendor/clang/dist/; revision=198092 svn path=/vendor/clang/clang-84119/; revision=198093; tag=vendor/clang/clang-r84119
Diffstat (limited to 'include/clang/Basic')
-rw-r--r--include/clang/Basic/Builtins.def173
-rw-r--r--include/clang/Basic/Builtins.h23
-rw-r--r--include/clang/Basic/ConvertUTF.h82
-rw-r--r--include/clang/Basic/Diagnostic.h194
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td3
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td10
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td22
-rw-r--r--include/clang/Basic/DiagnosticGroups.td21
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td12
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td17
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td483
-rw-r--r--include/clang/Basic/FileManager.h46
-rw-r--r--include/clang/Basic/IdentifierTable.h127
-rw-r--r--include/clang/Basic/LangOptions.h46
-rw-r--r--include/clang/Basic/Makefile4
-rw-r--r--include/clang/Basic/OnDiskHashTable.h88
-rw-r--r--include/clang/Basic/PartialDiagnostic.h155
-rw-r--r--include/clang/Basic/SourceLocation.h90
-rw-r--r--include/clang/Basic/SourceManager.h242
-rw-r--r--include/clang/Basic/SourceManagerInternals.h24
-rw-r--r--include/clang/Basic/TargetInfo.h176
-rw-r--r--include/clang/Basic/TokenKinds.def1
-rw-r--r--include/clang/Basic/TokenKinds.h2
-rw-r--r--include/clang/Basic/Version.h30
24 files changed, 1452 insertions, 619 deletions
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index c2f4061c5d78..27997858c00c 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -35,7 +35,10 @@
// a -> __builtin_va_list
// A -> "reference" to __builtin_va_list
// V -> Vector, following num elements and a base type.
+// X -> _Complex, followed by the base type.
// P -> FILE
+// J -> jmp_buf
+// SJ -> sigjmp_buf
// . -> "...". This may only occur at the end of the function list.
//
// Types maybe prefixed with the following modifiers:
@@ -54,15 +57,16 @@
// of the function. These must be kept in sync with the predicates in the
// Builtin::Context class. Currently we have:
// n -> nothrow
+// r -> noreturn
// c -> const
// F -> this is a libc/libm function with a '__builtin_' prefix added.
// f -> this is a libc/libm function without the '__builtin_' prefix. It can
// be followed by ':headername:' to state which header this function
// comes from.
-// p:N: -> this is a printf-like function whose Nth argument is the format
+// p:N: -> this is a printf-like function whose Nth argument is the format
// string.
// P:N: -> similar to the p:N: attribute, but the function is like vprintf
-// in that it accepts its arguments as a va_list rather than
+// in that it accepts its arguments as a va_list rather than
// through an ellipsis
// e -> const, but only when -fmath-errno=0
// FIXME: gcc has nonnull
@@ -72,28 +76,152 @@
#endif
// Standard libc/libm functions:
+BUILTIN(__builtin_atan2 , "ddd" , "nc")
+BUILTIN(__builtin_atan2f, "fff" , "nc")
+BUILTIN(__builtin_atan2l, "LdLdLd", "nc")
+BUILTIN(__builtin_abs , "ii" , "ncF")
+BUILTIN(__builtin_copysign, "ddd", "ncF")
+BUILTIN(__builtin_copysignf, "fff", "ncF")
+BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
+BUILTIN(__builtin_fabs , "dd" , "ncF")
+BUILTIN(__builtin_fabsf, "ff" , "ncF")
+BUILTIN(__builtin_fabsl, "LdLd", "ncF")
+BUILTIN(__builtin_fmod , "ddd" , "nc")
+BUILTIN(__builtin_fmodf, "fff" , "nc")
+BUILTIN(__builtin_fmodl, "LdLdLd", "nc")
+BUILTIN(__builtin_frexp , "ddi*" , "nc")
+BUILTIN(__builtin_frexpf, "ffi*" , "nc")
+BUILTIN(__builtin_frexpl, "LdLdi*", "nc")
BUILTIN(__builtin_huge_val, "d", "nc")
BUILTIN(__builtin_huge_valf, "f", "nc")
BUILTIN(__builtin_huge_vall, "Ld", "nc")
BUILTIN(__builtin_inf , "d" , "nc")
BUILTIN(__builtin_inff , "f" , "nc")
BUILTIN(__builtin_infl , "Ld" , "nc")
+BUILTIN(__builtin_ldexp , "ddi" , "nc")
+BUILTIN(__builtin_ldexpf, "ffi" , "nc")
+BUILTIN(__builtin_ldexpl, "LdLdi", "nc")
+BUILTIN(__builtin_modf , "ddd*" , "nc")
+BUILTIN(__builtin_modff, "fff*" , "nc")
+BUILTIN(__builtin_modfl, "LdLdLd*", "nc")
BUILTIN(__builtin_nan, "dcC*" , "ncF")
BUILTIN(__builtin_nanf, "fcC*" , "ncF")
BUILTIN(__builtin_nanl, "LdcC*", "ncF")
BUILTIN(__builtin_nans, "dcC*" , "ncF")
BUILTIN(__builtin_nansf, "fcC*" , "ncF")
BUILTIN(__builtin_nansl, "LdcC*", "ncF")
-BUILTIN(__builtin_abs , "ii" , "ncF")
-BUILTIN(__builtin_fabs , "dd" , "ncF")
-BUILTIN(__builtin_fabsf, "ff" , "ncF")
-BUILTIN(__builtin_fabsl, "LdLd", "ncF")
-BUILTIN(__builtin_copysign, "ddd", "ncF")
-BUILTIN(__builtin_copysignf, "fff", "ncF")
-BUILTIN(__builtin_copysignl, "LdLdLd", "ncF")
BUILTIN(__builtin_powi , "ddi" , "nc")
BUILTIN(__builtin_powif, "ffi" , "nc")
BUILTIN(__builtin_powil, "LdLdi", "nc")
+BUILTIN(__builtin_pow , "ddd" , "nc")
+BUILTIN(__builtin_powf, "fff" , "nc")
+BUILTIN(__builtin_powl, "LdLdLd", "nc")
+
+// Standard unary libc/libm functions with double/float/long double variants:
+BUILTIN(__builtin_acos , "dd" , "nc")
+BUILTIN(__builtin_acosf, "ff" , "nc")
+BUILTIN(__builtin_acosl, "LdLd", "nc")
+BUILTIN(__builtin_asin , "dd" , "nc")
+BUILTIN(__builtin_asinf, "ff" , "nc")
+BUILTIN(__builtin_asinl, "LdLd", "nc")
+BUILTIN(__builtin_atan , "dd" , "nc")
+BUILTIN(__builtin_atanf, "ff" , "nc")
+BUILTIN(__builtin_atanl, "LdLd", "nc")
+BUILTIN(__builtin_ceil , "dd" , "nc")
+BUILTIN(__builtin_ceilf, "ff" , "nc")
+BUILTIN(__builtin_ceill, "LdLd", "nc")
+BUILTIN(__builtin_cos , "dd" , "nc")
+BUILTIN(__builtin_cosf, "ff" , "nc")
+BUILTIN(__builtin_cosh , "dd" , "nc")
+BUILTIN(__builtin_coshf, "ff" , "nc")
+BUILTIN(__builtin_coshl, "LdLd", "nc")
+BUILTIN(__builtin_cosl, "LdLd", "nc")
+BUILTIN(__builtin_exp , "dd" , "nc")
+BUILTIN(__builtin_expf, "ff" , "nc")
+BUILTIN(__builtin_expl, "LdLd", "nc")
+BUILTIN(__builtin_floor , "dd" , "nc")
+BUILTIN(__builtin_floorf, "ff" , "nc")
+BUILTIN(__builtin_floorl, "LdLd", "nc")
+BUILTIN(__builtin_log , "dd" , "nc")
+BUILTIN(__builtin_log10 , "dd" , "nc")
+BUILTIN(__builtin_log10f, "ff" , "nc")
+BUILTIN(__builtin_log10l, "LdLd", "nc")
+BUILTIN(__builtin_logf, "ff" , "nc")
+BUILTIN(__builtin_logl, "LdLd", "nc")
+BUILTIN(__builtin_sin , "dd" , "nc")
+BUILTIN(__builtin_sinf, "ff" , "nc")
+BUILTIN(__builtin_sinh , "dd" , "nc")
+BUILTIN(__builtin_sinhf, "ff" , "nc")
+BUILTIN(__builtin_sinhl, "LdLd", "nc")
+BUILTIN(__builtin_sinl, "LdLd", "nc")
+BUILTIN(__builtin_sqrt , "dd" , "nc")
+BUILTIN(__builtin_sqrtf, "ff" , "nc")
+BUILTIN(__builtin_sqrtl, "LdLd", "nc")
+BUILTIN(__builtin_tan , "dd" , "nc")
+BUILTIN(__builtin_tanf, "ff" , "nc")
+BUILTIN(__builtin_tanh , "dd" , "nc")
+BUILTIN(__builtin_tanhf, "ff" , "nc")
+BUILTIN(__builtin_tanhl, "LdLd", "nc")
+BUILTIN(__builtin_tanl, "LdLd", "nc")
+
+// C99 complex builtins
+BUILTIN(__builtin_cabs, "dXd", "Fnc")
+BUILTIN(__builtin_cabsf, "fXf", "Fnc")
+BUILTIN(__builtin_cabsl, "LdXLd", "Fnc")
+BUILTIN(__builtin_cacos, "XdXd", "Fnc")
+BUILTIN(__builtin_cacosf, "XfXf", "Fnc")
+BUILTIN(__builtin_cacosl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_carg, "dXd", "Fnc")
+BUILTIN(__builtin_cargf, "fXf", "Fnc")
+BUILTIN(__builtin_cargl, "LdXLd", "Fnc")
+BUILTIN(__builtin_casin, "XdXd", "Fnc")
+BUILTIN(__builtin_casinf, "XfXf", "Fnc")
+BUILTIN(__builtin_casinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_catan, "XdXd", "Fnc")
+BUILTIN(__builtin_catanf, "XfXf", "Fnc")
+BUILTIN(__builtin_catanl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ccos, "XdXd", "Fnc")
+BUILTIN(__builtin_ccosf, "XfXf", "Fnc")
+BUILTIN(__builtin_ccosl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ccosh, "XdXd", "Fnc")
+BUILTIN(__builtin_ccoshf, "XfXf", "Fnc")
+BUILTIN(__builtin_ccoshl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cexp, "XdXd", "Fnc")
+BUILTIN(__builtin_cexpf, "XfXf", "Fnc")
+BUILTIN(__builtin_cexpl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cimag, "dXd", "Fnc")
+BUILTIN(__builtin_cimagf, "fXf", "Fnc")
+BUILTIN(__builtin_cimagl, "LdXLd", "Fnc")
+BUILTIN(__builtin_conj, "dXd", "Fnc")
+BUILTIN(__builtin_conjf, "fXf", "Fnc")
+BUILTIN(__builtin_conjl, "LdXLd", "Fnc")
+BUILTIN(__builtin_clog, "XdXd", "Fnc")
+BUILTIN(__builtin_clogf, "XfXf", "Fnc")
+BUILTIN(__builtin_clogl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cproj, "XdXd", "Fnc")
+BUILTIN(__builtin_cprojf, "XfXf", "Fnc")
+BUILTIN(__builtin_cprojl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_cpow, "XdXdXd", "Fnc")
+BUILTIN(__builtin_cpowf, "XfXfXf", "Fnc")
+BUILTIN(__builtin_cpowl, "XLdXLdXLd", "Fnc")
+BUILTIN(__builtin_creal, "dXd", "Fnc")
+BUILTIN(__builtin_crealf, "fXf", "Fnc")
+BUILTIN(__builtin_creall, "LdXLd", "Fnc")
+BUILTIN(__builtin_csin, "XdXd", "Fnc")
+BUILTIN(__builtin_csinf, "XfXf", "Fnc")
+BUILTIN(__builtin_csinl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csinh, "XdXd", "Fnc")
+BUILTIN(__builtin_csinhf, "XfXf", "Fnc")
+BUILTIN(__builtin_csinhl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_csqrt, "XdXd", "Fnc")
+BUILTIN(__builtin_csqrtf, "XfXf", "Fnc")
+BUILTIN(__builtin_csqrtl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ctan, "XdXd", "Fnc")
+BUILTIN(__builtin_ctanf, "XfXf", "Fnc")
+BUILTIN(__builtin_ctanl, "XLdXLd", "Fnc")
+BUILTIN(__builtin_ctanh, "XdXd", "Fnc")
+BUILTIN(__builtin_ctanhf, "XfXf", "Fnc")
+BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc")
// FP Comparisons.
BUILTIN(__builtin_isgreater , "i.", "nc")
@@ -103,6 +231,14 @@ BUILTIN(__builtin_islessequal , "i.", "nc")
BUILTIN(__builtin_islessgreater , "i.", "nc")
BUILTIN(__builtin_isunordered , "i.", "nc")
+// Unary FP classification
+// BUILTIN(__builtin_fpclassify, "iiiii.", "nc")
+BUILTIN(__builtin_isfinite, "i.", "nc")
+BUILTIN(__builtin_isinf, "i.", "nc")
+BUILTIN(__builtin_isinf_sign, "i.", "nc")
+BUILTIN(__builtin_isnan, "i.", "nc")
+BUILTIN(__builtin_isnormal, "i.", "nc")
+
// Builtins for arithmetic.
BUILTIN(__builtin_clz , "iUi" , "nc")
BUILTIN(__builtin_clzl , "iULi" , "nc")
@@ -138,6 +274,7 @@ BUILTIN(__builtin_stdarg_start, "vA.", "n")
BUILTIN(__builtin_bcmp, "iv*v*z", "n")
BUILTIN(__builtin_bcopy, "vv*v*z", "n")
BUILTIN(__builtin_bzero, "vv*z", "n")
+BUILTIN(__builtin_memchr, "v*vC*iz", "nF")
BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF")
BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF")
BUILTIN(__builtin_memmove, "v*v*vC*z", "nF")
@@ -169,6 +306,8 @@ BUILTIN(__builtin_flt_rounds, "i", "nc")
BUILTIN(__builtin_setjmp, "iv**", "")
BUILTIN(__builtin_longjmp, "vv**i", "")
BUILTIN(__builtin_unwind_init, "v", "")
+BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
+BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
// GCC Object size checking builtins
BUILTIN(__builtin_object_size, "zv*i", "n")
@@ -192,7 +331,9 @@ BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
BUILTIN(__builtin_expect, "iii" , "nc")
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
-BUILTIN(__builtin_trap, "v", "n")
+BUILTIN(__builtin_abort, "v", "Fnr")
+BUILTIN(__builtin_trap, "v", "nr")
+BUILTIN(__builtin_unreachable, "v", "nr")
BUILTIN(__builtin_shufflevector, "v." , "nc")
@@ -335,6 +476,8 @@ BUILTIN(__sync_fetch_and_umax, "UiUi*Ui", "n")
// C99 library functions
// C99 stdlib.h
LIBBUILTIN(calloc, "v*zz", "f", "stdlib.h")
+LIBBUILTIN(exit, "vi", "fr", "stdlib.h")
+LIBBUILTIN(_Exit, "vi", "fr", "stdlib.h")
LIBBUILTIN(malloc, "v*z", "f", "stdlib.h")
LIBBUILTIN(realloc, "v*v*z", "f", "stdlib.h")
// C99 string.h
@@ -365,6 +508,8 @@ LIBBUILTIN(vprintf, "icC*a", "fP:0:", "stdio.h")
LIBBUILTIN(vfprintf, "i.", "fP:1:", "stdio.h")
LIBBUILTIN(vsnprintf, "ic*zcC*a", "fP:2:", "stdio.h")
LIBBUILTIN(vsprintf, "ic*cC*a", "fP:1:", "stdio.h")
+// C99
+LIBBUILTIN(longjmp, "vJi", "fr", "setjmp.h")
// Non-C library functions
// FIXME: Non-C-standard stuff shouldn't be builtins in non-GNU mode!
@@ -377,15 +522,17 @@ LIBBUILTIN(strndup, "c*cC*z", "f", "string.h")
// POSIX strings.h
LIBBUILTIN(index, "c*cC*i", "f", "strings.h")
LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h")
+// POSIX unistd.h
+LIBBUILTIN(_exit, "vi", "fr", "unistd.h")
+// POSIX setjmp.h
+LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h")
+LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h")
// FIXME: This type isn't very correct, it should be
// id objc_msgSend(id, SEL)
// but we need new type letters for that.
LIBBUILTIN(objc_msgSend, "v*.", "f", "objc/message.h")
-// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
-// target-specific builtins, perhaps?
-
// Builtin math library functions
LIBBUILTIN(pow, "ddd", "fe", "math.h")
LIBBUILTIN(powl, "LdLdLd", "fe", "math.h")
diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h
index f770c5089eec..07f091a58a4e 100644
--- a/include/clang/Basic/Builtins.h
+++ b/include/clang/Basic/Builtins.h
@@ -17,6 +17,10 @@
#include <cstring>
+// VC++ defines 'alloca' as an object-like macro, which interferes with our
+// builtins.
+#undef alloca
+
namespace llvm {
template <typename T> class SmallVectorImpl;
}
@@ -63,35 +67,40 @@ public:
/// \brief Popular the vector with the names of all of the builtins.
void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
bool NoBuiltins);
-
+
/// Builtin::GetName - Return the identifier name for the specified builtin,
/// e.g. "__builtin_abs".
const char *GetName(unsigned ID) const {
return GetRecord(ID).Name;
}
-
+
/// GetTypeString - Get the type descriptor string for the specified builtin.
const char *GetTypeString(unsigned ID) const {
return GetRecord(ID).Type;
}
-
+
/// isConst - Return true if this function has no side effects and doesn't
/// read memory.
bool isConst(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'c') != 0;
}
-
+
/// isNoThrow - Return true if we know this builtin never throws an exception.
bool isNoThrow(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'n') != 0;
}
-
+
+ /// isNoReturn - Return true if we know this builtin never returns.
+ bool isNoReturn(unsigned ID) const {
+ return strchr(GetRecord(ID).Attributes, 'r') != 0;
+ }
+
/// isLibFunction - Return true if this is a builtin for a libc/libm function,
/// with a "__builtin_" prefix (e.g. __builtin_abs).
bool isLibFunction(unsigned ID) const {
return strchr(GetRecord(ID).Attributes, 'F') != 0;
}
-
+
/// \brief Determines whether this builtin is a predefined libc/libm
/// function, such as "malloc", where we know the signature a
/// priori.
@@ -115,7 +124,7 @@ public:
bool hasVAListUse(unsigned ID) const {
return strpbrk(GetRecord(ID).Type, "Aa") != 0;
}
-
+
/// isConstWithoutErrno - Return true if this function has no side
/// effects and doesn't read memory, except for possibly errno. Such
/// functions can be const when the MathErrno lang option is
diff --git a/include/clang/Basic/ConvertUTF.h b/include/clang/Basic/ConvertUTF.h
index 73e2fcd12fee..4da2ad757223 100644
--- a/include/clang/Basic/ConvertUTF.h
+++ b/include/clang/Basic/ConvertUTF.h
@@ -8,9 +8,9 @@
*==------------------------------------------------------------------------==*/
/*
* 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
@@ -18,9 +18,9 @@
* 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
@@ -41,7 +41,7 @@
Each routine converts the text between *sourceStart and sourceEnd,
putting the result into the buffer between *targetStart and
- targetEnd. Note: the end pointers are *after* the last item: e.g.
+ targetEnd. Note: the end pointers are *after* the last item: e.g.
*(sourceEnd - 1) is the last item.
The return result indicates whether the conversion was successful,
@@ -53,12 +53,12 @@
the respective buffers.
Input parameters:
- sourceStart - pointer to a pointer to the source buffer.
- The contents of this are modified on return so that
- it points at the next thing to be converted.
- targetStart - similarly, pointer to pointer to the target buffer.
- sourceEnd, targetEnd - respectively pointers to the ends of the
- two buffers, for overflow checking only.
+ sourceStart - pointer to a pointer to the source buffer.
+ The contents of this are modified on return so that
+ it points at the next thing to be converted.
+ targetStart - similarly, pointer to pointer to the target buffer.
+ sourceEnd, targetEnd - respectively pointers to the ends of the
+ two buffers, for overflow checking only.
These conversion functions take a ConversionFlags argument. When this
flag is set to strict, both irregular sequences and isolated surrogates
@@ -75,15 +75,15 @@
they constitute an error.
Output parameters:
- The value "sourceIllegal" is returned from some routines if the input
- sequence is malformed. When "sourceIllegal" is returned, the source
- value will point to the illegal value that caused the problem. E.g.,
- in UTF-8 when a sequence is malformed, it points to the start of the
- malformed sequence.
+ The value "sourceIllegal" is returned from some routines if the input
+ sequence is malformed. When "sourceIllegal" is returned, the source
+ value will point to the illegal value that caused the problem. E.g.,
+ in UTF-8 when a sequence is malformed, it points to the start of the
+ malformed sequence.
Author: Mark E. Davis, 1994.
Rev History: Rick McGowan, fixes & updates May 2001.
- Fixes & updates, Sept 2001.
+ Fixes & updates, Sept 2001.
------------------------------------------------------------------------ */
@@ -95,10 +95,10 @@
bit mask & shift operations.
------------------------------------------------------------------------ */
-typedef unsigned long UTF32; /* at least 32 bits */
-typedef unsigned short UTF16; /* at least 16 bits */
-typedef unsigned char UTF8; /* typically 8 bits */
-typedef unsigned char Boolean; /* 0 or 1 */
+typedef unsigned long UTF32; /* at least 32 bits */
+typedef unsigned short UTF16; /* at least 16 bits */
+typedef unsigned char UTF8; /* typically 8 bits */
+typedef unsigned char Boolean; /* 0 or 1 */
/* Some fundamental constants */
#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
@@ -108,15 +108,15 @@ typedef unsigned char Boolean; /* 0 or 1 */
#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
typedef enum {
- conversionOK, /* conversion successful */
- sourceExhausted, /* partial character in source, but hit end */
- targetExhausted, /* insuff. room in target for conversion */
- sourceIllegal /* source sequence is illegal/malformed */
+ conversionOK, /* conversion successful */
+ sourceExhausted, /* partial character in source, but hit end */
+ targetExhausted, /* insuff. room in target for conversion */
+ sourceIllegal /* source sequence is illegal/malformed */
} ConversionResult;
typedef enum {
- strictConversion = 0,
- lenientConversion
+ strictConversion = 0,
+ lenientConversion
} ConversionFlags;
/* This is for C++ and does no harm in C */
@@ -125,29 +125,29 @@ extern "C" {
#endif
ConversionResult ConvertUTF8toUTF16 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
#ifdef CLANG_NEEDS_THESE_ONE_DAY
ConversionResult ConvertUTF16toUTF8 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
ConversionResult ConvertUTF8toUTF32 (
- const UTF8** sourceStart, const UTF8* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF8 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
-
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
ConversionResult ConvertUTF16toUTF32 (
- const UTF16** sourceStart, const UTF16* sourceEnd,
- UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
ConversionResult ConvertUTF32toUTF16 (
- const UTF32** sourceStart, const UTF32* sourceEnd,
- UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
#endif
Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 207710bdff31..380192e9dae6 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -15,7 +15,9 @@
#define LLVM_CLANG_DIAGNOSTIC_H
#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/type_traits.h"
#include <string>
+#include <vector>
#include <cassert>
namespace llvm {
@@ -23,12 +25,14 @@ namespace llvm {
}
namespace clang {
- class DiagnosticClient;
- class SourceRange;
+ class DeclContext;
class DiagnosticBuilder;
+ class DiagnosticClient;
class IdentifierInfo;
class LangOptions;
-
+ class PartialDiagnostic;
+ class SourceRange;
+
// Import the diagnostic enums themselves.
namespace diag {
// Start position for diagnostics.
@@ -44,7 +48,7 @@ namespace clang {
};
class CustomDiagInfo;
-
+
/// diag::kind - All of the diagnostics that can be emitted by the frontend.
typedef unsigned kind;
@@ -55,7 +59,7 @@ namespace clang {
NUM_BUILTIN_COMMON_DIAGNOSTICS
#undef DIAG
};
-
+
/// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
/// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
/// (emit as an error). It allows clients to map errors to
@@ -67,13 +71,13 @@ namespace clang {
MAP_WARNING = 2, //< Map this diagnostic to a warning.
MAP_ERROR = 3, //< Map this diagnostic to an error.
MAP_FATAL = 4, //< Map this diagnostic to a fatal error.
-
+
/// Map this diagnostic to "warning", but make it immune to -Werror. This
/// happens when you specify -Wno-error=foo.
MAP_WARNING_NO_WERROR = 5
};
}
-
+
/// \brief Annotates a diagnostic with some code that should be
/// inserted, removed, or replaced to fix the problem.
///
@@ -102,7 +106,7 @@ public:
/// \brief Create a code modification hint that inserts the given
/// code string at a specific location.
- static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
+ static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
const std::string &Code) {
CodeModificationHint Hint;
Hint.InsertionLoc = InsertionLoc;
@@ -120,7 +124,7 @@ public:
/// \brief Create a code modification hint that replaces the given
/// source range with the given code string.
- static CodeModificationHint CreateReplacement(SourceRange RemoveRange,
+ static CodeModificationHint CreateReplacement(SourceRange RemoveRange,
const std::string &Code) {
CodeModificationHint Hint;
Hint.RemoveRange = RemoveRange;
@@ -140,13 +144,13 @@ public:
enum Level {
Ignored, Note, Warning, Error, Fatal
};
-
+
/// ExtensionHandling - How do we handle otherwise-unmapped extension? This
/// is controlled by -pedantic and -pedantic-errors.
enum ExtensionHandling {
Ext_Ignore, Ext_Warn, Ext_Error
};
-
+
enum ArgumentKind {
ak_std_string, // std::string
ak_c_string, // const char *
@@ -155,14 +159,17 @@ public:
ak_identifierinfo, // IdentifierInfo
ak_qualtype, // QualType
ak_declarationname, // DeclarationName
- ak_nameddecl // NamedDecl *
+ ak_nameddecl, // NamedDecl *
+ ak_nestednamespec, // NestedNameSpecifier *
+ ak_declcontext // DeclContext *
};
-private:
+private:
unsigned char AllExtensionsSilenced; // Used by __extension__
bool IgnoreAllWarnings; // Ignore all warnings: -w
- bool WarningsAsErrors; // Treat warnings like errors:
+ bool WarningsAsErrors; // Treat warnings like errors:
bool SuppressSystemWarnings; // Suppress warnings in system headers.
+ bool SuppressAllDiagnostics; // Suppress all diagnostics.
ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
DiagnosticClient *Client;
@@ -172,13 +179,15 @@ private:
/// when the mapping was established as a user mapping. If the high bit is
/// clear, then the low bits are set to the default value, and should be
/// mapped with -pedantic, -Werror, etc.
- mutable unsigned char DiagMappings[diag::DIAG_UPPER_LIMIT/2];
-
+
+ typedef std::vector<unsigned char> DiagMappings;
+ mutable std::vector<DiagMappings> DiagMappingsStack;
+
/// ErrorOccurred / FatalErrorOccurred - This is set to true when an error or
/// fatal error is emitted, and is sticky.
bool ErrorOccurred;
bool FatalErrorOccurred;
-
+
/// LastDiagLevel - This is the level of the last diagnostic emitted. This is
/// used to emit continuation diagnostics with the same level as the
/// diagnostic that they follow.
@@ -204,44 +213,70 @@ private:
public:
explicit Diagnostic(DiagnosticClient *client = 0);
~Diagnostic();
-
+
//===--------------------------------------------------------------------===//
// Diagnostic characterization methods, used by a client to customize how
//
-
+
DiagnosticClient *getClient() { return Client; };
const DiagnosticClient *getClient() const { return Client; };
-
+
+
+ /// pushMappings - Copies the current DiagMappings and pushes the new copy
+ /// onto the top of the stack.
+ void pushMappings();
+
+ /// popMappings - Pops the current DiagMappings off the top of the stack
+ /// causing the new top of the stack to be the active mappings. Returns
+ /// true if the pop happens, false if there is only one DiagMapping on the
+ /// stack.
+ bool popMappings();
+
void setClient(DiagnosticClient* client) { Client = client; }
/// setIgnoreAllWarnings - When set to true, any unmapped warnings are
/// ignored. If this and WarningsAsErrors are both set, then this one wins.
void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; }
-
+
/// setWarningsAsErrors - When set to true, any warnings reported are issued
/// as errors.
void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; }
bool getWarningsAsErrors() const { return WarningsAsErrors; }
-
+
/// setSuppressSystemWarnings - When set to true mask warnings that
/// come from system headers.
void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; }
bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; }
+ /// \brief Suppress all diagnostics, to silence the front end when we
+ /// know that we don't want any more diagnostics to be passed along to the
+ /// client
+ void setSuppressAllDiagnostics(bool Val = true) {
+ SuppressAllDiagnostics = Val;
+ }
+ bool getSuppressAllDiagnostics() const { return SuppressAllDiagnostics; }
+
+ /// \brief Pretend that the last diagnostic issued was ignored. This can
+ /// be used by clients who suppress diagnostics themselves.
+ void setLastDiagnosticIgnored() {
+ LastDiagLevel = Ignored;
+ }
+
/// setExtensionHandlingBehavior - This controls whether otherwise-unmapped
/// extension diagnostics are mapped onto ignore/warning/error. This
/// corresponds to the GCC -pedantic and -pedantic-errors option.
void setExtensionHandlingBehavior(ExtensionHandling H) {
ExtBehavior = H;
}
-
+
/// AllExtensionsSilenced - This is a counter bumped when an __extension__
/// block is encountered. When non-zero, all extension diagnostics are
/// entirely silenced, no matter how they are mapped.
void IncrementAllExtensionsSilenced() { ++AllExtensionsSilenced; }
void DecrementAllExtensionsSilenced() { --AllExtensionsSilenced; }
-
+ bool hasAllExtensionsSilenced() { return AllExtensionsSilenced != 0; }
+
/// setDiagnosticMapping - This allows the client to specify that certain
/// warnings are ignored. Notes can never be mapped, errors can only be
/// mapped to fatal, and WARNINGs and EXTENSIONs can be mapped arbitrarily.
@@ -252,7 +287,7 @@ public:
"Cannot map errors!");
setDiagnosticMappingInternal(Diag, Map, true);
}
-
+
/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
/// "unknown-pragmas" to have the specified mapping. This returns true and
/// ignores the request if "Group" was unknown, false otherwise.
@@ -263,13 +298,13 @@ public:
unsigned getNumErrors() const { return NumErrors; }
unsigned getNumDiagnostics() const { return NumDiagnostics; }
-
+
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
/// and level. If this is the first request for this diagnosic, it is
/// registered and created, otherwise the existing ID is returned.
unsigned getCustomDiagID(Level L, const char *Message);
-
-
+
+
/// ConvertArgToString - This method converts a diagnostic argument (as an
/// intptr_t) into the string that represents it.
void ConvertArgToString(ArgumentKind Kind, intptr_t Val,
@@ -279,12 +314,12 @@ public:
ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, Output,
ArgToStringCookie);
}
-
+
void SetArgToStringFn(ArgToStringFnTy Fn, void *Cookie) {
ArgToStringFn = Fn;
ArgToStringCookie = Cookie;
}
-
+
//===--------------------------------------------------------------------===//
// Diagnostic classification and reporting interfaces.
//
@@ -292,7 +327,7 @@ public:
/// getDescription - Given a diagnostic ID, return a description of the
/// issue.
const char *getDescription(unsigned DiagID) const;
-
+
/// isNoteWarningOrExtension - Return true if the unmapped diagnostic
/// level of the specified diagnostic ID is a Warning or Extension.
/// This only works on builtin diagnostics, not custom ones, and is not legal to
@@ -302,12 +337,12 @@ public:
/// \brief Determine whether the given built-in diagnostic ID is a
/// Note.
static bool isBuiltinNote(unsigned DiagID);
-
+
/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
/// ID is for an extension of some sort.
///
static bool isBuiltinExtensionDiag(unsigned DiagID);
-
+
/// getWarningOptionForDiag - Return the lowest-level warning option that
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
/// the diagnostic, this returns null.
@@ -326,8 +361,8 @@ public:
/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
/// object, classify the specified diagnostic ID into a Level, consumable by
/// the DiagnosticClient.
- Level getDiagnosticLevel(unsigned DiagID) const;
-
+ Level getDiagnosticLevel(unsigned DiagID) const;
+
/// Report - Issue the message to the client. @c DiagID is a member of the
/// @c diag::kind enum. This actually returns aninstance of DiagnosticBuilder
/// which emits the diagnostics (through @c ProcessDiag) when it is destroyed.
@@ -337,24 +372,25 @@ public:
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
-
+
private:
/// getDiagnosticMappingInfo - Return the mapping info currently set for the
/// specified builtin diagnostic. This returns the high bit encoding, or zero
/// if the field is completely uninitialized.
unsigned getDiagnosticMappingInfo(diag::kind Diag) const {
- return (diag::Mapping)((DiagMappings[Diag/2] >> (Diag & 1)*4) & 15);
+ const DiagMappings &currentMappings = DiagMappingsStack.back();
+ return (diag::Mapping)((currentMappings[Diag/2] >> (Diag & 1)*4) & 15);
}
-
+
void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map,
bool isUser) const {
if (isUser) Map |= 8; // Set the high bit for user mappings.
- unsigned char &Slot = DiagMappings[DiagId/2];
+ unsigned char &Slot = DiagMappingsStack.back()[DiagId/2];
unsigned Shift = (DiagId & 1)*4;
Slot &= ~(15 << Shift);
Slot |= Map << Shift;
}
-
+
/// getDiagnosticLevel - This is an internal implementation helper used when
/// DiagClass is already known.
Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass) const;
@@ -371,7 +407,7 @@ private:
/// CurDiagLoc - This is the location of the current diagnostic that is in
/// flight.
FullSourceLoc CurDiagLoc;
-
+
/// CurDiagID - This is the ID of the current diagnostic that is in flight.
/// This is set to ~0U when there is no diagnostic in flight.
unsigned CurDiagID;
@@ -382,7 +418,7 @@ private:
/// than that almost certainly has to be simplified anyway.
MaxArguments = 10
};
-
+
/// NumDiagArgs - This contains the number of entries in Arguments.
signed char NumDiagArgs;
/// NumRanges - This is the number of ranges in the DiagRanges array.
@@ -395,7 +431,7 @@ private:
/// values, with one for each argument. This specifies whether the argument
/// is in DiagArgumentsStr or in DiagArguments.
unsigned char DiagArgumentsKind[MaxArguments];
-
+
/// DiagArgumentsStr - This holds the values of each string argument for the
/// current diagnostic. This value is only used when the corresponding
/// ArgumentKind is ak_std_string.
@@ -406,11 +442,11 @@ private:
/// mangled into an intptr_t and the intepretation depends on exactly what
/// sort of argument kind it is.
intptr_t DiagArgumentsVal[MaxArguments];
-
+
/// DiagRanges - The list of ranges added to this diagnostic. It currently
/// only support 10 ranges, could easily be extended if needed.
const SourceRange *DiagRanges[10];
-
+
enum { MaxCodeModificationHints = 3 };
/// CodeModificationHints - If valid, provides a hint with some code
@@ -443,14 +479,14 @@ private:
class DiagnosticBuilder {
mutable Diagnostic *DiagObj;
mutable unsigned NumArgs, NumRanges, NumCodeModificationHints;
-
+
void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
friend class Diagnostic;
explicit DiagnosticBuilder(Diagnostic *diagObj)
- : DiagObj(diagObj), NumArgs(0), NumRanges(0),
+ : DiagObj(diagObj), NumArgs(0), NumRanges(0),
NumCodeModificationHints(0) {}
-public:
+public:
/// Copy constructor. When copied, this "takes" the diagnostic info from the
/// input and neuters it.
DiagnosticBuilder(const DiagnosticBuilder &D) {
@@ -467,7 +503,7 @@ public:
/// \brief Create an empty DiagnosticBuilder object that represents
/// no actual diagnostic.
- explicit DiagnosticBuilder(SuppressKind)
+ explicit DiagnosticBuilder(SuppressKind)
: DiagObj(0), NumArgs(0), NumRanges(0), NumCodeModificationHints(0) { }
/// \brief Force the diagnostic builder to emit the diagnostic now.
@@ -504,7 +540,7 @@ public:
/// Destructor - The dtor emits the diagnostic if it hasn't already
/// been emitted.
~DiagnosticBuilder() { Emit(); }
-
+
/// Operator bool: conversion of DiagnosticBuilder to bool always returns
/// true. This allows is to be used in boolean error contexts like:
/// return Diag(...);
@@ -518,7 +554,7 @@ public:
DiagObj->DiagArgumentsStr[NumArgs++] = S;
}
}
-
+
void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
assert(NumArgs < Diagnostic::MaxArguments &&
"Too many arguments to diagnostic!");
@@ -527,14 +563,14 @@ public:
DiagObj->DiagArgumentsVal[NumArgs++] = V;
}
}
-
+
void AddSourceRange(const SourceRange &R) const {
- assert(NumRanges <
+ assert(NumRanges <
sizeof(DiagObj->DiagRanges)/sizeof(DiagObj->DiagRanges[0]) &&
"Too many arguments to diagnostic!");
if (DiagObj)
DiagObj->DiagRanges[NumRanges++] = &R;
- }
+ }
void AddCodeModificationHint(const CodeModificationHint &Hint) const {
assert(NumCodeModificationHints < Diagnostic::MaxCodeModificationHints &&
@@ -579,6 +615,20 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
Diagnostic::ak_identifierinfo);
return DB;
}
+
+// Adds a DeclContext to the diagnostic. The enable_if template magic is here
+// so that we only match those arguments that are (statically) DeclContexts;
+// other arguments that derive from DeclContext (e.g., RecordDecls) will not
+// match.
+template<typename T>
+inline
+typename llvm::enable_if<llvm::is_same<T, DeclContext>,
+ const DiagnosticBuilder &>::type
+operator<<(const DiagnosticBuilder &DB, T *DC) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC),
+ Diagnostic::ak_declcontext);
+ return DB;
+}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const SourceRange &R) {
@@ -605,7 +655,7 @@ inline DiagnosticBuilder Diagnostic::Report(FullSourceLoc Loc, unsigned DiagID){
//===----------------------------------------------------------------------===//
// DiagnosticInfo
//===----------------------------------------------------------------------===//
-
+
/// DiagnosticInfo - This is a little helper class (which is basically a smart
/// pointer that forward info from Diagnostic) that allows clients to enquire
/// about the currently in-flight diagnostic.
@@ -613,74 +663,74 @@ class DiagnosticInfo {
const Diagnostic *DiagObj;
public:
explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {}
-
+
const Diagnostic *getDiags() const { return DiagObj; }
unsigned getID() const { return DiagObj->CurDiagID; }
const FullSourceLoc &getLocation() const { return DiagObj->CurDiagLoc; }
-
+
unsigned getNumArgs() const { return DiagObj->NumDiagArgs; }
-
+
/// getArgKind - Return the kind of the specified index. Based on the kind
/// of argument, the accessors below can be used to get the value.
Diagnostic::ArgumentKind getArgKind(unsigned Idx) const {
assert(Idx < getNumArgs() && "Argument index out of range!");
return (Diagnostic::ArgumentKind)DiagObj->DiagArgumentsKind[Idx];
}
-
+
/// getArgStdStr - Return the provided argument string specified by Idx.
const std::string &getArgStdStr(unsigned Idx) const {
assert(getArgKind(Idx) == Diagnostic::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagArgumentsStr[Idx];
}
-
+
/// getArgCStr - Return the specified C string argument.
const char *getArgCStr(unsigned Idx) const {
assert(getArgKind(Idx) == Diagnostic::ak_c_string &&
"invalid argument accessor!");
return reinterpret_cast<const char*>(DiagObj->DiagArgumentsVal[Idx]);
}
-
+
/// getArgSInt - Return the specified signed integer argument.
int getArgSInt(unsigned Idx) const {
assert(getArgKind(Idx) == Diagnostic::ak_sint &&
"invalid argument accessor!");
return (int)DiagObj->DiagArgumentsVal[Idx];
}
-
+
/// getArgUInt - Return the specified unsigned integer argument.
unsigned getArgUInt(unsigned Idx) const {
assert(getArgKind(Idx) == Diagnostic::ak_uint &&
"invalid argument accessor!");
return (unsigned)DiagObj->DiagArgumentsVal[Idx];
}
-
+
/// getArgIdentifier - Return the specified IdentifierInfo argument.
const IdentifierInfo *getArgIdentifier(unsigned Idx) const {
assert(getArgKind(Idx) == Diagnostic::ak_identifierinfo &&
"invalid argument accessor!");
return reinterpret_cast<IdentifierInfo*>(DiagObj->DiagArgumentsVal[Idx]);
}
-
+
/// getRawArg - Return the specified non-string argument in an opaque form.
intptr_t getRawArg(unsigned Idx) const {
assert(getArgKind(Idx) != Diagnostic::ak_std_string &&
"invalid argument accessor!");
return DiagObj->DiagArgumentsVal[Idx];
}
-
-
+
+
/// getNumRanges - Return the number of source ranges associated with this
/// diagnostic.
unsigned getNumRanges() const {
return DiagObj->NumDiagRanges;
}
-
+
const SourceRange &getRange(unsigned Idx) const {
assert(Idx < DiagObj->NumDiagRanges && "Invalid diagnostic range index!");
return *DiagObj->DiagRanges[Idx];
}
-
+
unsigned getNumCodeModificationHints() const {
return DiagObj->NumCodeModificationHints;
}
@@ -690,7 +740,7 @@ public:
}
const CodeModificationHint *getCodeModificationHints() const {
- return DiagObj->NumCodeModificationHints?
+ return DiagObj->NumCodeModificationHints?
&DiagObj->CodeModificationHints[0] : 0;
}
@@ -699,20 +749,20 @@ public:
/// array.
void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const;
};
-
+
/// DiagnosticClient - This is an abstract interface implemented by clients of
/// the front-end, which formats and prints fully processed diagnostics.
class DiagnosticClient {
public:
virtual ~DiagnosticClient();
-
+
/// setLangOptions - This is set by clients of diagnostics when they know the
/// language parameters of the diagnostics that may be sent through. Note
/// that this can change over time if a DiagClient has multiple languages sent
/// through it. It may also be set to null (e.g. when processing command line
/// options).
virtual void setLangOptions(const LangOptions *LO) {}
-
+
/// IncludeInDiagnosticCounts - This method (whose default implementation
/// returns true) indicates whether the diagnostics handled by this
/// DiagnosticClient should be included in the number of diagnostics
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index e059d5e60520..cbf9cdbc1599 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -41,7 +41,8 @@ def err_expected_namespace_name : Error<"expected namespace name">;
// Sema && Lex
def ext_longlong : Extension<
- "'long long' is an extension when C99 mode is not enabled">;
+ "'long long' is an extension when C99 mode is not enabled">,
+ InGroup<LongLong>;
def warn_integer_too_large : Warning<
"integer constant is too large for its type">;
def warn_integer_too_large_for_signed : Warning<
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index a8dbd68df10f..dfdf0ff2e733 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -14,6 +14,8 @@ def err_drv_unsupported_opt : Error<"unsupported option '%0'">;
def err_drv_unknown_stdin_type : Error<
"-E or -x required when input is from standard input">;
def err_drv_unknown_language : Error<"language not recognized: '%0'">;
+def err_drv_invalid_arch_name : Error<
+ "invalid arch name '%0'">;
def err_drv_invalid_opt_with_multiple_archs : Error<
"option '%0' cannot be used with multiple -arch options">;
def err_drv_invalid_output_with_multiple_archs : Error<
@@ -43,15 +45,21 @@ def err_drv_invalid_version_number : Error<
"invalid version number in '%0'">;
def err_drv_no_linker_llvm_support : Error<
"'%0': unable to pass LLVM bit-code files to linker">;
+def err_drv_no_ast_support : Error<
+ "'%0': unable to use AST files with this tool">;
def err_drv_clang_unsupported : Error<
"the clang compiler does not support '%0'">;
def err_drv_command_failed : Error<
"%0 command failed with exit code %1 (use -v to see invocation)">;
def err_drv_command_signalled : Error<
"%0 command failed due to signal %1 (use -v to see invocation)">;
+def err_drv_invalid_mfloat_abi : Error<
+ "invalid float ABI '%0'">;
def warn_drv_input_file_unused : Warning<
"%0: '%1' input unused when '%2' is present">;
+def warn_drv_preprocessed_input_file_unused : Warning<
+ "%0: previously preprocessed input unused when '%1' is present">;
def warn_drv_unused_argument : Warning<
"argument unused during compilation: '%0'">;
def warn_drv_pipe_ignored_with_save_temps : Warning<
@@ -64,5 +72,7 @@ def warn_drv_not_using_clang_arch : Warning<
"not using the clang compiler for the '%0' architecture">;
def warn_drv_clang_unsupported : Warning<
"the clang compiler does not support '%0'">;
+def warn_drv_assuming_mfloat_abi_is : Warning<
+ "unknown platform, assuming -mfloat-abi=%0">;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 815ae8d70003..e5c73270fdfc 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -11,8 +11,14 @@ let Component = "Frontend" in {
def err_fe_unknown_triple : Error<
"unknown target triple '%0', please use -triple or -arch">;
+def err_fe_unknown_target_abi : Error<"unknown target ABI '%0'">;
def err_fe_error_reading : Error<"error reading '%0'">;
def err_fe_error_reading_stdin : Error<"error reading stdin">;
+def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
+def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
+def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal;
+def err_fe_invalid_code_complete_file
+ : Error<"cannot locate code-completion file %0">, DefaultFatal;
def note_fixit_applied : Note<"FIX-IT applied suggested code changes">;
def note_fixit_in_macro : Note<
@@ -24,6 +30,9 @@ def warn_fixit_no_changes : Note<
"FIX-IT detected errors it could not fix; no output will be generated">;
// PCH reader
+def err_relocatable_without_without_isysroot : Error<
+ "must specify system root with -isysroot when building a relocatable "
+ "PCH file">;
def warn_pch_target_triple : Error<
"PCH file was compiled for the target '%0' but the current translation "
"unit is being compiled for target '%1'">;
@@ -66,6 +75,9 @@ def warn_pch_altivec : Error<
def warn_pch_opencl : Error<
"OpenCL language extensions were %select{disabled|enabled}0 in PCH file "
"but are currently %select{disabled|enabled}1">;
+def warn_pch_elide_constructors : Error<
+ "Elidable copy constructors were %select{disabled|enabled}0 in PCH file "
+ "but are currently %select{disabled|enabled}1">;
def warn_pch_exceptions : Error<
"exceptions were %select{disabled|enabled}0 in PCH file but "
"are currently %select{disabled|enabled}1">;
@@ -80,8 +92,14 @@ def warn_pch_builtins : Error<
"PCH file was compiled with builtins %select{enabled|disabled}0 but "
"builtins are currently %select{enabled|disabled}1">;
def warn_pch_thread_safe_statics : Error<
- "PCH file was compiled %select{without|with}0 thread-safe statics but"
+ "PCH file was compiled %select{without|with}0 thread-safe statics but "
"thread-safe statics are currently %select{disabled|enabled}1">;
+def warn_pch_posix_threads : Error<
+ "PCH file was compiled %select{without|with}0 POSIX thread support but "
+ "POSIX threads are currently %select{disabled|enabled}1">;
+def warn_pch_stack_protector : Error<
+ "stack protector was %select{off|on|required}0 in PCH file but "
+ "is currently %select{off|on|required}1">;
def warn_pch_blocks : Error<
"blocks were %select{disabled|enabled}0 in PCH file but "
"are currently %select{disabled|enabled}1">;
@@ -118,6 +136,8 @@ def warn_pch_version_too_old : Error<
"PCH file uses an older PCH format that is no longer supported">;
def warn_pch_version_too_new : Error<
"PCH file uses a newer PCH format that cannot be read">;
+def warn_pch_different_branch : Error<
+ "PCH file built from a different branch (%0) than the compiler (%1)">;
def warn_cmdline_conflicting_macro_def : Error<
"definition of the macro '%0' conflicts with the definition used to "
"build the precompiled header">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 2896f7988c01..c34bdc111c90 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -19,12 +19,13 @@ def Implicit : DiagGroup<"implicit", [
// Empty DiagGroups: these are recognized by clang but ignored.
+def : DiagGroup<"address">;
def : DiagGroup<"aggregate-return">;
+def : DiagGroup<"attributes">;
def : DiagGroup<"bad-function-cast">;
def : DiagGroup<"cast-align">;
def : DiagGroup<"cast-qual">;
def : DiagGroup<"char-align">;
-def : DiagGroup<"char-subscripts">;
def Comment : DiagGroup<"comment">;
def : DiagGroup<"conversion">;
def : DiagGroup<"declaration-after-statement">;
@@ -38,6 +39,7 @@ def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
def FourByteMultiChar : DiagGroup<"four-char-constants">;
+def : DiagGroup<"import">;
def : DiagGroup<"init-self">;
def : DiagGroup<"inline">;
def : DiagGroup<"int-to-pointer-cast">;
@@ -49,15 +51,17 @@ def : DiagGroup<"missing-noreturn">;
def MultiChar : DiagGroup<"multichar">;
def : DiagGroup<"nested-externs">;
def : DiagGroup<"newline-eof">;
-def : DiagGroup<"long-long">;
+def LongLong : DiagGroup<"long-long">;
def MismatchedTags : DiagGroup<"mismatched-tags">;
def : DiagGroup<"missing-field-initializers">;
def NonNull : DiagGroup<"nonnull">;
def : DiagGroup<"nonportable-cfstrings">;
def : DiagGroup<"old-style-definition">;
+def : DiagGroup<"overflow">;
+def : DiagGroup<"overloaded-virtual">;
def : DiagGroup<"packed">;
def Parentheses : DiagGroup<"parentheses">;
-def : DiagGroup<"pointer-arith">;
+def PointerArith : DiagGroup<"pointer-arith">;
def : DiagGroup<"pointer-to-int-cast">;
def : DiagGroup<"redundant-decls">;
def ReturnType : DiagGroup<"return-type">;
@@ -66,6 +70,9 @@ def : DiagGroup<"shadow">;
def : DiagGroup<"shorten-64-to-32">;
def : DiagGroup<"sign-compare">;
+// Preprocessor warnings.
+def : DiagGroup<"builtin-macro-redefined">;
+
// Just silence warnings about common forms of -Wstrict-aliasing for now.
def : DiagGroup<"strict-aliasing=0">;
def : DiagGroup<"strict-aliasing=1">;
@@ -94,11 +101,14 @@ def UnusedParameter : DiagGroup<"unused-parameter">;
def UnusedValue : DiagGroup<"unused-value">;
def UnusedVariable : DiagGroup<"unused-variable">;
def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
+def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
+def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def : DiagGroup<"variadic-macros">;
def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
def : DiagGroup<"write-strings">;
+def CharSubscript : DiagGroup<"char-subscripts">;
// Aggregation warning settings.
@@ -126,6 +136,7 @@ def Most : DiagGroup<"most", [
Implicit,
MismatchedTags,
MultiChar,
+ ReturnType,
Switch,
Trigraphs,
Uninitialized,
@@ -134,8 +145,8 @@ def Most : DiagGroup<"most", [
UnusedVariable,
VectorConversions,
VolatileRegisterVar,
- ReadOnlySetterAttrs,
- UndeclaredSelector
+ Reorder,
+ CharSubscript
]>;
// -Wall is -Wmost -Wparentheses
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 6ca50db50a8a..3f132c0dabfa 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -112,7 +112,8 @@ def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
def pp_out_of_date_dependency : Warning<
"current file is older than dependency %0">;
def pp_undef_builtin_macro : Warning<"undefining builtin macro">;
-def pp_redef_builtin_macro : Warning<"redefining builtin macro">;
+def pp_redef_builtin_macro : Warning<"redefining builtin macro">,
+ InGroup<DiagGroup<"builtin-macro-redefined">>;
def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore,
InGroup<DiagGroup<"unused-macros">>;
def warn_pp_undef_identifier : Warning<
@@ -226,10 +227,17 @@ def ext_stdc_pragma_syntax_eom :
def warn_stdc_fenv_access_not_supported :
Warning<"pragma STDC FENV_ACCESS ON is not supported, ignoring pragma">,
InGroup<UnknownPragmas>;
-def warn_pragma_diagnostic_invalid :
+def warn_pragma_diagnostic_gcc_invalid :
ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', or"
" 'fatal'">,
InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_clang_invalid :
+ ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal'"
+ " 'push', or 'pop'">,
+ InGroup<UnknownPragmas>;
+def warn_pragma_diagnostic_clang_cannot_ppp :
+ ExtWarn<"pragma diagnostic pop could not pop, no matching push">,
+ InGroup<UnknownPragmas>;
def warn_pragma_diagnostic_invalid_option :
ExtWarn<"pragma diagnostic expected option name (e.g. \"-Wundef\")">,
InGroup<UnknownPragmas>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index d65a97eb7067..6971df50cb55 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -35,6 +35,7 @@ def err_invalid_short_spec : Error<"'short %0' is invalid">;
def err_invalid_long_spec : Error<"'long %0' is invalid">;
def err_invalid_longlong_spec : Error<"'long long %0' is invalid">;
def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">;
+def err_friend_storage_spec : Error<"'%0' is invalid in friend declarations">;
def ext_ident_list_in_param : Extension<
"type-less parameter names in function declaration">;
@@ -77,7 +78,7 @@ def err_expected_rparen : Error<"expected ')'">;
def err_expected_rsquare : Error<"expected ']'">;
def err_expected_rbrace : Error<"expected '}'">;
def err_expected_greater : Error<"expected '>'">;
-def err_expected_semi_declation : Error<
+def err_expected_semi_declaration : Error<
"expected ';' at end of declaration">;
def err_expected_semi_decl_list : Error<
"expected ';' at end of declaration list">;
@@ -135,9 +136,13 @@ def err_rvalue_reference : Error<
def err_argument_required_after_attribute : Error<
"argument required after attribute">;
def err_missing_param : Error<"expected parameter declarator">;
+def err_missing_comma_before_ellipsis : Error<
+ "C requires a comma prior to the ellipsis in a variadic function type">;
def err_unexpected_typedef_ident : Error<
"unexpected type name %0: expected identifier">;
def err_expected_class_name : Error<"expected class name">;
+def err_destructor_class_name : Error<
+ "expected the class name after '~' to name a destructor">;
def err_unspecified_vla_size_with_static : Error<
"'static' may not be used with an unspecified variable length array size">;
@@ -150,14 +155,16 @@ def err_typename_invalid_functionspec : Error<
"type name does not allow function specifier to be specified">;
def err_invalid_decl_spec_combination : Error<
"cannot combine with previous '%0' declaration specifier">;
+def err_friend_invalid_in_context : Error<
+ "'friend' used outside of class">;
def err_unknown_typename : Error<
"unknown type name %0">;
def err_use_of_tag_name_without_tag : Error<
"use of tagged type %0 without '%1' tag">;
def err_expected_ident_in_using : Error<
"expected an identifier in using directive">;
-def err_unexpected_template_spec_in_using : Error<
- "use of template specialization in using directive not allowed">;
+def err_using_decl_can_not_refer_to_template_spec : Error<
+ "using declaration can not refer to template specialization">;
/// Objective-C parser diagnostics
@@ -272,6 +279,10 @@ def err_expected_type_name_after_typename : Error<
def err_variadic_templates : Error<
"variadic templates are only allowed in C++0x">;
+
+// C++ declarations
+def err_friend_decl_defines_class : Error<
+ "cannot define a type in a friend declaration">;
// Language specific pragmas
// - Generic warnings
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b1a73d05a45f..b03676d877e2 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -67,6 +67,9 @@ def ext_flexible_array_init : Extension<
// Declarations.
def ext_vla : Extension<
"variable length arrays are a C99 feature, accepted as an extension">;
+def err_vla_cxx : Error<
+ "variable length arrays are not permitted in C++">;
+
def ext_anon_param_requires_type_specifier : Extension<
"type specifier required for unnamed parameter, defaults to int">;
def err_bad_variable_name : Error<
@@ -74,9 +77,11 @@ def err_bad_variable_name : Error<
def err_parameter_name_omitted : Error<"parameter name omitted">;
def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
+def warn_unused_variable : Warning<"unused variable %0">,
+ InGroup<UnusedVariable>, DefaultIgnore;
def warn_decl_in_param_list : Warning<
"declaration of %0 will not be visible outside of this function">;
-
+
def warn_implicit_function_decl : Warning<
"implicit declaration of function %0">,
InGroup<ImplicitFunctionDeclare>, DefaultIgnore;
@@ -92,10 +97,18 @@ def warn_use_out_of_scope_declaration : Warning<
"use of out-of-scope declaration of %0">;
def err_inline_non_function : Error<
"'inline' can only appear on functions">;
+
+// C++ using declarations
def err_using_requires_qualname : Error<
"using declaration requires a qualified name">;
def err_using_typename_non_type : Error<
"'typename' keyword used on a non-type">;
+def err_using_decl_nested_name_specifier_is_not_a_base_class : Error<
+ "using declaration refers into '%0', which is not a base class of %1">;
+def err_using_decl_can_not_refer_to_class_member : Error<
+ "using declaration can not refer to class member">;
+ def err_using_decl_can_not_refer_to_namespace : Error<
+ "using declaration can not refer to namespace">;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
@@ -104,6 +117,23 @@ def err_thread_non_global : Error<
def err_thread_unsupported : Error<
"thread-local storage is unsupported for the current target">;
+def warn_maybe_falloff_nonvoid_function : Warning<
+ "control may reach end of non-void function">,
+ InGroup<ReturnType>;
+def warn_falloff_nonvoid_function : Warning<
+ "control reaches end of non-void function">,
+ InGroup<ReturnType>;
+def err_maybe_falloff_nonvoid_block : Error<
+ "control may reach end of non-void block">;
+def err_falloff_nonvoid_block : Error<
+ "control reaches end of non-void block">;
+def warn_suggest_noreturn_function : Warning<
+ "function could be attribute 'noreturn'">,
+ InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+def warn_suggest_noreturn_block : Warning<
+ "block could be attribute 'noreturn'">,
+ InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore;
+
/// Built-in functions.
def ext_implicit_lib_function_decl : ExtWarn<
"implicitly declaring C library function '%0' with type %1">;
@@ -113,11 +143,27 @@ def note_please_include_header : Note<
def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">;
def err_implicit_decl_requires_stdio : Error<
"implicit declaration of '%0' requires inclusion of the header <stdio.h>">;
+def err_implicit_decl_requires_setjmp : Error<
+ "implicit declaration of '%0' requires inclusion of the header <setjmp.h>">;
def warn_redecl_library_builtin : Warning<
"incompatible redeclaration of library function %0">;
def err_builtin_definition : Error<"definition of builtin function %0">;
def err_types_compatible_p_in_cplusplus : Error<
"__builtin_types_compatible_p is not valid in C++">;
+def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError;
+
+/// main()
+// static/inline main() are not errors in C, just in C++.
+def warn_unusual_main_decl : Warning<"'main' should not be declared "
+ "%select{static|inline|static or inline}0">;
+def err_unusual_main_decl : Error<"'main' is not allowed to be declared "
+ "%select{static|inline|static or inline}0">;
+def err_main_returns_nonint : Error<"'main' must return 'int'">;
+def err_main_surplus_args : Error<"%0 is too many arguments for 'main': "
+ "must be 0, 2, or 3">;
+def warn_main_one_arg : Warning<"one-argument 'main' is usually a mistake">;
+def err_main_arg_wrong : Error<"%select{first|second|third}0 argument of "
+ "'main' should be of type %1">;
/// parser diagnostics
def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
@@ -135,6 +181,8 @@ def warn_pragma_pack_pop_identifer_and_alignment : Warning<
"specifying both a name and alignment to 'pop' is undefined">;
def warn_pragma_pack_pop_failed : Warning<"#pragma pack(pop, ...) failed: %0">;
+def warn_pragma_unused_undeclared_var : Warning<
+ "undeclared variable %0 used as an argument for '#pragma unused'">;
def warn_pragma_unused_expected_localvar : Warning<
"only local variables can be arguments to '#pragma unused'">;
def err_unsupported_pragma_weak : Error<
@@ -145,6 +193,8 @@ def err_duplicate_class_def : Error<
"duplicate interface definition for class %0">;
def err_undef_superclass : Error<
"cannot find interface declaration for %0, superclass of %1">;
+def err_recursive_superclass : Error<
+ "trying to recursively use %0 as superclass of %1">;
def warn_previous_alias_decl : Warning<"previously declared alias is ignored">;
def err_conflicting_aliasing_type : Error<"conflicting types for alias %0">;
def warn_undef_interface : Warning<"cannot find interface declaration for %0">;
@@ -166,10 +216,12 @@ def warn_dup_category_def : Warning<
"duplicate definition of category %1 on interface %0">;
def err_conflicting_super_class : Error<"conflicting super class name %0">;
def err_dup_implementation_class : Error<"reimplementation of class %0">;
+def err_dup_implementation_category : Error<
+ "reimplementation of category %1 for class %0">;
def err_conflicting_ivar_type : Error<
"instance variable %0 has conflicting type: %1 vs %2">;
def err_conflicting_ivar_bitwidth : Error<
- "instance variable %0 has conflicting bitfield width">;
+ "instance variable %0 has conflicting bit-field width">;
def err_conflicting_ivar_name : Error<
"conflicting instance variable names: %0 vs %1">;
def err_inconsistant_ivar_count : Error<
@@ -183,6 +235,10 @@ def warn_conflicting_ret_types : Warning<
def warn_conflicting_param_types : Warning<
"conflicting parameter types in implementation of %0: %1 vs %2">;
+def warn_implements_nscopying : Warning<
+"default assign attribute on property %0 which implements "
+"NSCopying protocol is not appropriate with -fobjc-gc[-only]">;
+
def warn_multiple_method_decl : Warning<"multiple methods named %0 found">;
def warn_accessor_property_type_mismatch : Warning<
"type of property %0 does not match type of accessor %1">;
@@ -255,11 +311,26 @@ def err_static_assert_expression_is_not_constant : Error<
"static_assert expression is not an integral constant expression">;
def err_static_assert_failed : Error<"static_assert failed \"%0\"">;
-def err_friend_decl_outside_class : Error<
- "'friend' used outside of class">;
+def err_unexpected_friend : Error<
+ "friends can only be classes or functions">;
+def err_enum_friend : Error<
+ "enum types cannot be friends">;
+def err_friend_is_member : Error<
+ "friends cannot be members of the declaring class">;
+def ext_friend_inner_class : Extension<
+ "C++ 98 does not allow inner classes as friends">;
+def err_unelaborated_friend_type : Error<
+ "must specify '%select{struct|union|class|enum}0' to befriend %1">;
+def err_qualified_friend_not_found : Error<
+ "no function named %0 with type %1 was found in the specified scope">;
+def err_introducing_special_friend : Error<
+ "must use a qualified name when declaring a %select{constructor|"
+ "destructor|conversion operator}0 as a friend">;
+def err_tagless_friend_type_template : Error<
+ "friend type templates must use an elaborated type">;
def err_abstract_type_in_decl : Error<
- "%select{return|parameter|variable|field}1 type %0 is an abstract class">;
+ "%select{return|parameter|variable|field}0 type %1 is an abstract class">;
def err_allocation_of_abstract_type : Error<
"allocation of an object of abstract type %0">;
@@ -285,10 +356,17 @@ def err_distant_exception_spec : Error<
"exception specifications are not allowed beyond a single level "
"of indirection">;
def err_incomplete_in_exception_spec : Error<
- "%select{|pointer to |reference to }1incomplete type %0 is not allowed "
+ "%select{|pointer to |reference to }0incomplete type %1 is not allowed "
"in exception specification">;
def err_mismatched_exception_spec : Error<
"exception specification in declaration does not match previous declaration">;
+def err_override_exception_spec : Error<
+ "exception specification of overriding function is more lax than "
+ "base version">;
+def err_incompatible_exception_specs : Error<
+ "target exception specification is not superset of source">;
+def err_deep_exception_specs_differ : Error<
+ "exception specifications of %select{return|argument}0 types differ">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@@ -299,6 +377,12 @@ def note_previous_access_declaration : Note<
// C++ name lookup
def err_incomplete_nested_name_spec : Error<
"incomplete type %0 named in nested name specifier">;
+def err_nested_name_member_ref_lookup_ambiguous : Error<
+ "lookup of %0 in member access expression is ambiguous">;
+def note_ambig_member_ref_object_type : Note<
+ "lookup in the object type %0 refers here">;
+def note_ambig_member_ref_scope : Note<
+ "lookup from the current scope refers here">;
// C++ class members
def err_storageclass_invalid_for_member : Error<
@@ -332,6 +416,21 @@ def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
+def err_missing_default_constructor : Error<
+ "default constructor for %1 is missing in initialization of "
+ "%select{base class|member}0">;
+def err_illegal_union_member : Error<
+ "union member %0 has a non-trivial %select{constructor|"
+ "copy constructor|copy assignment operator|destructor}1">;
+def note_nontrivial_has_virtual : Note<
+ "because type %0 has a virtual %select{member function|base class}1">;
+def note_nontrivial_has_nontrivial : Note<
+ "because type %0 has a %select{member|base class}1 with a non-trivial "
+ "%select{constructor|copy constructor|copy assignment operator|destructor}2">;
+def note_nontrivial_user_defined : Note<
+ "because type %0 has a user-declared %select{constructor|copy constructor|"
+ "copy assignment operator|destructor}1">;
+
def err_different_return_type_for_overriding_virtual_function : Error<
"virtual function %0 has a different return type (%1) than the "
"function it overrides (which has return type %2)">;
@@ -378,9 +477,15 @@ def err_destructor_with_params : Error<"destructor cannot have any parameters">;
def err_destructor_variadic : Error<"destructor cannot be variadic">;
def err_destructor_typedef_name : Error<
"destructor cannot be declared using a typedef %0 of the class name">;
+def err_destructor_name : Error<
+ "expected the class name after '~' to name the enclosing class">;
// C++ initialization
def err_lvalue_to_rvalue_ref : Error<"rvalue reference cannot bind to lvalue">;
+def err_invalid_initialization : Error<
+"invalid initialization of reference of type %0 from expression of type %1">;
+def err_lvalue_to_rvalue_ambig_ref : Error<"rvalue reference cannot bind to lvalue "
+ "due to multiple conversion functions">;
// FIXME: passing in an English string as %1!
def err_not_reference_to_const_init : Error<
"non-const lvalue reference to type %0 cannot be initialized "
@@ -412,6 +517,8 @@ def err_illegal_decl_array_of_auto : Error<
def err_auto_not_allowed : Error<
"'auto' not allowed in %select{function prototype|struct member|union member"
"|class member|exception declaration|template parameter|block literal}0">;
+def err_auto_var_requires_init : Error<
+ "declaration of variable %0 with type %1 requires an initializer">;
// Objective-C++
def err_objc_decls_may_only_appear_in_global_scope : Error<
@@ -464,23 +571,37 @@ def err_ext_vector_component_name_illegal : Error<
"illegal vector component name '%0'">;
def err_attribute_address_space_not_int : Error<
"address space attribute requires an integer constant">;
+def err_attribute_address_space_negative : Error<
+ "address space is negative">;
+def err_attribute_address_space_too_high : Error<
+ "address space is larger than the maximum supported (%0)">;
def err_attribute_address_multiple_qualifiers : Error<
"multiple address spaces specified for type">;
def err_implicit_pointer_address_space_cast : Error<
"illegal implicit cast between two pointers with different address spaces">;
def err_as_qualified_auto_decl : Error<
"automatic variable qualified with an address space">;
-def err_attribute_annotate_no_string : Error<
- "argument to annotate attribute was not a string literal">;
+def err_arg_with_address_space : Error<
+ "parameter may not be qualified with an address space">;
+def err_attribute_not_string : Error<
+ "argument to %0 attribute was not a string literal">;
+def err_attribute_section_invalid_for_target : Error<
+ "argument to 'section' attribute is not valid for this target: %0">;
def err_attribute_aligned_not_power_of_two : Error<
"requested alignment is not a power of 2">;
def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
"'%0' redeclared without %1 attribute: previous %1 ignored">;
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
+def warn_attribute_precede_definition : Warning<
+ "attribute declaration must precede definition">;
def warn_attribute_weak_on_field : Warning<
"__weak attribute cannot be specified on a field declaration">;
def warn_attribute_weak_on_local : Warning<
"__weak attribute cannot be specified on an automatic variable">;
+def warn_weak_identifier_undeclared : Warning<
+ "weak identifier %0 never declared">;
+def err_attribute_weak_static : Error<
+ "weak declaration of '%0' must be public">;
def warn_attribute_weak_import_invalid_on_definition : Warning<
"'weak_import' attribute cannot be specified on a definition">;
def warn_attribute_wrong_decl_type : Warning<
@@ -521,6 +642,8 @@ def err_attr_wrong_decl : Error<
"'%0' attribute invalid on this declaration, requires typedef or value">;
def warn_attribute_nonnull_no_pointers : Warning<
"'nonnull' attribute applied to function with no pointer arguments">;
+def warn_attribute_malloc_pointer_only : Warning<
+ "'malloc' attribute only applies to functions returning a pointer type">;
def warn_transparent_union_nonpointer : Warning<
"'transparent_union' attribute support incomplete; only supported for "
"pointer unions">;
@@ -594,8 +717,16 @@ def err_param_default_argument_references_this : Error<
def err_param_default_argument_nonfunc : Error<
"default arguments can only be specified for parameters in a function "
"declaration">;
+def err_param_default_argument_template_redecl : Error<
+ "default arguments cannot be added to a function template that has already "
+ "been declared">;
+def err_param_default_argument_member_template_redecl : Error<
+ "default arguments cannot be added to an out-of-line definition of a member "
+ "of a %select{class template|class template partial specialization|nested "
+ "class in a template}0">;
+def note_field_decl : Note<"member is declared here">;
def err_defining_default_ctor : Error<
- "cannot define the implicit default constructor for %0, because %select{base class|member}1 "
+ "cannot define the implicit default constructor for %0, because %select{base class|member's type}1 "
"%2 does not have any default constructor">;
def note_previous_class_decl : Note<
"%0 declared here">;
@@ -608,6 +739,12 @@ def note_first_required_here : Note<
def err_unintialized_member : Error<
"cannot define the implicit default constructor for %0, because "
"%select{reference|const}1 member %2 cannot be default-initialized">;
+def err_null_intialized_reference_member : Error<
+ "cannot initialize the member to null in default constructor because "
+ "reference member %0 cannot be null-initialized">;
+def err_unintialized_member_in_ctor : Error<
+ "constructor for %0 must explicitly initialize the "
+ "%select{reference|const}1 member %2 ">;
def err_use_of_default_argument_to_function_declared_later : Error<
"use of default argument to function %0 that is declared later in class %1">;
@@ -639,12 +776,23 @@ def err_ovl_ambiguous_member_call : Error<
def err_ovl_deleted_member_call : Error<
"call to %select{unavailable|deleted}0 member function %1">;
def err_ovl_candidate : Note<"candidate function">;
+def err_ovl_candidate_not_viable : Note<"function not viable because"
+ " of ambiguity in conversion of argument %0">;
+def note_ambiguous_type_conversion: Note<
+ "because of ambiguity in conversion of %0 to %1">;
+def err_ovl_template_candidate : Note<
+ "candidate function template specialization %0">;
def err_ovl_candidate_deleted : Note<
"candidate function has been explicitly %select{made unavailable|deleted}0">;
-def err_ovl_builtin_candidate : Note<"built-in candidate function %0">;
+def err_ovl_builtin_binary_candidate : Note<
+ "built-in candidate operator %0 (%1, %2)">;
+def err_ovl_builtin_unary_candidate : Note<
+ "built-in candidate operator %0 (%1)">;
def err_ovl_no_viable_function_in_init : Error<
"no matching constructor for initialization of %0">;
def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
+def err_ref_init_ambiguous : Error<
+ "reference initialization of type %0 with initializer of type %1 is ambiguous">;
def err_ovl_deleted_init : Error<
"call to %select{unavailable|deleted}0 constructor of %1">;
def err_ovl_ambiguous_oper : Error<
@@ -663,6 +811,10 @@ def err_ovl_surrogate_cand : Note<"conversion candidate of type %0">;
def err_member_call_without_object : Error<
"call to non-static member function without an object argument">;
+// C++ Address of Overloaded Function
+def err_addr_ovl_ambiguous : Error<
+ "address of overloaded function %0 is ambiguous">;
+
// C++ Template Declarations
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
@@ -704,6 +856,12 @@ def note_template_param_prev_default_arg : Note<
"previous default template argument defined here">;
def err_template_param_default_arg_missing : Error<
"template parameter missing a default argument">;
+
+def err_template_variable : Error<"variable %0 declared as a template">;
+def err_template_variable_noparams : Error<
+ "extraneous 'template<>' in declaration of variable %0">;
+def err_template_tag_noparams : Error<
+ "extraneous 'template<>' in declaration of %0 %1">;
// C++ Template Argument Lists
def err_template_arg_list_different_arity : Error<
@@ -776,25 +934,64 @@ def err_template_arg_not_pointer_to_member_form : Error<
def err_template_arg_extra_parens : Error<
"non-type template argument cannot be surrounded by parentheses">;
-// C++ class template specialization
-def err_template_spec_needs_header : Error<
- "template specialization requires 'template<>'">;
-def err_template_spec_extra_headers : Error<
- "template specialization must have a single 'template<>' header">;
+// C++ template specialization
+def err_template_spec_unknown_kind : Error<
+ "can only provide an explicit %select{<error>|<error>|specialization|"
+ "instantiation|instantiation}0 for a class template, function template, or "
+ "a member function, static data member, or member class of a class template">;
+def note_specialized_entity : Note<
+ "explicitly %select{<error>|<error>|specialized|instantiated|instantiated}0 "
+ "declaration is here">;
+def err_template_spec_decl_function_scope : Error<
+ "explicit %select{<error>|<error>|specialization|instantiation|"
+ "instantiation}0 of %1 in function scope">;
+def err_template_spec_decl_class_scope : Error<
+ "explicit %select{<error>|<error>|specialization|instantiation|"
+ "instantiation}0 of %1 in class scope">;
def err_template_spec_decl_out_of_scope_global : Error<
- "class template %select{|partial }0specialization of %1 must occur in the "
- "global scope">;
+ "%select{class template|class template partial|function template|member "
+ "function|static data member|member class}0 specialization of %1 must "
+ "originally be declared in the global scope">;
def err_template_spec_decl_out_of_scope : Error<
- "class template %select{|partial }0specialization of %1 not in namespace %2">;
-def err_template_spec_decl_function_scope : Error<
- "%select{class template specialization|class template partial specialization|"
- "explicit instantiation}0 of %1 in function scope">;
+ "%select{class template|class template partial|function template|member "
+ "function|static data member|member class}0 specialization of %1 must "
+ "originally be declared in namespace %2">;
def err_template_spec_redecl_out_of_scope : Error<
- "%select{class template specialization|class template partial specialization|"
- "explicit instantiation}0 of %1 not in a namespace enclosing %2">;
+ "%select{class template|class template partial|function template|member "
+ "function|static data member|member class}0 specialization of %1 not in a "
+ "namespace enclosing %2">;
def err_template_spec_redecl_global_scope : Error<
- "%select{class template specialization|class template partial specialization|"
- "explicit instantiation}0 of %1 must occur at global scope">;
+ "%select{class template|class template partial|function template|member "
+ "function|static data member|member class}0 specialization of %1 must occur "
+ "at global scope">;
+def err_spec_member_not_instantiated : Error<
+ "specialization of member %q0 does not specialize an instantiated member">;
+def note_specialized_decl : Note<"attempt to specialize declaration here">;
+def err_specialization_after_instantiation : Error<
+ "explicit specialization of %0 after instantiation">;
+def note_instantiation_required_here : Note<
+ "%select{implicit|explicit}0 instantiation first required here">;
+def err_template_spec_friend : Error<
+ "template specialization declaration cannot be a friend">;
+def err_template_spec_default_arg : Error<
+ "default argument not permitted on an explicit "
+ "%select{instantiation|specialization}0 of function %1">;
+
+// C++ class template specializations and out-of-line definitions
+def err_template_spec_needs_header : Error<
+ "template specialization requires 'template<>'">;
+def err_template_spec_needs_template_parameters : Error<
+ "template specialization or definition requires a template parameter list"
+ "corresponding to the nested type %0">;
+def err_template_param_list_matches_nontemplate : Error<
+ "template parameter list matching the non-templated nested type %0 should "
+ "be empty ('template<>')">;
+def err_template_spec_extra_headers : Error<
+ "extraneous template parameter list in template specialization or "
+ "out-of-line template definition">;
+def err_template_qualified_declarator_no_match : Error<
+ "nested name specifier '%0' for declaration does not refer into a class, "
+ "class template or class template partial specialization">;
// C++ Class Template Partial Specialization
def err_default_arg_in_partial_spec : Error<
@@ -815,9 +1012,19 @@ def warn_partial_specs_not_deducible : Warning<
"deduced; this partial specialization will never be used">;
def note_partial_spec_unused_parameter : Note<
"non-deducible template parameter %0">;
-def unsup_template_partial_spec_ordering : Error<
- "partial ordering of class template partial specializations is not yet "
- "supported">;
+def err_partial_spec_ordering_ambiguous : Error<
+ "ambiguous partial specializations of %0">;
+def note_partial_spec_match : Note<"partial specialization matches %0">;
+
+// C++ Function template specializations
+def err_function_template_spec_no_match : Error<
+ "no function template matches function template specialization %0">;
+def err_function_template_spec_ambiguous : Error<
+ "function template specialization %0 ambiguously refers to more than one "
+ "function template; explicitly specify%select{|additional }1 template "
+ "arguments to identify a particular function template">;
+def note_function_template_spec_matched : Note<
+ "function template matches specialization %0">;
// C++ Template Instantiation
def err_template_recursion_depth_exceeded : Error<
@@ -838,9 +1045,14 @@ def note_template_member_function_here : Note<
"in instantiation of member function %q0 requested here">;
def note_function_template_spec_here : Note<
"in instantiation of function template specialization %q0 requested here">;
+def note_template_static_data_member_def_here : Note<
+ "in instantiation of static data member %q0 requested here">;
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
+def note_default_function_arg_instantiation_here : Note<
+ "in instantiation of default function argument expression "
+ "for '%0' required here">;
def note_explicit_template_arg_substitution_here : Note<
"while substituting explicitly-specified template arguments into function "
"template %f, here">;
@@ -873,15 +1085,34 @@ def note_nontemplate_decl_here : Note<
"non-templated declaration is here">;
def err_explicit_instantiation_out_of_scope : Error<
"explicit instantiation of %0 not in a namespace enclosing %1">;
-
+def err_explicit_instantiation_requires_name : Error<
+ "explicit instantiation declaration requires a name">;
+def err_explicit_instantiation_of_typedef : Error<
+ "explicit instantiation of typedef %0">;
+def err_explicit_instantiation_not_known : Error<
+ "explicit instantiation of %0 does not refer to a function template, member "
+ "function, member class, or static data member">;
+def note_explicit_instantiation_here : Note<
+ "explicit instantiation refers here">;
+def err_explicit_instantiation_data_member_not_instantiated : Error<
+ "explicit instantiation refers to static data member %q0 that is not an "
+ "instantiation">;
+def err_explicit_instantiation_member_function_not_instantiated : Error<
+ "explicit instantiation refers to member function %q0 that is not an "
+ "instantiation">;
+def err_explicit_instantiation_ambiguous : Error<
+ "partial ordering for explicit instantiation of %0 is ambiguous">;
+def note_explicit_instantiation_candidate : Note<
+ "explicit instantiation candidate function template here %0">;
+
// C++ typename-specifiers
def err_typename_nested_not_found : Error<"no type named %0 in %1">;
-def err_typename_nested_not_found_global : Error<
- "no type named %0 in the global namespace">;
def err_typename_nested_not_type : Error<
- "typename specifier refers to non-type member %0">;
+ "typename specifier refers to non-type member %0 in %1">;
def note_typename_refers_here : Note<
"referenced member %0 is declared here">;
+def err_typename_missing : Error<
+ "missing 'typename' prior to dependent type name '%0%1'">;
def err_template_kw_refers_to_non_template : Error<
"%0 following the 'template' keyword does not refer to a template">;
@@ -1018,11 +1249,11 @@ def err_bitfield_has_negative_width : Error<
"bit-field %0 has negative width (%1)">;
def err_anon_bitfield_has_negative_width : Error<
"anonymous bit-field has negative width (%0)">;
-def err_bitfield_has_zero_width : Error<"bit-field %0 has zero width">;
+def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">;
def err_bitfield_width_exceeds_type_size : Error<
"size of bit-field %0 exceeds size of its type (%1 bits)">;
def err_anon_bitfield_width_exceeds_type_size : Error<
- "size of anonymous bitfield exceeds size of its type (%0 bits)">;
+ "size of anonymous bit-field exceeds size of its type (%0 bits)">;
def err_redefinition_of_label : Error<"redefinition of label '%0'">;
def err_undeclared_label_use : Error<"use of undeclared label '%0'">;
@@ -1053,6 +1284,8 @@ def note_protected_by_cxx_try : Note<
"jump bypasses initialization of try block">;
def note_protected_by_cxx_catch : Note<
"jump bypasses initialization of catch block">;
+def note_protected_by___block : Note<
+ "jump bypasses setup of __block variable">;
def err_func_returning_array_function : Error<
"function cannot return array or function type %0">;
@@ -1105,16 +1338,16 @@ def err_func_def_incomplete_result : Error<
// Expressions.
def ext_sizeof_function_type : Extension<
- "invalid application of 'sizeof' to a function type">;
+ "invalid application of 'sizeof' to a function type">, InGroup<PointerArith>;
def ext_sizeof_void_type : Extension<
- "invalid application of '%0' to a void type">;
+ "invalid application of '%0' to a void type">, InGroup<PointerArith>;
// FIXME: merge with %select
def err_sizeof_incomplete_type : Error<
"invalid application of 'sizeof' to an incomplete type %0">;
def err_alignof_incomplete_type : Error<
"invalid application of '__alignof' to an incomplete type %0">;
def err_sizeof_alignof_bitfield : Error<
- "invalid application of '%select{sizeof|__alignof}0' to bitfield">;
+ "invalid application of '%select{sizeof|__alignof}0' to bit-field">;
def err_offsetof_record_type : Error<
"offsetof requires struct, union, or class type, %0 invalid">;
def err_offsetof_array_type : Error<"offsetof requires array type, %0 invalid">;
@@ -1127,6 +1360,11 @@ def warn_floatingpoint_eq : Warning<
"comparing floating point with == or != is unsafe">,
InGroup<DiagGroup<"float-equal">>, DefaultIgnore;
+def warn_shift_negative : Warning<
+ "shift count is negative">;
+def warn_shift_gt_typewidth : Warning<
+ "shift count >= width of type">;
+
def err_sizeof_nonfragile_interface : Error<
"invalid application of '%select{alignof|sizeof}1' to interface %0 in "
"non-fragile ABI">;
@@ -1163,12 +1401,15 @@ def err_typecheck_member_reference_unknown : Error<
"cannot refer to member %0 with '%select{.|->}1'">;
def note_member_reference_needs_call : Note<
"perhaps you meant to call this function with '()'?">;
+def warn_subscript_is_char : Warning<"array subscript is of type 'char'">,
+ InGroup<CharSubscript>, DefaultIgnore;
def err_typecheck_incomplete_tag : Error<"incomplete definition of type %0">;
-def err_typecheck_no_member : Error<"no member named %0">;
+def err_no_member : Error<"no member named %0 in %1">;
+
def err_member_redeclared : Error<"class member cannot be redeclared">;
def err_member_def_does_not_match : Error<
- "out-of-line definition does not match any declaration in %0">;
+ "out-of-line definition of %0 does not match any declaration in %1">;
def err_nonstatic_member_out_of_line : Error<
"non-static data member defined out-of-line">;
def err_qualified_typedef_declarator : Error<
@@ -1191,6 +1432,8 @@ def err_typecheck_pointer_arith_void_type : Error<
"arithmetic on pointer to void type">;
def err_typecheck_decl_incomplete_type : Error<
"variable has incomplete type %0">;
+def ext_typecheck_decl_incomplete_type : ExtWarn<
+ "tentative definition of variable with internal linkage has incomplete non-array type %0">;
def err_tentative_def_incomplete_type : Error<
"tentative definition has type %0 that is never completed">;
def err_tentative_def_incomplete_type_arr : Error<
@@ -1215,6 +1458,10 @@ def err_typecheck_unary_expr : Error<
"invalid argument type %0 to unary expression">;
def err_typecheck_indirection_requires_pointer : Error<
"indirection requires pointer operand (%0 invalid)">;
+def err_indirection_requires_nonfragile_object : Error<
+ "indirection cannot be to an interface in non-fragile ABI (%0 invalid)">;
+def err_direct_interface_unsupported : Error<
+ "indirection to an interface is not supported (%0 invalid)">;
def err_typecheck_invalid_operands : Error<
"invalid operands to binary expression (%0 and %1)">;
def err_typecheck_sub_ptr_object : Error<
@@ -1223,8 +1470,12 @@ def err_typecheck_sub_ptr_compatible : Error<
"%0 and %1 are not pointers to compatible types">;
def ext_typecheck_ordered_comparison_of_pointer_integer : ExtWarn<
"ordered comparison between pointer and integer (%0 and %1)">;
+def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
+ "ordered comparison between pointer and zero (%0 and %1) is an extension">;
def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
"ordered comparison of function pointers (%0 and %1)">;
+def ext_typecheck_comparison_of_fptr_to_void : Extension<
+ "equality comparison between function pointer and void pointer (%0 and %1)">;
def ext_typecheck_comparison_of_pointer_integer : ExtWarn<
"comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : ExtWarn<
@@ -1271,9 +1522,10 @@ def err_unexpected_interface : Error<
def err_property_not_found : Error<
"property %0 not found on object of type %1">;
def ext_gnu_void_ptr : Extension<
- "use of GNU void* extension">;
+ "use of GNU void* extension">, InGroup<PointerArith>;
def ext_gnu_ptr_func_arith : Extension<
- "arithmetic on pointer to function type %0 is a GNU extension">;
+ "arithmetic on pointer to function type %0 is a GNU extension">,
+ InGroup<PointerArith>;
def error_readonly_property_assignment : Error<
"assigning to property with 'readonly' attribute not allowed">;
def ext_integer_increment_complex : Extension<
@@ -1326,36 +1578,56 @@ def note_property_impl_required : Note<
// C++ casts
-def err_bad_cxx_cast_generic : Error<"%0 from %2 to %1 is not allowed">;
-def err_bad_cxx_cast_rvalue : Error<"%0 from rvalue to reference type %1">;
+// These messages adhere to the TryCast pattern: %0 is an int specifying the
+// cast type, %1 is the source type, %2 is the destination type.
+def err_bad_cxx_cast_generic : Error<
+ "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+ "functional-style cast}0 from %1 to %2 is not allowed">;
+def err_bad_cxx_cast_rvalue : Error<
+ "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+ "functional-style cast}0 from rvalue to reference type %2">;
def err_bad_cxx_cast_const_away : Error<
- "%0 from %2 to %1 casts away constness">;
+ "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|"
+ "functional-style cast}0 from %1 to %2 casts away constness">;
def err_bad_const_cast_dest : Error<
- "const_cast to %0, which is not a reference, pointer-to-object, "
- "or pointer-to-data-member">;
-
-def err_bad_reinterpret_cast_same_type : Error<
- "source and destination type of reinterpret_cast are not distinct">;
-def ext_reinterpret_cast_fn_obj : Extension<
- "reinterpret_cast between pointer-to-function and pointer-to-object is "
- "an extension">;
-
+ "%select{const_cast||||C-style cast|functional-style cast}0 to %2, "
+ "which is not a reference, pointer-to-object, or pointer-to-data-member">;
+def ext_cast_fn_obj : Extension<
+ "cast between pointer-to-function and pointer-to-object is an extension">;
def err_bad_reinterpret_cast_small_int : Error<
- "cast from pointer to smaller type %0 loses information">;
+ "cast from pointer to smaller type %2 loses information">;
+def err_bad_cxx_cast_vector_to_scalar_different_size : Error<
+ "%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
+ "to scalar %2 of different size">;
+def err_bad_cxx_cast_scalar_to_vector_different_size : Error<
+ "%select{||reinterpret_cast||C-style cast|}0 from scalar %1 "
+ "to vector %2 of different size">;
+def err_bad_cxx_cast_vector_to_vector_different_size : Error<
+ "%select{||reinterpret_cast||C-style cast|}0 from vector %1 "
+ "to vector %2 of different size">;
+def err_bad_lvalue_to_rvalue_cast : Error<
+ "cannot cast from lvalue of type %1 to rvalue reference type %2; types are "
+ "not compatible">;
+def err_bad_static_cast_pointer_nonpointer : Error<
+ "cannot cast from type %1 to pointer type %2">;
+def err_bad_static_cast_member_pointer_nonmp : Error<
+ "cannot cast from type %1 to member pointer type %2">;
+def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">;
+
+// These messages don't adhere to the pattern.
+// FIXME: Display the path somehow better.
+def err_ambiguous_base_to_derived_cast : Error<
+ "ambiguous cast from base %0 to derived %1:%2">;
+def err_static_downcast_via_virtual : Error<
+ "cannot cast %0 to %1 via virtual base %2">;
+def err_downcast_from_inaccessible_base : Error<
+ "cannot cast %1 to %0 due to inaccessible conversion path">;
def err_bad_dynamic_cast_not_ref_or_ptr : Error<
"%0 is not a reference or pointer">;
def err_bad_dynamic_cast_not_class : Error<"%0 is not a class">;
def err_bad_dynamic_cast_incomplete : Error<"%0 is an incomplete type">;
def err_bad_dynamic_cast_not_ptr : Error<"%0 is not a pointer">;
def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">;
-// FIXME: Display the path somehow better.
-def err_ambiguous_base_to_derived_cast : Error<
- "ambiguous static_cast from base %0 to derived %1:%2">;
-def err_static_downcast_via_virtual : Error<
- "cannot cast %0 to %1 via virtual base %2">;
-def err_bad_lvalue_to_rvalue_cast : Error<
- "cannot cast from lvalue of type %0 to rvalue reference to %1; types are "
- "not compatible">;
// Other C++ expressions
def err_need_header_before_typeid : Error<
@@ -1375,6 +1647,8 @@ def err_array_size_not_integral : Error<
def err_new_uninitialized_const : Error<
"must provide an initializer if the allocated object is 'const'">;
def err_delete_operand : Error<"cannot delete expression of type %0">;
+def err_ambiguous_delete_operand : Error<"ambiguous conversion of delete "
+ "expression of type %0 to a pointer">;
def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behaviour">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
@@ -1394,6 +1668,9 @@ def err_bad_memptr_rhs : Error<
def err_bad_memptr_lhs : Error<
"left hand operand to %0 must be a %select{|pointer to }1class "
"compatible with the right hand operand, but is %2">;
+def warn_exception_caught_by_earlier_handler : Warning<
+ "exception of type %0 will be caught by earlier handler">;
+def note_previous_exception_handler : Note<"for type %0">;
def err_conditional_void_nonvoid : Error<
"%select{left|right}1 operand to ? is void, but %select{right|left}1 operand "
@@ -1412,6 +1689,22 @@ def err_throw_incomplete_ptr : Error<
def err_return_in_constructor_handler : Error<
"return in the catch of a function try block of a constructor is illegal">;
+def err_ident_in_pseudo_dtor_not_a_type : Error<
+ "identifier %0 in pseudo-destructor expression does not name a type">;
+def err_operator_arrow_circular : Error<
+ "circular pointer delegation detected">;
+def err_pseudo_dtor_base_not_scalar : Error<
+ "object expression of non-scalar type %0 cannot be used in a "
+ "pseudo-destructor expression">;
+def err_pseudo_dtor_type_mismatch : Error<
+ "the type of object expression (%0) does not match the type being destroyed "
+ "(%1) in pseudo-destructor expression">;
+def err_pseudo_dtor_call_with_args : Error<
+ "call to pseudo-destructor cannot have any arguments">;
+def err_dtor_expr_without_call : Error<
+ "%select{destructor reference|pseudo-destructor expression}0 must be "
+ "called immediately with '()'">;
+
def err_invalid_use_of_function_type : Error<
"a function type is not allowed here">;
def err_invalid_use_of_array_type : Error<"an array type is not allowed here">;
@@ -1419,6 +1712,8 @@ def err_type_defined_in_condition : Error<
"types may not be defined in conditions">;
def err_typecheck_bool_condition : Error<
"value of type %0 is not contextually convertible to 'bool'">;
+def err_typecheck_ambiguous_condition : Error<
+ "conversion from %0 to %1 is ambiguous">;
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
def err_invalid_declarator_scope : Error<
"definition or redeclaration of %0 not in a namespace enclosing %1">;
@@ -1429,6 +1724,13 @@ def err_invalid_declarator_in_function : Error<
def err_not_tag_in_scope : Error<
"%0 does not name a tag member in the specified scope">;
+def err_cannot_form_pointer_to_member_of_reference_type : Error<
+ "cannot form a pointer-to-member to member %0 of reference type %1">;
+
+def warn_condition_is_assignment : Warning<"using the result of an "
+ "assignment as a condition without parentheses">,
+ InGroup<Parentheses>;
+
def warn_value_always_zero : Warning<"%0 is always zero in this context">;
def warn_value_always_false : Warning<"%0 is always false in this context">;
@@ -1436,6 +1738,8 @@ def warn_value_always_false : Warning<"%0 is always false in this context">;
// FIXME: %2 is an english string here.
def err_typecheck_convert_incompatible : Error<
"incompatible type %2 %1, expected %0">;
+def err_typecheck_convert_ambiguous : Error<
+ "ambiguity in initializing value of type %0 with initializer of type %1">;
def err_cannot_initialize_decl_noname : Error<
"cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
"of type %2">;
@@ -1443,8 +1747,6 @@ def err_cannot_initialize_decl : Error<
"cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
def warn_incompatible_qualified_id : Warning<
"incompatible type %2 %1, expected %0">;
-def warn_incompatible_qualified_id_operands : Warning<
- "invalid operands to binary expression (%0 and %1)">;
def ext_typecheck_convert_pointer_int : ExtWarn<
"incompatible pointer to integer conversion %2 %1, expected %0">;
def ext_typecheck_convert_int_pointer : ExtWarn<
@@ -1486,7 +1788,11 @@ def err_block_decl_ref_not_modifiable_lvalue : Error<
def err_typecheck_call_not_function : Error<
"called object type %0 is not a function or function pointer">;
def err_call_incomplete_return : Error<
- "return type of called function (%0) is incomplete">;
+ "calling function with incomplete return type %0">;
+def err_call_function_incomplete_return : Error<
+ "calling %0 with incomplete return type %1">;
+def note_function_with_incomplete_return_type_declared_here : Note<
+ "%0 declared here">;
def err_call_incomplete_argument : Error<
"argument type %0 is incomplete">;
def err_typecheck_call_too_few_args : Error<
@@ -1513,12 +1819,13 @@ def err_cannot_pass_objc_interface_to_vararg : Error<
def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
"cannot pass object of non-POD type %0 through variadic "
- "%select{function|block|method}1; call will abort at runtime">;
+ "%select{function|block|method|constructor}1; call will abort at runtime">;
-def err_typecheck_closure_too_many_args : Error<
- "too many arguments to closure call">;
def err_typecheck_call_invalid_ordered_compare : Error<
"ordered compare requires two args of floating point type (%0 and %1)">;
+def err_typecheck_call_invalid_unary_fp : Error<
+ "floating point classification requires argument of floating point type "
+ "(passed in %0)">;
def err_typecheck_cond_expect_scalar : Error<
"used type %0 where arithmetic or pointer type is required">;
def ext_typecheck_cond_one_void : Extension<
@@ -1548,7 +1855,16 @@ def ext_typecheck_expression_not_constant_but_accepted : Extension<
"expression is not a constant, but is accepted as one by GNU extensions">;
def warn_unused_expr : Warning<"expression result unused">,
InGroup<UnusedValue>;
+def warn_unused_property_expr : Warning<
+ "property access result unused - getters should not have side effects">,
+ InGroup<UnusedValue>;
+def warn_unused_call : Warning<
+ "ignoring return value of function declared with %0 attribute">,
+ InGroup<UnusedValue>;
+def err_incomplete_type_used_in_type_trait_expr : Error<
+ "incomplete type %0 used in type trait expression">;
+
// inline asm.
def err_asm_wide_character : Error<"wide string is invalid in 'asm'">;
def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
@@ -1606,6 +1922,17 @@ def error_multiple_base_initialization : Error <
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
+def err_mem_initializer_mismatch : Error<
+ "Too many arguments for member initializer %0">;
+
+def warn_field_initialized : Warning<
+ "member '%0' will be initialized after">,
+ InGroup<Reorder>, DefaultIgnore;
+def warn_base_initialized : Warning<
+ "base class %0 will be initialized after">,
+ InGroup<Reorder>, DefaultIgnore;
+def note_fieldorbase_initialized_here : Note<
+ "%select{field|base}0 %1">;
def err_base_init_does_not_name_class : Error<
"constructor initializer %0 does not name a class">;
@@ -1690,6 +2017,10 @@ def err_ambiguous_member_multiple_subobject_types : Error<
def note_ambiguous_member_found : Note<"member found by ambiguous name lookup">;
def err_ambiguous_reference : Error<"reference to %0 is ambiguous">;
def note_ambiguous_candidate : Note<"candidate found by name lookup is %q0">;
+def err_ambiguous_tag_hiding : Error<"a type named %0 is hidden by a "
+ "declaration in a different namespace">;
+def note_hidden_tag : Note<"type declaration hidden">;
+def note_hiding_object : Note<"declaration hides type">;
// C++ operator overloading
def err_operator_overload_needs_class_or_enum : Error<
@@ -1850,6 +2181,9 @@ def ext_return_has_void_expr : Extension<
def warn_noreturn_function_has_return_expr : Warning<
"function %0 declared 'noreturn' should not return">, DefaultError,
InGroup<DiagGroup<"invalid-noreturn">>;
+def warn_falloff_noreturn_function : Warning<
+ "function declared 'noreturn' should not return">,
+ InGroup<DiagGroup<"invalid-noreturn">>;
def err_noreturn_block_has_return_expr : Error<
"block declared 'noreturn' should not return">;
def err_block_on_nonlocal : Error<
@@ -1867,6 +2201,9 @@ def err_shufflevector_argument_too_large : Error<
"index for __builtin_shufflevector must be less than the total number "
"of vector elements">;
+def err_vector_incorrect_num_initializers : Error<
+ "%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
+def err_altivec_empty_initializer : Error<"expected initializer">;
def err_stack_const_level : Error<
"level argument for a stack address builtin must be constant">;
@@ -1918,10 +2255,11 @@ def err_objc_array_of_interfaces : Error<
"array of interface %0 is invalid (probably should be an array of pointers)">;
def ext_c99_array_usage : Extension<
"use of C99-specific array features, accepted as an extension">;
+def err_c99_array_usage_cxx : Error<
+ "C99-specific array features are not permitted in C++">;
+
def err_invalid_protocol_qualifiers : Error<
"invalid protocol qualifiers on non-ObjC type">;
-def err_qualified_class_unsupported : Error<
- "protocol qualified 'Class' is unsupported">;
def warn_ivar_use_hidden : Warning<
"local declaration of %0 hides instance variable">;
def error_ivar_use_in_class_method : Error<
@@ -1933,6 +2271,7 @@ def error_protected_ivar_access : Error<"instance variable %0 is protected">,
def warn_maynot_respond : Warning<"%0 may not respond to %1">;
def warn_attribute_method_def : Warning<
"method attribute can only be specified on method declarations">;
-
-
+def ext_typecheck_base_super : Warning<
+ "method parameter type %0 does not match "
+ "super class method parameter type %1">, InGroup<SuperSubClassMismatch>, DefaultIgnore;
}
diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h
index d6a0cf34d9fa..7c9113c497ef 100644
--- a/include/clang/Basic/FileManager.h
+++ b/include/clang/Basic/FileManager.h
@@ -15,19 +15,17 @@
#define LLVM_CLANG_FILEMANAGER_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Config/config.h" // for mode_t
-#include <map>
-#include <set>
-#include <string>
// FIXME: Enhance libsystem to support inode and other fields in stat.
#include <sys/types.h>
#include <sys/stat.h>
namespace clang {
class FileManager;
-
+
/// DirectoryEntry - Cached information about one directory on the disk.
///
class DirectoryEntry {
@@ -35,7 +33,7 @@ class DirectoryEntry {
friend class FileManager;
public:
DirectoryEntry() : Name(0) {}
- const char *getName() const { return Name; }
+ const char *getName() const { return Name; }
};
/// FileEntry - Cached information about one file on the disk.
@@ -55,7 +53,7 @@ public:
: Name(0), Device(device), Inode(inode), FileMode(m) {}
// Add a default constructor for use with llvm::StringMap
FileEntry() : Name(0), Device(0), Inode(0), FileMode(0) {}
-
+
const char *getName() const { return Name; }
off_t getSize() const { return Size; }
unsigned getUID() const { return UID; }
@@ -63,11 +61,11 @@ public:
dev_t getDevice() const { return Device; }
time_t getModificationTime() const { return ModTime; }
mode_t getFileMode() const { return FileMode; }
-
+
/// getDir - Return the directory the file lives in.
///
const DirectoryEntry *getDir() const { return Dir; }
-
+
bool operator<(const FileEntry& RHS) const {
return Device < RHS.Device || (Device == RHS.Device && Inode < RHS.Inode);
}
@@ -87,19 +85,19 @@ public:
/// execution of the front end.
class MemorizeStatCalls : public StatSysCallCache {
public:
- /// \brief The result of a stat() call.
+ /// \brief The result of a stat() call.
///
/// The first member is the result of calling stat(). If stat()
/// found something, the second member is a copy of the stat
/// structure.
typedef std::pair<int, struct stat> StatResult;
- /// \brief The set of stat() calls that have been
+ /// \brief The set of stat() calls that have been
llvm::StringMap<StatResult, llvm::BumpPtrAllocator> StatCalls;
typedef llvm::StringMap<StatResult, llvm::BumpPtrAllocator>::const_iterator
iterator;
-
+
iterator begin() const { return StatCalls.begin(); }
iterator end() const { return StatCalls.end(); }
@@ -126,22 +124,22 @@ class FileManager {
///
llvm::StringMap<DirectoryEntry*, llvm::BumpPtrAllocator> DirEntries;
llvm::StringMap<FileEntry*, llvm::BumpPtrAllocator> FileEntries;
-
+
/// NextFileUID - Each FileEntry we create is assigned a unique ID #.
///
unsigned NextFileUID;
-
+
// Statistics.
unsigned NumDirLookups, NumFileLookups;
unsigned NumDirCacheMisses, NumFileCacheMisses;
-
+
// Caching.
llvm::OwningPtr<StatSysCallCache> StatCache;
int stat_cached(const char* path, struct stat* buf) {
return StatCache.get() ? StatCache->stat(path, buf) : stat(path, buf);
}
-
+
public:
FileManager();
~FileManager();
@@ -152,24 +150,24 @@ public:
void setStatCache(StatSysCallCache *statCache) {
StatCache.reset(statCache);
}
-
+
/// getDirectory - Lookup, cache, and verify the specified directory. This
/// returns null if the directory doesn't exist.
- ///
- const DirectoryEntry *getDirectory(const std::string &Filename) {
- return getDirectory(&Filename[0], &Filename[0] + Filename.size());
+ ///
+ const DirectoryEntry *getDirectory(const llvm::StringRef &Filename) {
+ return getDirectory(Filename.begin(), Filename.end());
}
const DirectoryEntry *getDirectory(const char *FileStart,const char *FileEnd);
-
+
/// getFile - Lookup, cache, and verify the specified file. This returns null
/// if the file doesn't exist.
- ///
- const FileEntry *getFile(const std::string &Filename) {
- return getFile(&Filename[0], &Filename[0] + Filename.size());
+ ///
+ const FileEntry *getFile(const llvm::StringRef &Filename) {
+ return getFile(Filename.begin(), Filename.end());
}
const FileEntry *getFile(const char *FilenameStart,
const char *FilenameEnd);
-
+
void PrintStats() const;
};
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 57cd31163144..84c2fc910d11 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -21,8 +21,8 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
-#include <string>
-#include <cassert>
+#include <string>
+#include <cassert>
namespace llvm {
template <typename T> struct DenseMapInfo;
@@ -38,21 +38,21 @@ namespace clang {
/// IdentifierLocPair - A simple pair of identifier info and location.
typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
-
-
+
+
/// IdentifierInfo - One of these records is kept for each identifier that
/// is lexed. This contains information about whether the token was #define'd,
/// is a language keyword, or if it is a front-end token of some sort (e.g. a
/// variable or function name). The preprocessor keeps this information in a
-/// set, and all tok::identifier tokens have a pointer to one of these.
+/// set, and all tok::identifier tokens have a pointer to one of these.
class IdentifierInfo {
// Note: DON'T make TokenID a 'tok::TokenKind'; MSVC will treat it as a
// signed char and TokenKinds > 127 won't be handled correctly.
- unsigned TokenID : 8; // Front-end token ID or tok::identifier.
+ unsigned TokenID : 8; // Front-end token ID or tok::identifier.
// Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf).
// First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values
// are for builtins.
- unsigned ObjCOrBuiltinID :10;
+ unsigned ObjCOrBuiltinID :10;
bool HasMacro : 1; // True if there is a #define for this.
bool IsExtension : 1; // True if identifier is a lang extension.
bool IsPoisoned : 1; // True if identifier is poisoned.
@@ -61,50 +61,50 @@ class IdentifierInfo {
// 9 bits left in 32-bit word.
void *FETokenInfo; // Managed by the language front-end.
llvm::StringMapEntry<IdentifierInfo*> *Entry;
-
+
IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
void operator=(const IdentifierInfo&); // NONASSIGNABLE.
- friend class IdentifierTable;
+ friend class IdentifierTable;
public:
IdentifierInfo();
-
+
/// isStr - Return true if this is the identifier for the specified string.
/// This is intended to be used for string literals only: II->isStr("foo").
template <std::size_t StrLen>
bool isStr(const char (&Str)[StrLen]) const {
return getLength() == StrLen-1 && !memcmp(getName(), Str, StrLen-1);
}
-
- /// getName - Return the actual string for this identifier. The returned
+
+ /// getName - Return the actual string for this identifier. The returned
/// string is properly null terminated.
///
- const char *getName() const {
+ const char *getName() const {
if (Entry) return Entry->getKeyData();
// FIXME: This is gross. It would be best not to embed specific details
// of the PTH file format here.
- // The 'this' pointer really points to a
+ // The 'this' pointer really points to a
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
return ((std::pair<IdentifierInfo, const char*>*) this)->second;
}
-
+
/// getLength - Efficiently return the length of this identifier info.
///
unsigned getLength() const {
if (Entry) return Entry->getKeyLength();
// FIXME: This is gross. It would be best not to embed specific details
// of the PTH file format here.
- // The 'this' pointer really points to a
+ // The 'this' pointer really points to a
// std::pair<IdentifierInfo, const char*>, where internal pointer
// points to the external string data.
const char* p = ((std::pair<IdentifierInfo, const char*>*) this)->second-2;
return (((unsigned) p[0])
| (((unsigned) p[1]) << 8)) - 1;
}
-
+
/// hasMacroDefinition - Return true if this identifier is #defined to some
/// other value.
bool hasMacroDefinition() const {
@@ -112,29 +112,29 @@ public:
}
void setHasMacroDefinition(bool Val) {
if (HasMacro == Val) return;
-
+
HasMacro = Val;
if (Val)
NeedsHandleIdentifier = 1;
else
RecomputeNeedsHandleIdentifier();
}
-
+
/// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
/// can be used to cause the lexer to map identifiers to source-language
/// tokens.
tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; }
void setTokenID(tok::TokenKind ID) { TokenID = ID; }
-
+
/// getPPKeywordID - Return the preprocessor keyword ID for this identifier.
/// For example, "define" will return tok::pp_define.
tok::PPKeywordKind getPPKeywordID() const;
-
+
/// getObjCKeywordID - Return the Objective-C keyword ID for the this
/// identifier. For example, 'class' will return tok::objc_class if ObjC is
/// enabled.
tok::ObjCKeywordKind getObjCKeywordID() const {
- if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
+ if (ObjCOrBuiltinID < tok::NUM_OBJC_KEYWORDS)
return tok::ObjCKeywordKind(ObjCOrBuiltinID);
else
return tok::objc_not_keyword;
@@ -144,15 +144,15 @@ public:
/// getBuiltinID - Return a value indicating whether this is a builtin
/// function. 0 is not-built-in. 1 is builtin-for-some-nonprimary-target.
/// 2+ are specific builtin functions.
- unsigned getBuiltinID() const {
+ unsigned getBuiltinID() const {
if (ObjCOrBuiltinID >= tok::NUM_OBJC_KEYWORDS)
- return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
+ return ObjCOrBuiltinID - tok::NUM_OBJC_KEYWORDS;
else
return 0;
}
void setBuiltinID(unsigned ID) {
ObjCOrBuiltinID = ID + tok::NUM_OBJC_KEYWORDS;
- assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
+ assert(ObjCOrBuiltinID - unsigned(tok::NUM_OBJC_KEYWORDS) == ID
&& "ID too large for field!");
}
@@ -170,7 +170,7 @@ public:
else
RecomputeNeedsHandleIdentifier();
}
-
+
/// setIsPoisoned - Mark this identifier as poisoned. After poisoning, the
/// Preprocessor will emit an error every time this token is used.
void setIsPoisoned(bool Value = true) {
@@ -180,10 +180,10 @@ public:
else
RecomputeNeedsHandleIdentifier();
}
-
+
/// isPoisoned - Return true if this token has been poisoned.
bool isPoisoned() const { return IsPoisoned; }
-
+
/// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
/// this identifier is a C++ alternate representation of an operator.
void setIsCPlusPlusOperatorKeyword(bool Val = true) {
@@ -205,7 +205,7 @@ public:
/// must be called on a token of this identifier. If this returns false, we
/// know that HandleIdentifier will not affect the token.
bool isHandleIdentifierCase() const { return NeedsHandleIdentifier; }
-
+
private:
/// RecomputeNeedsHandleIdentifier - The Preprocessor::HandleIdentifier does
/// several special (but rare) things to identifiers of various sorts. For
@@ -227,13 +227,13 @@ private:
class IdentifierInfoLookup {
public:
virtual ~IdentifierInfoLookup();
-
+
/// get - Return the identifier token info for the specified named identifier.
/// Unlike the version in IdentifierTable, this returns a pointer instead
/// of a reference. If the pointer is NULL then the IdentifierInfo cannot
/// be found.
virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd) = 0;
-};
+};
/// \brief An abstract class used to resolve numerical identifier
/// references (meaningful only to some external source) into
@@ -257,7 +257,7 @@ class IdentifierTable {
// BumpPtrAllocator!
typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy;
HashTableTy HashTable;
-
+
IdentifierInfoLookup* ExternalLookup;
public:
@@ -265,7 +265,7 @@ public:
/// info about the language keywords for the language specified by LangOpts.
IdentifierTable(const LangOptions &LangOpts,
IdentifierInfoLookup* externalLookup = 0);
-
+
/// \brief Set the external identifier lookup mechanism.
void setExternalIdentifierLookup(IdentifierInfoLookup *IILookup) {
ExternalLookup = IILookup;
@@ -274,16 +274,16 @@ public:
llvm::BumpPtrAllocator& getAllocator() {
return HashTable.getAllocator();
}
-
+
/// get - Return the identifier token info for the specified named identifier.
///
IdentifierInfo &get(const char *NameStart, const char *NameEnd) {
llvm::StringMapEntry<IdentifierInfo*> &Entry =
HashTable.GetOrCreateValue(NameStart, NameEnd);
-
+
IdentifierInfo *II = Entry.getValue();
if (II) return *II;
-
+
// No entry; if we have an external lookup, look there first.
if (ExternalLookup) {
II = ExternalLookup->get(NameStart, NameEnd);
@@ -305,7 +305,7 @@ public:
return *II;
}
-
+
/// \brief Creates a new IdentifierInfo from the given string.
///
/// This is a lower-level version of get() that requires that this
@@ -314,14 +314,14 @@ public:
/// identifier sources can use this routine to build IdentifierInfo
/// nodes and then introduce additional information about those
/// identifiers.
- IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
+ IdentifierInfo &CreateIdentifierInfo(const char *NameStart,
const char *NameEnd) {
llvm::StringMapEntry<IdentifierInfo*> &Entry =
HashTable.GetOrCreateValue(NameStart, NameEnd);
-
+
IdentifierInfo *II = Entry.getValue();
assert(!II && "IdentifierInfo already exists");
-
+
// Lookups failed, make a new IdentifierInfo.
void *Mem = getAllocator().Allocate<IdentifierInfo>();
II = new (Mem) IdentifierInfo();
@@ -334,37 +334,32 @@ public:
return *II;
}
- IdentifierInfo &get(const char *Name) {
- return get(Name, Name+strlen(Name));
- }
- IdentifierInfo &get(const std::string &Name) {
- // Don't use c_str() here: no need to be null terminated.
- const char *NameBytes = Name.data();
- return get(NameBytes, NameBytes+Name.size());
+ IdentifierInfo &get(const llvm::StringRef& Name) {
+ return get(Name.begin(), Name.end());
}
typedef HashTableTy::const_iterator iterator;
typedef HashTableTy::const_iterator const_iterator;
-
+
iterator begin() const { return HashTable.begin(); }
iterator end() const { return HashTable.end(); }
unsigned size() const { return HashTable.size(); }
-
+
/// PrintStats - Print some statistics to stderr that indicate how well the
/// hashing is doing.
void PrintStats() const;
-
+
void AddKeywords(const LangOptions &LangOpts);
};
/// Selector - This smart pointer class efficiently represents Objective-C
/// method names. This class will either point to an IdentifierInfo or a
/// MultiKeywordSelector (which is private). This enables us to optimize
-/// selectors that take no arguments and selectors that take 1 argument, which
+/// selectors that take no arguments and selectors that take 1 argument, which
/// accounts for 78% of all selectors in Cocoa.h.
class Selector {
friend class DiagnosticInfo;
-
+
enum IdentifierInfoFlag {
// MultiKeywordSelector = 0.
ZeroArg = 0x1,
@@ -372,7 +367,7 @@ class Selector {
ArgFlags = ZeroArg|OneArg
};
uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
-
+
Selector(IdentifierInfo *II, unsigned nArgs) {
InfoPtr = reinterpret_cast<uintptr_t>(II);
assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
@@ -383,7 +378,7 @@ class Selector {
InfoPtr = reinterpret_cast<uintptr_t>(SI);
assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
}
-
+
IdentifierInfo *getAsIdentifierInfo() const {
if (getIdentifierInfoFlag())
return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
@@ -417,19 +412,19 @@ public:
bool isNull() const { return InfoPtr == 0; }
// Predicates to identify the selector type.
- bool isKeywordSelector() const {
- return getIdentifierInfoFlag() != ZeroArg;
+ bool isKeywordSelector() const {
+ return getIdentifierInfoFlag() != ZeroArg;
}
- bool isUnarySelector() const {
+ bool isUnarySelector() const {
return getIdentifierInfoFlag() == ZeroArg;
}
unsigned getNumArgs() const;
IdentifierInfo *getIdentifierInfoForSlot(unsigned argIndex) const;
-
+
/// getAsString - Derive the full selector name (e.g. "foo:bar:") and return
/// it as an std::string.
std::string getAsString() const;
-
+
static Selector getEmptyMarker() {
return Selector(uintptr_t(-1));
}
@@ -452,7 +447,7 @@ public:
/// whether this is a no argument selector "foo", a single argument selector
/// "foo:" or multi-argument "foo:bar:".
Selector getSelector(unsigned NumArgs, IdentifierInfo **IIV);
-
+
Selector getUnarySelector(IdentifierInfo *ID) {
return Selector(ID, 1);
}
@@ -519,15 +514,15 @@ struct DenseMapInfo<clang::Selector> {
return clang::Selector::getEmptyMarker();
}
static inline clang::Selector getTombstoneKey() {
- return clang::Selector::getTombstoneMarker();
+ return clang::Selector::getTombstoneMarker();
}
-
+
static unsigned getHashValue(clang::Selector S);
-
+
static bool isEqual(clang::Selector LHS, clang::Selector RHS) {
return LHS == RHS;
}
-
+
static bool isPod() { return true; }
};
@@ -537,7 +532,7 @@ template<>
class PointerLikeTypeTraits<clang::IdentifierInfo*> {
public:
static inline void *getAsVoidPointer(clang::IdentifierInfo* P) {
- return P;
+ return P;
}
static inline clang::IdentifierInfo *getFromVoidPointer(void *P) {
return static_cast<clang::IdentifierInfo*>(P);
@@ -549,7 +544,7 @@ template<>
class PointerLikeTypeTraits<const clang::IdentifierInfo*> {
public:
static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) {
- return P;
+ return P;
}
static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) {
return static_cast<const clang::IdentifierInfo*>(P);
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 26688bf56728..d4d3fe50eba0 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -34,18 +34,17 @@ public:
unsigned CPlusPlus : 1; // C++ Support
unsigned CPlusPlus0x : 1; // C++0x Support
unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords.
-
+
unsigned ObjC1 : 1; // Objective-C 1 support enabled.
unsigned ObjC2 : 1; // Objective-C 2 support enabled.
- unsigned ObjCSenderDispatch: 1; // Objective-C 2 three-dimensional dispatch
- // enabled.
unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled
-
+
unsigned PascalStrings : 1; // Allow Pascal strings
unsigned WritableStrings : 1; // Allow writable strings
unsigned LaxVectorConversions : 1;
unsigned AltiVec : 1; // Support AltiVec-style vector initializers.
unsigned Exceptions : 1; // Support exception handling.
+ unsigned Rtti : 1; // Support rtti information.
unsigned NeXTRuntime : 1; // Use NeXT runtime.
unsigned Freestanding : 1; // Freestanding implementation
@@ -53,6 +52,8 @@ public:
unsigned ThreadsafeStatics : 1; // Whether static initializers are protected
// by locks.
+ unsigned POSIXThreads : 1; // Compiling with POSIX thread support
+ // (-pthread)
unsigned Blocks : 1; // block extension to C
unsigned EmitAllDecls : 1; // Emit all declarations, even if
// they are unused.
@@ -66,7 +67,7 @@ public:
// may be ripped out at any time.
unsigned Optimize : 1; // Whether __OPTIMIZE__ should be defined.
- unsigned OptimizeSize : 1; // Whether __OPTIMIZE_SIZE__ should be
+ unsigned OptimizeSize : 1; // Whether __OPTIMIZE_SIZE__ should be
// defined.
unsigned Static : 1; // Should __STATIC__ be defined (as
// opposed to __DYNAMIC__).
@@ -79,12 +80,14 @@ public:
unsigned ObjCGCBitmapPrint : 1; // Enable printing of gc's bitmap layout
// for __weak/__strong ivars.
- unsigned AccessControl : 1; // Whether C++ access control should
+ unsigned AccessControl : 1; // Whether C++ access control should
// be enabled.
unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type
unsigned OpenCL : 1; // OpenCL C99 language extensions.
+ unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
+ // elided if possible.
private:
unsigned GC : 2; // Objective-C Garbage Collection modes. We
// declare this enum as unsigned because MSVC
@@ -101,46 +104,51 @@ private:
/// the original input file, for example with -save-temps.
const char *MainFileName;
-public:
+public:
unsigned InstantiationDepth; // Maximum template instantiation depth.
+ const char *ObjCConstantStringClass;
+
enum GCMode { NonGC, GCOnly, HybridGC };
enum StackProtectorMode { SSPOff, SSPOn, SSPReq };
- enum VisibilityMode {
- Default,
- Protected,
+ enum VisibilityMode {
+ Default,
+ Protected,
Hidden
};
-
+
LangOptions() {
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
GNUMode = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0;
+ ObjCConstantStringClass = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = 0;
Exceptions = NeXTRuntime = Freestanding = NoBuiltin = 0;
+ Rtti = 1;
LaxVectorConversions = 1;
HeinousExtensions = 0;
AltiVec = OpenCL = StackProtector = 0;
-
+
SymbolVisibility = (unsigned) Default;
-
+
// FIXME: The default should be 1.
ThreadsafeStatics = 0;
+ POSIXThreads = 0;
Blocks = 0;
EmitAllDecls = 0;
MathErrno = 1;
// FIXME: The default should be 1.
AccessControl = 0;
-
+ ElideConstructors = 1;
+
OverflowChecking = 0;
ObjCGCBitmapPrint = 0;
- ObjCSenderDispatch = 0;
InstantiationDepth = 99;
-
+
Optimize = 0;
OptimizeSize = 0;
@@ -154,7 +162,7 @@ public:
MainFileName = 0;
}
-
+
GCMode getGCMode() const { return (GCMode) GC; }
void setGCMode(GCMode m) { GC = (unsigned) m; }
@@ -168,8 +176,8 @@ public:
const char *getMainFileName() const { return MainFileName; }
void setMainFileName(const char *Name) { MainFileName = Name; }
- VisibilityMode getVisibilityMode() const {
- return (VisibilityMode) SymbolVisibility;
+ VisibilityMode getVisibilityMode() const {
+ return (VisibilityMode) SymbolVisibility;
}
void setVisibilityMode(VisibilityMode v) { SymbolVisibility = (unsigned) v; }
};
diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile
index b08d61457b75..6ed5fefb7e64 100644
--- a/include/clang/Basic/Makefile
+++ b/include/clang/Basic/Makefile
@@ -9,12 +9,12 @@ TABLEGEN_INC_FILES_COMMON = 1
include $(LEVEL)/Makefile.common
-$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td DiagnosticGroups.td Diagnostic%Kinds.td $(TBLGEN)
+$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN)
$(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen"
$(Verb) -$(MKDIR) $(@D)
$(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $<
-$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td $(wildcard Diagnostic*.td) $(TBLGEN)
+$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(wildcard Diagnostic*.td) $(TBLGEN)
$(Echo) "Building Clang diagnostic groups with tblgen"
$(Verb) -$(MKDIR) $(@D)
$(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $<
diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h
index f54d67042c47..65245167d8d5 100644
--- a/include/clang/Basic/OnDiskHashTable.h
+++ b/include/clang/Basic/OnDiskHashTable.h
@@ -29,7 +29,7 @@ namespace clang {
// This is basically copy-and-paste from StringMap. This likely won't
// stay here, which is why I didn't both to expose this function from
// String Map.
-inline unsigned BernsteinHash(const char* x) {
+inline unsigned BernsteinHash(const char* x) {
unsigned int R = 0;
for ( ; *x != '\0' ; ++x) R = R * 33 + *x;
return R + (R >> 5);
@@ -131,29 +131,29 @@ class OnDiskChainedHashTableGenerator {
unsigned NumBuckets;
unsigned NumEntries;
llvm::BumpPtrAllocator BA;
-
+
class Item {
public:
typename Info::key_type key;
typename Info::data_type data;
Item *next;
const uint32_t hash;
-
+
Item(typename Info::key_type_ref k, typename Info::data_type_ref d)
: key(k), data(d), next(0), hash(Info::ComputeHash(k)) {}
};
-
- class Bucket {
+
+ class Bucket {
public:
io::Offset off;
Item* head;
unsigned length;
-
+
Bucket() {}
};
-
+
Bucket* Buckets;
-
+
private:
void insert(Bucket* b, size_t size, Item* E) {
unsigned idx = E->hash & (size - 1);
@@ -162,7 +162,7 @@ private:
++B.length;
B.head = E;
}
-
+
void resize(size_t newsize) {
Bucket* newBuckets = (Bucket*) std::calloc(newsize, sizeof(Bucket));
// Populate newBuckets with the old entries.
@@ -173,14 +173,14 @@ private:
insert(newBuckets, newsize, E);
E = N;
}
-
+
free(Buckets);
NumBuckets = newsize;
Buckets = newBuckets;
- }
-
+ }
+
public:
-
+
void insert(typename Info::key_type_ref key,
typename Info::data_type_ref data) {
@@ -188,7 +188,7 @@ public:
if (4*NumEntries >= 3*NumBuckets) resize(NumBuckets*2);
insert(Buckets, NumBuckets, new (BA.Allocate<Item>()) Item(key, data));
}
-
+
io::Offset Emit(llvm::raw_ostream &out) {
Info InfoObj;
return Emit(out, InfoObj);
@@ -201,42 +201,42 @@ public:
for (unsigned i = 0; i < NumBuckets; ++i) {
Bucket& B = Buckets[i];
if (!B.head) continue;
-
+
// Store the offset for the data of this bucket.
B.off = out.tell();
assert(B.off && "Cannot write a bucket at offset 0. Please add padding.");
// Write out the number of items in the bucket.
Emit16(out, B.length);
-
+
// Write out the entries in the bucket.
for (Item *I = B.head; I ; I = I->next) {
Emit32(out, I->hash);
- const std::pair<unsigned, unsigned>& Len =
+ const std::pair<unsigned, unsigned>& Len =
InfoObj.EmitKeyDataLength(out, I->key, I->data);
InfoObj.EmitKey(out, I->key, Len.first);
InfoObj.EmitData(out, I->key, I->data, Len.second);
}
}
-
+
// Emit the hashtable itself.
Pad(out, 4);
io::Offset TableOff = out.tell();
Emit32(out, NumBuckets);
Emit32(out, NumEntries);
for (unsigned i = 0; i < NumBuckets; ++i) Emit32(out, Buckets[i].off);
-
+
return TableOff;
}
-
+
OnDiskChainedHashTableGenerator() {
NumEntries = 0;
- NumBuckets = 64;
+ NumBuckets = 64;
// Note that we do not need to run the constructors of the individual
// Bucket objects since 'calloc' returns bytes that are all 0.
Buckets = (Bucket*) std::calloc(NumBuckets, sizeof(Bucket));
}
-
+
~OnDiskChainedHashTableGenerator() {
std::free(Buckets);
}
@@ -254,7 +254,7 @@ public:
typedef typename Info::internal_key_type internal_key_type;
typedef typename Info::external_key_type external_key_type;
typedef typename Info::data_type data_type;
-
+
OnDiskChainedHashTable(unsigned numBuckets, unsigned numEntries,
const unsigned char* buckets,
const unsigned char* base,
@@ -271,7 +271,7 @@ public:
const unsigned char* getBuckets() const { return Buckets; }
bool isEmpty() const { return NumEntries == 0; }
-
+
class iterator {
internal_key_type key;
const unsigned char* const data;
@@ -282,12 +282,12 @@ public:
iterator(const internal_key_type k, const unsigned char* d, unsigned l,
Info *InfoObj)
: key(k), data(d), len(l), InfoObj(InfoObj) {}
-
- data_type operator*() const { return InfoObj->ReadData(key, data, len); }
- bool operator==(const iterator& X) const { return X.data == data; }
+
+ data_type operator*() const { return InfoObj->ReadData(key, data, len); }
+ bool operator==(const iterator& X) const { return X.data == data; }
bool operator!=(const iterator& X) const { return X.data != data; }
- };
-
+ };
+
iterator find(const external_key_type& eKey, Info *InfoPtr = 0) {
if (!InfoPtr)
InfoPtr = &InfoObj;
@@ -295,25 +295,25 @@ public:
using namespace io;
const internal_key_type& iKey = Info::GetInternalKey(eKey);
unsigned key_hash = Info::ComputeHash(iKey);
-
+
// Each bucket is just a 32-bit offset into the hash table file.
unsigned idx = key_hash & (NumBuckets - 1);
const unsigned char* Bucket = Buckets + sizeof(uint32_t)*idx;
-
+
unsigned offset = ReadLE32(Bucket);
if (offset == 0) return iterator(); // Empty bucket.
const unsigned char* Items = Base + offset;
-
+
// 'Items' starts with a 16-bit unsigned integer representing the
// number of items in this bucket.
unsigned len = ReadUnalignedLE16(Items);
-
+
for (unsigned i = 0; i < len; ++i) {
// Read the hash.
uint32_t item_hash = ReadUnalignedLE32(Items);
-
+
// Determine the length of the key and the data.
- const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Items);
+ const std::pair<unsigned, unsigned>& L = Info::ReadKeyDataLength(Items);
unsigned item_len = L.first + L.second;
// Compare the hashes. If they are not the same, skip the entry entirely.
@@ -321,7 +321,7 @@ public:
Items += item_len;
continue;
}
-
+
// Read the key.
const internal_key_type& X =
InfoPtr->ReadKey((const unsigned char* const) Items, L.first);
@@ -331,17 +331,17 @@ public:
Items += item_len;
continue;
}
-
+
// The key matches!
return iterator(X, Items + L.first, L.second, InfoPtr);
}
-
+
return iterator();
}
-
+
iterator end() const { return iterator(); }
-
-
+
+
static OnDiskChainedHashTable* Create(const unsigned char* buckets,
const unsigned char* const base,
const Info &InfoObj = Info()) {
@@ -349,14 +349,14 @@ public:
assert(buckets > base);
assert((reinterpret_cast<uintptr_t>(buckets) & 0x3) == 0 &&
"buckets should be 4-byte aligned.");
-
+
unsigned numBuckets = ReadLE32(buckets);
unsigned numEntries = ReadLE32(buckets);
return new OnDiskChainedHashTable<Info>(numBuckets, numEntries, buckets,
base, InfoObj);
- }
+ }
};
} // end namespace clang
-#endif
+#endif
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
new file mode 100644
index 000000000000..e8cc564c8a20
--- /dev/null
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -0,0 +1,155 @@
+//===--- PartialDiagnostic.h - Diagnostic "closures" ----------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a partial diagnostic that can be emitted anwyhere
+// in a DiagnosticBuilder stream.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
+#define LLVM_CLANG_PARTIALDIAGNOSTIC_H
+
+#include "clang/AST/Type.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace clang {
+
+class DeclarationName;
+
+class PartialDiagnostic {
+ struct Storage {
+ Storage() : NumDiagArgs(0), NumDiagRanges(0) { }
+
+ enum {
+ /// MaxArguments - The maximum number of arguments we can hold. We
+ /// currently only support up to 10 arguments (%0-%9).
+ /// A single diagnostic with more than that almost certainly has to
+ /// be simplified anyway.
+ MaxArguments = 10
+ };
+
+ /// NumDiagArgs - This contains the number of entries in Arguments.
+ unsigned char NumDiagArgs;
+
+ /// NumDiagRanges - This is the number of ranges in the DiagRanges array.
+ unsigned char NumDiagRanges;
+
+ /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
+ /// values, with one for each argument. This specifies whether the argument
+ /// is in DiagArgumentsStr or in DiagArguments.
+ unsigned char DiagArgumentsKind[MaxArguments];
+
+ /// DiagArgumentsVal - The values for the various substitution positions.
+ /// This is used when the argument is not an std::string. The specific value
+ /// is mangled into an intptr_t and the intepretation depends on exactly
+ /// what sort of argument kind it is.
+ mutable intptr_t DiagArgumentsVal[MaxArguments];
+
+ /// DiagRanges - The list of ranges added to this diagnostic. It currently
+ /// only support 10 ranges, could easily be extended if needed.
+ mutable const SourceRange *DiagRanges[10];
+ };
+
+ /// DiagID - The diagnostic ID.
+ mutable unsigned DiagID;
+
+ /// DiagStorare - Storge for args and ranges.
+ mutable Storage *DiagStorage;
+
+ void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
+ if (!DiagStorage)
+ DiagStorage = new Storage;
+
+ assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
+ "Too many arguments to diagnostic!");
+ DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
+ DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
+ }
+
+ void AddSourceRange(const SourceRange &R) const {
+ if (!DiagStorage)
+ DiagStorage = new Storage;
+
+ assert(DiagStorage->NumDiagRanges <
+ llvm::array_lengthof(DiagStorage->DiagRanges) &&
+ "Too many arguments to diagnostic!");
+ DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = &R;
+ }
+
+ void operator=(const PartialDiagnostic &); // DO NOT IMPLEMENT
+
+public:
+ PartialDiagnostic(unsigned DiagID)
+ : DiagID(DiagID), DiagStorage(0) { }
+
+ PartialDiagnostic(const PartialDiagnostic &Other)
+ : DiagID(Other.DiagID), DiagStorage(Other.DiagStorage) {
+ Other.DiagID = 0;
+ Other.DiagStorage = 0;
+ }
+
+ ~PartialDiagnostic() {
+ delete DiagStorage;
+ }
+
+ unsigned getDiagID() const { return DiagID; }
+
+ void Emit(const DiagnosticBuilder &DB) const {
+ if (!DiagStorage)
+ return;
+
+ // Add all arguments.
+ for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) {
+ DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i],
+ (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]);
+ }
+
+ // Add all ranges.
+ for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i)
+ DB.AddSourceRange(*DiagStorage->DiagRanges[i]);
+ }
+
+ friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ QualType T) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+ Diagnostic::ak_qualtype);
+ return PD;
+ }
+
+ friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ unsigned I) {
+ PD.AddTaggedVal(I, Diagnostic::ak_uint);
+ return PD;
+ }
+
+ friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const SourceRange &R) {
+ PD.AddSourceRange(R);
+ return PD;
+ }
+
+ friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ DeclarationName N);
+};
+
+inline PartialDiagnostic PDiag(unsigned DiagID = 0) {
+ return PartialDiagnostic(DiagID);
+}
+
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const PartialDiagnostic &PD) {
+ PD.Emit(DB);
+ return DB;
+}
+
+
+} // end namespace clang
+#endif
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 2405c2fe7db7..28cf2db9bc25 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -24,10 +24,10 @@ namespace llvm {
}
namespace clang {
-
+
class SourceManager;
class FileEntry;
-
+
/// FileID - This is an opaque identifier used by SourceManager which refers to
/// a source file (MemoryBuffer) along with its #include path and #line data.
///
@@ -36,19 +36,19 @@ class FileID {
unsigned ID;
public:
FileID() : ID(0) {}
-
+
bool isInvalid() const { return ID == 0; }
-
+
bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
bool operator>(const FileID &RHS) const { return RHS < *this; }
bool operator>=(const FileID &RHS) const { return RHS <= *this; }
-
+
static FileID getSentinel() { return get(~0U); }
unsigned getHashValue() const { return ID; }
-
+
private:
friend class SourceManager;
static FileID get(unsigned V) {
@@ -58,8 +58,8 @@ private:
}
unsigned getOpaqueValue() const { return ID; }
};
-
-
+
+
/// SourceLocation - This is a carefully crafted 32-bit identifier that encodes
/// a full include stack, line and column number information for a position in
/// an input translation unit.
@@ -72,17 +72,17 @@ class SourceLocation {
public:
SourceLocation() : ID(0) {} // 0 is an invalid FileID.
-
+
bool isFileID() const { return (ID & MacroIDBit) == 0; }
bool isMacroID() const { return (ID & MacroIDBit) != 0; }
-
+
/// isValid - Return true if this is a valid SourceLocation object. Invalid
/// SourceLocations are often used when events have no corresponding location
/// in the source (e.g. a diagnostic is required for a command line option).
///
bool isValid() const { return ID != 0; }
bool isInvalid() const { return ID == 0; }
-
+
private:
/// getOffset - Return the index for SourceManager's SLocEntryTable table,
/// note that this is not an index *into* it though.
@@ -96,7 +96,7 @@ private:
L.ID = ID;
return L;
}
-
+
static SourceLocation getMacroLoc(unsigned ID) {
assert((ID & MacroIDBit) == 0 && "Ran out of source locations!");
SourceLocation L;
@@ -104,7 +104,7 @@ private:
return L;
}
public:
-
+
/// getFileLocWithOffset - Return a source location with the specified offset
/// from this file SourceLocation.
SourceLocation getFileLocWithOffset(int Offset) const {
@@ -113,14 +113,14 @@ public:
L.ID = ID+Offset;
return L;
}
-
+
/// getRawEncoding - When a SourceLocation itself cannot be used, this returns
/// an (opaque) 32-bit integer encoding for it. This should only be passed
/// to SourceLocation::getFromRawEncoding, it should not be inspected
/// directly.
unsigned getRawEncoding() const { return ID; }
-
-
+
+
/// getFromRawEncoding - Turn a raw encoding of a SourceLocation object into
/// a real SourceLocation.
static SourceLocation getFromRawEncoding(unsigned Encoding) {
@@ -128,7 +128,7 @@ public:
X.ID = Encoding;
return X;
}
-
+
void print(llvm::raw_ostream &OS, const SourceManager &SM) const;
void dump(const SourceManager &SM) const;
};
@@ -140,7 +140,7 @@ inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
return !(LHS == RHS);
}
-
+
inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.getRawEncoding() < RHS.getRawEncoding();
}
@@ -153,24 +153,24 @@ public:
SourceRange(): B(SourceLocation()), E(SourceLocation()) {}
SourceRange(SourceLocation loc) : B(loc), E(loc) {}
SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
-
+
SourceLocation getBegin() const { return B; }
SourceLocation getEnd() const { return E; }
-
+
void setBegin(SourceLocation b) { B = b; }
void setEnd(SourceLocation e) { E = e; }
-
+
bool isValid() const { return B.isValid() && E.isValid(); }
-
+
bool operator==(const SourceRange &X) const {
return B == X.B && E == X.E;
}
-
+
bool operator!=(const SourceRange &X) const {
return B != X.B || E != X.E;
}
};
-
+
/// FullSourceLoc - A SourceLocation and its associated SourceManager. Useful
/// for argument passing to functions that expect both objects.
class FullSourceLoc : public SourceLocation {
@@ -179,21 +179,21 @@ public:
/// Creates a FullSourceLoc where isValid() returns false.
explicit FullSourceLoc() : SrcMgr((SourceManager*) 0) {}
- explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM)
+ explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
-
+
SourceManager &getManager() {
assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
}
-
+
const SourceManager &getManager() const {
assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
}
-
+
FileID getFileID() const;
-
+
FullSourceLoc getInstantiationLoc() const;
FullSourceLoc getSpellingLoc() const;
@@ -204,37 +204,37 @@ public:
unsigned getSpellingColumnNumber() const;
const char *getCharacterData() const;
-
+
const llvm::MemoryBuffer* getBuffer() const;
-
+
/// getBufferData - Return a pointer to the start and end of the source buffer
/// data for the specified FileID.
std::pair<const char*, const char*> getBufferData() const;
-
+
/// getDecomposedLoc - Decompose the specified location into a raw FileID +
/// Offset pair. The first element is the FileID, the second is the
/// offset from the start of the buffer of the location.
std::pair<FileID, unsigned> getDecomposedLoc() const;
bool isInSystemHeader() const;
-
+
/// Prints information about this FullSourceLoc to stderr. Useful for
/// debugging.
void dump() const { SourceLocation::dump(*SrcMgr); }
- friend inline bool
+ friend inline bool
operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
return LHS.getRawEncoding() == RHS.getRawEncoding() &&
LHS.SrcMgr == RHS.SrcMgr;
}
- friend inline bool
+ friend inline bool
operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
return !(LHS == RHS);
}
};
-
+
/// PresumedLoc - This class represents an unpacked "presumed" location which
/// can be presented to the user. A 'presumed' location can be modified by
/// #line and GNU line marker directives and is always the instantiation point
@@ -250,13 +250,13 @@ public:
PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL)
: Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) {
}
-
+
/// isInvalid - Return true if this object is invalid or uninitialized. This
/// occurs when created with invalid source locations or when walking off
/// the top of a #include stack.
bool isInvalid() const { return Filename == 0; }
bool isValid() const { return Filename != 0; }
-
+
/// getFilename - Return the presumed filename of this location. This can be
/// affected by #line etc.
const char *getFilename() const { return Filename; }
@@ -264,7 +264,7 @@ public:
/// getLine - Return the presumed line number of this location. This can be
/// affected by #line etc.
unsigned getLine() const { return Line; }
-
+
/// getColumn - Return the presumed column number of this location. This can
/// not be affected by #line, but is packaged here for convenience.
unsigned getColumn() const { return Col; }
@@ -274,7 +274,7 @@ public:
SourceLocation getIncludeLoc() const { return IncludeLoc; }
};
-
+
} // end namespace clang
namespace llvm {
@@ -286,20 +286,20 @@ namespace llvm {
return clang::FileID();
}
static inline clang::FileID getTombstoneKey() {
- return clang::FileID::getSentinel();
+ return clang::FileID::getSentinel();
}
-
+
static unsigned getHashValue(clang::FileID S) {
return S.getHashValue();
}
-
+
static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
return LHS == RHS;
}
-
+
static bool isPod() { return true; }
};
-
+
} // end namespace llvm
#endif
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index 249ca89f717d..7eb988f005ec 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -24,9 +24,9 @@
namespace llvm {
class MemoryBuffer;
}
-
+
namespace clang {
-
+
class SourceManager;
class FileManager;
class FileEntry;
@@ -46,7 +46,7 @@ namespace SrcMgr {
enum CharacteristicKind {
C_User, C_System, C_ExternCSystem
};
-
+
/// ContentCache - Once instance of this struct is kept for every file
/// loaded or used. This object owns the MemoryBuffer object.
class ContentCache {
@@ -54,17 +54,20 @@ namespace SrcMgr {
/// file. This is owned by the ContentCache object.
mutable const llvm::MemoryBuffer *Buffer;
+ /// The line and column at which we should truncate the file.
+ unsigned TruncateAtLine, TruncateAtColumn;
+
public:
/// Reference to the file entry. This reference does not own
/// the FileEntry object. It is possible for this to be NULL if
/// the ContentCache encapsulates an imaginary text buffer.
const FileEntry *Entry;
-
+
/// SourceLineCache - A bump pointer allocated array of offsets for each
/// source line. This is lazily computed. This is owned by the
/// SourceManager BumpPointerAllocator object.
unsigned *SourceLineCache;
-
+
/// NumLines - The number of lines in this ContentCache. This is only valid
/// if SourceLineCache is non-null.
unsigned NumLines;
@@ -76,44 +79,57 @@ namespace SrcMgr {
/// getBuffer - Returns the memory buffer for the associated content.
const llvm::MemoryBuffer *getBuffer() const;
-
+
/// getSize - Returns the size of the content encapsulated by this
/// ContentCache. This can be the size of the source file or the size of an
/// arbitrary scratch buffer. If the ContentCache encapsulates a source
/// file this size is retrieved from the file's FileEntry.
unsigned getSize() const;
-
+
/// getSizeBytesMapped - Returns the number of bytes actually mapped for
/// this ContentCache. This can be 0 if the MemBuffer was not actually
/// instantiated.
unsigned getSizeBytesMapped() const;
-
+
void setBuffer(const llvm::MemoryBuffer *B) {
assert(!Buffer && "MemoryBuffer already set.");
Buffer = B;
}
-
+
+ /// \brief Truncate this file at the given line and column.
+ ///
+ /// \param Line the line on which to truncate the current file (1-based).
+ /// \param Column the column at which to truncate the current file.
+ /// (1-based).
+ void truncateAt(unsigned Line, unsigned Column);
+
+ /// \brief Determines whether the file was artificially truncated with
+ /// truncateAt().
+ bool isTruncated() const { return TruncateAtLine && TruncateAtColumn; }
+
ContentCache(const FileEntry *Ent = 0)
- : Buffer(0), Entry(Ent), SourceLineCache(0), NumLines(0) {}
+ : Buffer(0), TruncateAtLine(0), TruncateAtColumn(0), Entry(Ent),
+ SourceLineCache(0), NumLines(0) {}
~ContentCache();
-
+
/// The copy ctor does not allow copies where source object has either
/// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory
/// is not transfered, so this is a logical error.
- ContentCache(const ContentCache &RHS) : Buffer(0), SourceLineCache(0) {
+ ContentCache(const ContentCache &RHS)
+ : Buffer(0), TruncateAtLine(0), TruncateAtColumn(0), SourceLineCache(0) {
Entry = RHS.Entry;
assert (RHS.Buffer == 0 && RHS.SourceLineCache == 0
&& "Passed ContentCache object cannot own a buffer.");
-
- NumLines = RHS.NumLines;
+
+ NumLines = RHS.NumLines;
}
-
+
private:
// Disable assignments.
- ContentCache &operator=(const ContentCache& RHS);
- };
+ ContentCache &operator=(const ContentCache& RHS);
+ };
/// FileInfo - Information about a FileID, basically just the logical file
/// that it represents and include stack information.
@@ -128,7 +144,7 @@ namespace SrcMgr {
/// IncludeLoc - The location of the #include that brought in this file.
/// This is an invalid SLOC for the main file (top of the #include chain).
unsigned IncludeLoc; // Really a SourceLocation
-
+
/// Data - This contains the ContentCache* and the bits indicating the
/// characteristic of the file and whether it has #line info, all bitmangled
/// together.
@@ -145,39 +161,39 @@ namespace SrcMgr {
X.Data |= (unsigned)FileCharacter;
return X;
}
-
+
SourceLocation getIncludeLoc() const {
return SourceLocation::getFromRawEncoding(IncludeLoc);
}
const ContentCache* getContentCache() const {
return reinterpret_cast<const ContentCache*>(Data & ~7UL);
}
-
+
/// getCharacteristic - Return whether this is a system header or not.
- CharacteristicKind getFileCharacteristic() const {
+ CharacteristicKind getFileCharacteristic() const {
return (CharacteristicKind)(Data & 3);
}
/// hasLineDirectives - Return true if this FileID has #line directives in
/// it.
bool hasLineDirectives() const { return (Data & 4) != 0; }
-
+
/// setHasLineDirectives - Set the flag that indicates that this FileID has
/// line table entries associated with it.
void setHasLineDirectives() {
Data |= 4;
}
};
-
+
/// InstantiationInfo - Each InstantiationInfo encodes the Instantiation
/// location - where the token was ultimately instantiated, and the
/// SpellingLoc - where the actual character data for the token came from.
class InstantiationInfo {
// Really these are all SourceLocations.
-
+
/// SpellingLoc - Where the spelling for the token can be found.
unsigned SpellingLoc;
-
+
/// InstantiationLocStart/InstantiationLocEnd - In a macro expansion, these
/// indicate the start and end of the instantiation. In object-like macros,
/// these will be the same. In a function-like macro instantiation, the
@@ -193,12 +209,12 @@ namespace SrcMgr {
SourceLocation getInstantiationLocEnd() const {
return SourceLocation::getFromRawEncoding(InstantiationLocEnd);
}
-
+
std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const {
return std::make_pair(getInstantiationLocStart(),
getInstantiationLocEnd());
}
-
+
/// get - Return a InstantiationInfo for an expansion. IL specifies
/// the instantiation location (where the macro is expanded), and SL
/// specifies the spelling location (where the characters from the token
@@ -213,7 +229,7 @@ namespace SrcMgr {
return X;
}
};
-
+
/// SLocEntry - This is a discriminated union of FileInfo and
/// InstantiationInfo. SourceManager keeps an array of these objects, and
/// they are uniquely identified by the FileID datatype.
@@ -225,10 +241,10 @@ namespace SrcMgr {
};
public:
unsigned getOffset() const { return Offset >> 1; }
-
+
bool isInstantiation() const { return Offset & 1; }
bool isFile() const { return !isInstantiation(); }
-
+
const FileInfo &getFile() const {
assert(isFile() && "Not a file SLocEntry!");
return File;
@@ -238,7 +254,7 @@ namespace SrcMgr {
assert(isInstantiation() && "Not an instantiation SLocEntry!");
return Instantiation;
}
-
+
static SLocEntry get(unsigned Offset, const FileInfo &FI) {
SLocEntry E;
E.Offset = Offset << 1;
@@ -277,18 +293,18 @@ public:
/// location specifies where it was expanded.
class SourceManager {
mutable llvm::BumpPtrAllocator ContentCacheAlloc;
-
+
/// FileInfos - Memoized information about all of the files tracked by this
/// SourceManager. This set allows us to merge ContentCache entries based
/// on their FileEntry*. All ContentCache objects will thus have unique,
- /// non-null, FileEntry pointers.
+ /// non-null, FileEntry pointers.
llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> FileInfos;
-
+
/// MemBufferInfos - Information about various memory buffers that we have
/// read in. All FileEntry* within the stored ContentCache objects are NULL,
/// as they do not refer to a file.
std::vector<SrcMgr::ContentCache*> MemBufferInfos;
-
+
/// SLocEntryTable - This is an array of SLocEntry's that we have created.
/// FileID is an index into this vector. This array is sorted by the offset.
std::vector<SrcMgr::SLocEntry> SLocEntryTable;
@@ -308,49 +324,55 @@ class SourceManager {
/// LastFileIDLookup records the last FileID looked up or created, because it
/// is very common to look up many tokens from the same file.
mutable FileID LastFileIDLookup;
-
+
/// LineTable - This holds information for #line directives. It is referenced
/// by indices from SLocEntryTable.
LineTableInfo *LineTable;
-
+
/// LastLineNo - These ivars serve as a cache used in the getLineNumber
/// method which is used to speedup getLineNumber calls to nearby locations.
mutable FileID LastLineNoFileIDQuery;
mutable SrcMgr::ContentCache *LastLineNoContentCache;
mutable unsigned LastLineNoFilePos;
mutable unsigned LastLineNoResult;
-
+
/// MainFileID - The file ID for the main source file of the translation unit.
FileID MainFileID;
// Statistics for -print-stats.
mutable unsigned NumLinearScans, NumBinaryProbes;
-
+
// Cache results for the isBeforeInTranslationUnit method.
mutable FileID LastLFIDForBeforeTUCheck;
mutable FileID LastRFIDForBeforeTUCheck;
mutable bool LastResForBeforeTUCheck;
+
+ // Keep track of the file/line/column that we should truncate.
+ const FileEntry *TruncateFile;
+ unsigned TruncateAtLine;
+ unsigned TruncateAtColumn;
// SourceManager doesn't support copy construction.
explicit SourceManager(const SourceManager&);
- void operator=(const SourceManager&);
+ void operator=(const SourceManager&);
public:
- SourceManager()
- : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
- NumBinaryProbes(0) {
+ SourceManager()
+ : ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
+ NumBinaryProbes(0), TruncateFile(0), TruncateAtLine(0),
+ TruncateAtColumn(0) {
clearIDTables();
}
~SourceManager();
-
+
void clearIDTables();
-
+
//===--------------------------------------------------------------------===//
// MainFileID creation and querying methods.
//===--------------------------------------------------------------------===//
/// getMainFileID - Returns the FileID of the main source file.
FileID getMainFileID() const { return MainFileID; }
-
+
/// createMainFileID - Create the FileID for the main source file.
FileID createMainFileID(const FileEntry *SourceFile,
SourceLocation IncludePos) {
@@ -358,15 +380,15 @@ public:
MainFileID = createFileID(SourceFile, IncludePos, SrcMgr::C_User);
return MainFileID;
}
-
+
//===--------------------------------------------------------------------===//
// Methods to create new FileID's and instantiations.
//===--------------------------------------------------------------------===//
-
+
/// createFileID - Create a new FileID that represents the specified file
/// being #included from the specified IncludePosition. This returns 0 on
/// error and translates NULL into standard input.
- /// PreallocateID should be non-zero to specify which a pre-allocated,
+ /// PreallocateID should be non-zero to specify which a pre-allocated,
/// lazily computed source location is being filled in by this operation.
FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
@@ -376,7 +398,7 @@ public:
if (IR == 0) return FileID(); // Error opening file?
return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset);
}
-
+
/// createFileIDForMemBuffer - Create a new FileID that represents the
/// specified memory buffer. This does no caching of the buffer and takes
/// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
@@ -386,7 +408,7 @@ public:
return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
SrcMgr::C_User, PreallocatedID, Offset);
}
-
+
/// createMainFileIDForMembuffer - Create the FileID for a memory buffer
/// that will represent the FileID for the main source. One example
/// of when this would be used is when the main source is read from STDIN.
@@ -405,31 +427,31 @@ public:
unsigned TokLength,
unsigned PreallocatedID = 0,
unsigned Offset = 0);
-
+
//===--------------------------------------------------------------------===//
// FileID manipulation methods.
//===--------------------------------------------------------------------===//
-
+
/// getBuffer - Return the buffer for the specified FileID.
///
const llvm::MemoryBuffer *getBuffer(FileID FID) const {
return getSLocEntry(FID).getFile().getContentCache()->getBuffer();
}
-
+
/// getFileEntryForID - Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
return getSLocEntry(FID).getFile().getContentCache()->Entry;
}
-
+
/// getBufferData - Return a pointer to the start and end of the source buffer
/// data for the specified FileID.
std::pair<const char*, const char*> getBufferData(FileID FID) const;
-
-
+
+
//===--------------------------------------------------------------------===//
// SourceLocation manipulation methods.
//===--------------------------------------------------------------------===//
-
+
/// getFileID - Return the FileID for a SourceLocation. This is a very
/// hot method that is used for all SourceManager queries that start with a
/// SourceLocation object. It is responsible for finding the entry in
@@ -437,14 +459,14 @@ public:
///
FileID getFileID(SourceLocation SpellingLoc) const {
unsigned SLocOffset = SpellingLoc.getOffset();
-
+
// If our one-entry cache covers this offset, just return it.
if (isOffsetInFileID(LastFileIDLookup, SLocOffset))
return LastFileIDLookup;
return getFileIDSlow(SLocOffset);
}
-
+
/// getLocForStartOfFile - Return the source location corresponding to the
/// first byte of the specified file.
SourceLocation getLocForStartOfFile(FileID FID) const {
@@ -453,7 +475,7 @@ public:
unsigned FileOffset = getSLocEntry(FID).getOffset();
return SourceLocation::getFileLoc(FileOffset);
}
-
+
/// getInstantiationLoc - Given a SourceLocation object, return the
/// instantiation location referenced by the ID.
SourceLocation getInstantiationLoc(SourceLocation Loc) const {
@@ -462,18 +484,18 @@ public:
if (Loc.isFileID()) return Loc;
return getInstantiationLocSlowCase(Loc);
}
-
+
/// getImmediateInstantiationRange - Loc is required to be an instantiation
/// location. Return the start/end of the instantiation information.
std::pair<SourceLocation,SourceLocation>
getImmediateInstantiationRange(SourceLocation Loc) const;
-
+
/// getInstantiationRange - Given a SourceLocation object, return the
/// range of tokens covered by the instantiation in the ultimate file.
std::pair<SourceLocation,SourceLocation>
getInstantiationRange(SourceLocation Loc) const;
-
-
+
+
/// getSpellingLoc - Given a SourceLocation object, return the spelling
/// location referenced by the ID. This is the place where the characters
/// that make up the lexed token can be found.
@@ -483,12 +505,12 @@ public:
if (Loc.isFileID()) return Loc;
return getSpellingLocSlowCase(Loc);
}
-
+
/// getImmediateSpellingLoc - Given a SourceLocation object, return the
/// spelling location referenced by the ID. This is the first level down
/// towards the place where the characters that make up the lexed token can be
/// found. This should not generally be used by clients.
- SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
+ SourceLocation getImmediateSpellingLoc(SourceLocation Loc) const;
/// getDecomposedLoc - Decompose the specified location into a raw FileID +
/// Offset pair. The first element is the FileID, the second is the
@@ -497,7 +519,7 @@ public:
FileID FID = getFileID(Loc);
return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset());
}
-
+
/// getDecomposedInstantiationLoc - Decompose the specified location into a
/// raw FileID + Offset pair. If the location is an instantiation record,
/// walk through it until we find the final location instantiated.
@@ -505,11 +527,11 @@ public:
getDecomposedInstantiationLoc(SourceLocation Loc) const {
FileID FID = getFileID(Loc);
const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
-
+
unsigned Offset = Loc.getOffset()-E->getOffset();
if (Loc.isFileID())
return std::make_pair(FID, Offset);
-
+
return getDecomposedInstantiationLocSlowCase(E, Offset);
}
@@ -520,29 +542,29 @@ public:
getDecomposedSpellingLoc(SourceLocation Loc) const {
FileID FID = getFileID(Loc);
const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
-
+
unsigned Offset = Loc.getOffset()-E->getOffset();
if (Loc.isFileID())
return std::make_pair(FID, Offset);
return getDecomposedSpellingLocSlowCase(E, Offset);
- }
-
+ }
+
/// getFileOffset - This method returns the offset from the start
/// of the file that the specified SourceLocation represents. This is not very
/// meaningful for a macro ID.
unsigned getFileOffset(SourceLocation SpellingLoc) const {
return getDecomposedLoc(SpellingLoc).second;
}
-
-
+
+
//===--------------------------------------------------------------------===//
// Queries about the code at a SourceLocation.
//===--------------------------------------------------------------------===//
-
+
/// getCharacterData - Return a pointer to the start of the specified location
/// in the appropriate spelling MemoryBuffer.
const char *getCharacterData(SourceLocation SL) const;
-
+
/// getColumnNumber - Return the column # for the specified file position.
/// This is significantly cheaper to compute than the line number. This
/// returns zero if the column number isn't known. This may only be called on
@@ -551,24 +573,24 @@ public:
unsigned getColumnNumber(FileID FID, unsigned FilePos) const;
unsigned getSpellingColumnNumber(SourceLocation Loc) const;
unsigned getInstantiationColumnNumber(SourceLocation Loc) const;
-
-
+
+
/// getLineNumber - Given a SourceLocation, return the spelling line number
/// for the position indicated. This requires building and caching a table of
/// line offsets for the MemoryBuffer, so this is not cheap: use only when
/// about to emit a diagnostic.
unsigned getLineNumber(FileID FID, unsigned FilePos) const;
-
+
unsigned getInstantiationLineNumber(SourceLocation Loc) const;
unsigned getSpellingLineNumber(SourceLocation Loc) const;
-
+
/// Return the filename or buffer identifier of the buffer the location is in.
/// Note that this name does not respect #line directives. Use getPresumedLoc
/// for normal clients.
const char *getBufferName(SourceLocation Loc) const;
-
+
/// getFileCharacteristic - return the file characteristic of the specified
- /// source location, indicating whether this is a normal file, a system
+ /// source location, indicating whether this is a normal file, a system
/// header, or an "implicit extern C" system header.
///
/// This state can be modified with flags on GNU linemarker directives like:
@@ -576,7 +598,7 @@ public:
/// which changes all source locations in the current file after that to be
/// considered to be from a system header.
SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const;
-
+
/// getPresumedLoc - This method returns the "presumed" location of a
/// SourceLocation specifies. A "presumed location" can be modified by #line
/// or GNU line marker directives. This provides a view on the data that a
@@ -585,44 +607,44 @@ public:
/// Note that a presumed location is always given as the instantiation point
/// of an instantiation location, not at the spelling location.
PresumedLoc getPresumedLoc(SourceLocation Loc) const;
-
+
/// isFromSameFile - Returns true if both SourceLocations correspond to
/// the same file.
bool isFromSameFile(SourceLocation Loc1, SourceLocation Loc2) const {
return getFileID(Loc1) == getFileID(Loc2);
}
-
+
/// isFromMainFile - Returns true if the file of provided SourceLocation is
/// the main file.
bool isFromMainFile(SourceLocation Loc) const {
return getFileID(Loc) == getMainFileID();
- }
-
+ }
+
/// isInSystemHeader - Returns if a SourceLocation is in a system header.
bool isInSystemHeader(SourceLocation Loc) const {
return getFileCharacteristic(Loc) != SrcMgr::C_User;
}
-
+
/// isInExternCSystemHeader - Returns if a SourceLocation is in an "extern C"
/// system header.
bool isInExternCSystemHeader(SourceLocation Loc) const {
return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem;
}
-
+
//===--------------------------------------------------------------------===//
// Line Table Manipulation Routines
//===--------------------------------------------------------------------===//
-
+
/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
- ///
+ ///
unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
-
+
/// AddLineNote - Add a line note to the line table for the FileID and offset
/// specified by Loc. If FilenameID is -1, it is considered to be
/// unspecified.
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID);
void AddLineNote(SourceLocation Loc, unsigned LineNo, int FilenameID,
- bool IsFileEntry, bool IsFileExit,
+ bool IsFileEntry, bool IsFileExit,
bool IsSystemHeader, bool IsExternCHeader);
/// \brief Determine if the source manager has a line table.
@@ -641,12 +663,18 @@ public:
/// be based upon the first inclusion.
SourceLocation getLocation(const FileEntry *SourceFile,
unsigned Line, unsigned Col) const;
-
+
/// \brief Determines the order of 2 source locations in the translation unit.
///
/// \returns true if LHS source location comes before RHS, false otherwise.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const;
+ /// \brief Truncate the given file at the specified line/column.
+ void truncateFileAt(const FileEntry *Entry, unsigned Line, unsigned Column);
+
+ /// \brief Determine whether this file was truncated.
+ bool isTruncatedFile(FileID FID) const;
+
// Iterators over FileInfos.
typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>
::const_iterator fileinfo_iterator;
@@ -657,22 +685,22 @@ public:
///
void PrintStats() const;
- // Iteration over the source location entry table.
+ // Iteration over the source location entry table.
typedef std::vector<SrcMgr::SLocEntry>::const_iterator sloc_entry_iterator;
- sloc_entry_iterator sloc_entry_begin() const {
- return SLocEntryTable.begin();
+ sloc_entry_iterator sloc_entry_begin() const {
+ return SLocEntryTable.begin();
}
- sloc_entry_iterator sloc_entry_end() const {
- return SLocEntryTable.end();
+ sloc_entry_iterator sloc_entry_end() const {
+ return SLocEntryTable.end();
}
unsigned sloc_entry_size() const { return SLocEntryTable.size(); }
const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const {
assert(FID.ID < SLocEntryTable.size() && "Invalid id");
- if (ExternalSLocEntries &&
+ if (ExternalSLocEntries &&
FID.ID < SLocEntryLoaded.size() &&
!SLocEntryLoaded[FID.ID])
ExternalSLocEntries->ReadSLocEntry(FID.ID);
@@ -698,14 +726,14 @@ private:
const SrcMgr::SLocEntry &Entry = getSLocEntry(FID);
// If the entry is after the offset, it can't contain it.
if (SLocOffset < Entry.getOffset()) return false;
-
+
// If this is the last entry than it does. Otherwise, the entry after it
// has to not include it.
if (FID.ID+1 == SLocEntryTable.size()) return true;
return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset();
}
-
+
/// createFileID - Create a new fileID for the specified ContentCache and
/// include position. This works regardless of whether the ContentCache
/// corresponds to a file or some other input source.
@@ -714,15 +742,15 @@ private:
SrcMgr::CharacteristicKind DirCharacter,
unsigned PreallocatedID = 0,
unsigned Offset = 0);
-
+
const SrcMgr::ContentCache *
getOrCreateContentCache(const FileEntry *SourceFile);
/// createMemBufferContentCache - Create a new ContentCache for the specified
/// memory buffer.
- const SrcMgr::ContentCache*
+ const SrcMgr::ContentCache*
createMemBufferContentCache(const llvm::MemoryBuffer *Buf);
-
+
FileID getFileIDSlow(unsigned SLocOffset) const;
SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const;
@@ -730,7 +758,7 @@ private:
std::pair<FileID, unsigned>
getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E,
- unsigned Offset) const;
+ unsigned Offset) const;
std::pair<FileID, unsigned>
getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
unsigned Offset) const;
diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h
index 0bcb68e4601d..258989cb7787 100644
--- a/include/clang/Basic/SourceManagerInternals.h
+++ b/include/clang/Basic/SourceManagerInternals.h
@@ -28,22 +28,22 @@ namespace clang {
struct LineEntry {
/// FileOffset - The offset in this file that the line entry occurs at.
unsigned FileOffset;
-
+
/// LineNo - The presumed line number of this line entry: #line 4.
unsigned LineNo;
-
+
/// FilenameID - The ID of the filename identified by this line entry:
/// #line 4 "foo.c". This is -1 if not specified.
int FilenameID;
-
- /// Flags - Set the 0 if no flags, 1 if a system header,
+
+ /// Flags - Set the 0 if no flags, 1 if a system header,
SrcMgr::CharacteristicKind FileKind;
-
+
/// IncludeOffset - This is the offset of the virtual include stack location,
/// which is manipulated by GNU linemarker directives. If this is 0 then
/// there is no virtual #includer.
unsigned IncludeOffset;
-
+
static LineEntry get(unsigned Offs, unsigned Line, int Filename,
SrcMgr::CharacteristicKind FileKind,
unsigned IncludeOffset) {
@@ -70,7 +70,7 @@ inline bool operator<(const LineEntry &E, unsigned Offset) {
inline bool operator<(unsigned Offset, const LineEntry &E) {
return Offset < E.FileOffset;
}
-
+
/// LineTableInfo - This class is used to hold and unique data used to
/// represent #line information.
class LineTableInfo {
@@ -81,22 +81,22 @@ class LineTableInfo {
/// to string.
llvm::StringMap<unsigned, llvm::BumpPtrAllocator> FilenameIDs;
std::vector<llvm::StringMapEntry<unsigned>*> FilenamesByID;
-
+
/// LineEntries - This is a map from FileIDs to a list of line entries (sorted
/// by the offset they occur in the file.
std::map<unsigned, std::vector<LineEntry> > LineEntries;
public:
LineTableInfo() {
}
-
+
void clear() {
FilenameIDs.clear();
FilenamesByID.clear();
LineEntries.clear();
}
-
+
~LineTableInfo() {}
-
+
unsigned getLineTableFilenameID(const char *Ptr, unsigned Len);
const char *getFilename(unsigned ID) const {
assert(ID < FilenamesByID.size() && "Invalid FilenameID");
@@ -110,7 +110,7 @@ public:
unsigned LineNo, int FilenameID,
unsigned EntryExit, SrcMgr::CharacteristicKind FileKind);
-
+
/// FindNearestLineEntry - Find the line entry nearest to FID that is before
/// it. If there is no line entry before Offset in FID, return null.
const LineEntry *FindNearestLineEntry(unsigned FID, unsigned Offset);
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 537d553bc2d1..a1e0a17c882e 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -16,31 +16,37 @@
// FIXME: Daniel isn't smart enough to use a prototype for this.
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <vector>
#include <string>
-namespace llvm { struct fltSemantics; }
+namespace llvm {
+struct fltSemantics;
+class StringRef;
+}
namespace clang {
class Diagnostic;
+class SourceLocation;
class SourceManager;
class LangOptions;
-
namespace Builtin { struct Info; }
-
+
/// TargetInfo - This class exposes information about the current target.
///
class TargetInfo {
- std::string Triple;
+ llvm::Triple Triple;
protected:
// Target values set by the ctor of the actual target implementation. Default
// values are specified by the TargetInfo constructor.
bool TLSSupported;
unsigned char PointerWidth, PointerAlign;
unsigned char WCharWidth, WCharAlign;
+ unsigned char Char16Width, Char16Align;
+ unsigned char Char32Width, Char32Align;
unsigned char IntWidth, IntAlign;
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
@@ -55,8 +61,8 @@ protected:
// TargetInfo Constructor. Default initializes all fields.
TargetInfo(const std::string &T);
-
-public:
+
+public:
/// CreateTargetInfo - Return the target info object for the specified target
/// triple.
static TargetInfo* CreateTargetInfo(const std::string &Triple);
@@ -77,7 +83,7 @@ public:
};
protected:
IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
- Int64Type;
+ Char16Type, Char32Type, Int64Type;
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@@ -87,6 +93,8 @@ public:
}
IntType getIntPtrType() const { return IntPtrType; }
IntType getWCharType() const { return WCharType; }
+ IntType getChar16Type() const { return Char16Type; }
+ IntType getChar32Type() const { return Char32Type; }
IntType getInt64Type() const { return Int64Type; }
/// getPointerWidth - Return the width of pointers on this target, for the
@@ -97,44 +105,50 @@ public:
uint64_t getPointerAlign(unsigned AddrSpace) const {
return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
}
-
+
/// getBoolWidth/Align - Return the size of '_Bool' and C++ 'bool' for this
/// target, in bits.
unsigned getBoolWidth(bool isWide = false) const { return 8; } // FIXME
unsigned getBoolAlign(bool isWide = false) const { return 8; } // FIXME
-
- unsigned getCharWidth(bool isWide = false) const {
- return isWide ? getWCharWidth() : 8; // FIXME
- }
- unsigned getCharAlign(bool isWide = false) const {
- return isWide ? getWCharAlign() : 8; // FIXME
- }
-
+
+ unsigned getCharWidth() const { return 8; } // FIXME
+ unsigned getCharAlign() const { return 8; } // FIXME
+
/// getShortWidth/Align - Return the size of 'signed short' and
- /// 'unsigned short' for this target, in bits.
+ /// 'unsigned short' for this target, in bits.
unsigned getShortWidth() const { return 16; } // FIXME
unsigned getShortAlign() const { return 16; } // FIXME
-
+
/// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
/// this target, in bits.
unsigned getIntWidth() const { return IntWidth; }
unsigned getIntAlign() const { return IntAlign; }
-
+
/// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
/// for this target, in bits.
unsigned getLongWidth() const { return LongWidth; }
unsigned getLongAlign() const { return LongAlign; }
-
+
/// getLongLongWidth/Align - Return the size of 'signed long long' and
/// 'unsigned long long' for this target, in bits.
unsigned getLongLongWidth() const { return LongLongWidth; }
unsigned getLongLongAlign() const { return LongLongAlign; }
-
- /// getWcharWidth/Align - Return the size of 'wchar_t' for this target, in
+
+ /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
/// bits.
unsigned getWCharWidth() const { return WCharWidth; }
unsigned getWCharAlign() const { return WCharAlign; }
+ /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
+ /// bits.
+ unsigned getChar16Width() const { return Char16Width; }
+ unsigned getChar16Align() const { return Char16Align; }
+
+ /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
+ /// bits.
+ unsigned getChar32Width() const { return Char32Width; }
+ unsigned getChar32Align() const { return Char32Align; }
+
/// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
unsigned getFloatWidth() const { return FloatWidth; }
unsigned getFloatAlign() const { return FloatAlign; }
@@ -152,13 +166,13 @@ public:
const llvm::fltSemantics &getLongDoubleFormat() const {
return *LongDoubleFormat;
}
-
+
/// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this
- /// target, in bits.
+ /// target, in bits.
unsigned getIntMaxTWidth() const {
return IntMaxTWidth;
}
-
+
/// getUserLabelPrefix - This returns the default value of the
/// __USER_LABEL_PREFIX__ macro, which is the prefix given to user symbols by
/// default. On most platforms this is "_", but it is "" on some, and "." on
@@ -166,22 +180,22 @@ public:
const char *getUserLabelPrefix() const {
return UserLabelPrefix;
}
-
+
/// getTypeName - Return the user string for the specified integer type enum.
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);
-
+
///===---- Other target property query methods --------------------------===//
-
+
/// getTargetDefines - Appends the target-specific #define values for this
/// target set to the specified buffer.
virtual void getTargetDefines(const LangOptions &Opts,
std::vector<char> &DefineBuffer) const = 0;
-
+
/// getTargetBuiltins - Return information about target-specific builtins for
/// the current primary target, and info about which builtins are non-portable
/// across the current set of primary and secondary targets.
- virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const = 0;
/// getVAListDeclaration - Return the declaration to use for
@@ -196,7 +210,7 @@ public:
// getNormalizedGCCRegisterName - Returns the "normalized" GCC register name.
// For example, on x86 it will return "ax" when "eax" is passed in.
const char *getNormalizedGCCRegisterName(const char *Name) const;
-
+
struct ConstraintInfo {
enum {
CI_None = 0x00,
@@ -207,7 +221,7 @@ public:
};
unsigned Flags;
int TiedOperand;
-
+
std::string ConstraintStr; // constraint: "=rm"
std::string Name; // Operand name: [foo] with no []'s.
public:
@@ -221,11 +235,11 @@ public:
bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
-
+
/// hasMatchingInput - Return true if this output operand has a matching
/// (tied) input operand.
bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
-
+
/// hasTiedOperand() - Return true if this input operand is a matching
/// constraint that ties it to an output operand. If this returns true,
/// then getTiedOperand will indicate which output operand this is tied to.
@@ -234,12 +248,12 @@ public:
assert(hasTiedOperand() && "Has no tied operand!");
return (unsigned)TiedOperand;
}
-
+
void setIsReadWrite() { Flags |= CI_ReadWrite; }
void setAllowsMemory() { Flags |= CI_AllowsMemory; }
void setAllowsRegister() { Flags |= CI_AllowsRegister; }
void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
-
+
/// setTiedOperand - Indicate that this is an input operand that is tied to
/// the specified output operand. Copy over the various constraint
/// information from the output.
@@ -261,24 +275,20 @@ public:
bool resolveSymbolicName(const char *&Name,
ConstraintInfo *OutputConstraints,
unsigned NumOutputs, unsigned &Index) const;
-
+
virtual std::string convertConstraint(const char Constraint) const {
return std::string(1, Constraint);
}
-
+
// Returns a string of target-specific clobbers, in LLVM format.
virtual const char *getClobbers() const = 0;
-
- /// getTargetPrefix - Return the target prefix used for identifying
- /// llvm intrinsics.
- virtual const char *getTargetPrefix() const = 0;
-
- /// getTargetTriple - Return the target triple of the primary target.
- const char *getTargetTriple() const {
- return Triple.c_str();
+
+ /// getTriple - Return the target triple of the primary target.
+ const llvm::Triple &getTriple() const {
+ return Triple;
}
-
+
const char *getTargetDescription() const {
return DescriptionString;
}
@@ -290,55 +300,56 @@ public:
virtual bool useGlobalsForAutomaticVariables() const { return false; }
- /// getStringSymbolPrefix - Get the default symbol prefix to
- /// use for string literals.
- virtual const char *getStringSymbolPrefix(bool IsConstant) const {
- return ".str";
- }
-
- /// getCFStringSymbolPrefix - Get the default symbol prefix
- /// to use for CFString literals.
- virtual const char *getCFStringSymbolPrefix() const {
- return "";
- }
-
- /// getUnicodeStringSymbolPrefix - Get the default symbol prefix to
- /// use for string literals.
- virtual const char *getUnicodeStringSymbolPrefix() const {
- return ".str";
- }
-
/// getUnicodeStringSection - Return the section to use for unicode
/// string literals, or 0 if no special section is used.
- virtual const char *getUnicodeStringSection() const {
+ virtual const char *getUnicodeStringSection() const {
return 0;
}
/// getCFStringSection - Return the section to use for CFString
/// literals, or 0 if no special section is used.
- virtual const char *getCFStringSection() const {
+ virtual const char *getCFStringSection() const {
return "__DATA,__cfstring";
}
- /// getCFStringDataSection - Return the section to use for the
- /// constant string data associated with a CFString literal, or 0 if
- /// no special section is used.
- virtual const char *getCFStringDataSection() const {
- return "__TEXT,__cstring,cstring_literals";
+ /// isValidSectionSpecifier - This is an optional hook that targets can
+ /// implement to perform semantic checking on attribute((section("foo")))
+ /// specifiers. In this case, "foo" is passed in to be checked. If the
+ /// section specifier is invalid, the backend should return a non-empty string
+ /// that indicates the problem.
+ ///
+ /// This hook is a simple quality of implementation feature to catch errors
+ /// and give good diagnostics in cases when the assembler or code generator
+ /// would otherwise reject the section specifier.
+ ///
+ virtual std::string isValidSectionSpecifier(const llvm::StringRef &SR) const {
+ return "";
}
/// getDefaultLangOptions - Allow the target to specify default settings for
/// various language options. These may be overridden by command line
- /// options.
+ /// options.
virtual void getDefaultLangOptions(LangOptions &Opts) {}
/// getDefaultFeatures - Get the default set of target features for
/// the \args CPU; this should include all legal feature strings on
/// the target.
- virtual void getDefaultFeatures(const std::string &CPU,
+ virtual void getDefaultFeatures(const std::string &CPU,
llvm::StringMap<bool> &Features) const {
}
+ /// getABI - Get the ABI in use.
+ virtual const char *getABI() const {
+ return "";
+ }
+
+ /// setABI - Use the specific ABI.
+ ///
+ /// \return - False on error (invalid ABI name).
+ virtual bool setABI(const std::string &Name) {
+ return false;
+ }
+
/// setFeatureEnabled - Enable or disable a specific target feature,
/// the feature name must be valid.
///
@@ -359,10 +370,17 @@ public:
return RegParmMax;
}
- // isTLSSupported - Whether the target supports thread-local storage
- unsigned isTLSSupported() const {
+ /// isTLSSupported - Whether the target supports thread-local storage.
+ bool isTLSSupported() const {
return TLSSupported;
}
+
+ /// getEHDataRegisterNumber - Return the register number that
+ /// __builtin_eh_return_regno would return with the specified argument.
+ virtual int getEHDataRegisterNumber(unsigned RegNo) const {
+ return -1;
+ }
+
protected:
virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
@@ -374,11 +392,11 @@ protected:
virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
return PtrDiffType;
}
- virtual void getGCCRegNames(const char * const *&Names,
+ virtual void getGCCRegNames(const char * const *&Names,
unsigned &NumNames) const = 0;
- virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
unsigned &NumAliases) const = 0;
- virtual bool validateAsmConstraint(const char *&Name,
+ virtual bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &info) const= 0;
};
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index e711996cf26d..239712c08caf 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -92,6 +92,7 @@ PPKEYWORD(unassert)
TOK(unknown) // Not a token.
TOK(eof) // End of file.
TOK(eom) // End of macro (end of line inside a macro).
+TOK(code_completion) // Code completion marker
// C99 6.4.9: Comments.
TOK(comment) // Comment (only in -E -C[C] mode)
diff --git a/include/clang/Basic/TokenKinds.h b/include/clang/Basic/TokenKinds.h
index 62a9e428bf21..85dc0671de62 100644
--- a/include/clang/Basic/TokenKinds.h
+++ b/include/clang/Basic/TokenKinds.h
@@ -29,7 +29,7 @@ enum TokenKind {
/// PPKeywordKind - This provides a namespace for preprocessor keywords which
/// start with a '#' at the beginning of the line.
enum PPKeywordKind {
-#define PPKEYWORD(X) pp_##X,
+#define PPKEYWORD(X) pp_##X,
#include "clang/Basic/TokenKinds.def"
NUM_PP_KEYWORDS
};
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index f0e1aa7db233..120d5a4210d0 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -7,7 +7,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This header defines version macros for Clang.
+// This header defines version macros and version-related utility functions
+// for Clang.
//
//===----------------------------------------------------------------------===//
@@ -17,12 +18,25 @@
/// \brief Clang major version
#define CLANG_VERSION_MAJOR 1
+// FIXME: Updates to this file must also update CMakeLists.txt and VER.
/// \brief Clang minor version
-#define CLANG_VERSION_MINOR 0
+#define CLANG_VERSION_MINOR 1
+
+/// \brief Clang patchlevel version
+// #define CLANG_VERSION_PATCHLEVEL 1
/// \brief Helper macro for CLANG_VERSION_STRING.
#define CLANG_MAKE_VERSION_STRING2(X) #X
+#ifdef CLANG_VERSION_PATCHLEVEL
+/// \brief Helper macro for CLANG_VERSION_STRING.
+#define CLANG_MAKE_VERSION_STRING(X,Y,Z) CLANG_MAKE_VERSION_STRING2(X.Y.Z)
+
+/// \brief A string that describes the Clang version number, e.g.,
+/// "1.0".
+#define CLANG_VERSION_STRING \
+ CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR,CLANG_VERSION_PATCHLEVEL)
+#else
/// \brief Helper macro for CLANG_VERSION_STRING.
#define CLANG_MAKE_VERSION_STRING(X,Y) CLANG_MAKE_VERSION_STRING2(X.Y)
@@ -30,6 +44,16 @@
/// "1.0".
#define CLANG_VERSION_STRING \
CLANG_MAKE_VERSION_STRING(CLANG_VERSION_MAJOR,CLANG_VERSION_MINOR)
-
+#endif
+
+namespace clang {
+ /// \brief Retrieves the Subversion path that identifies the particular
+ /// Clang branch, tag, or trunk from which this Clang was built.
+ const char *getClangSubversionPath();
+
+ /// \brief Retrieves the Subversion revision number from which this Clang
+ /// was built.
+ unsigned getClangSubversionRevision();
+}
#endif // LLVM_CLANG_BASIC_VERSION_H