diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-14 18:03:49 +0000 |
commit | 4c8b24812ddcd1dedaca343a6d4e76f91f398981 (patch) | |
tree | 137ebebcae16fb0ce7ab4af456992bbd8d22fced /include/clang/Basic | |
parent | 5362a71c02e7d448a8ce98cf00c47e353fba5d04 (diff) | |
download | src-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')
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 ¤tMappings = 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 |