diff options
Diffstat (limited to 'include/clang/Basic')
35 files changed, 2317 insertions, 1169 deletions
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index e64dc6a2ade09..2a4ba5c6c73ce 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -54,7 +54,9 @@ class ExprArgument<string name> : Argument<name>; class FunctionArgument<string name> : Argument<name>; class TypeArgument<string name> : Argument<name>; class UnsignedArgument<string name> : Argument<name>; +class SourceLocArgument<string name> : Argument<name>; class VariadicUnsignedArgument<string name> : Argument<name>; +class VariadicExprArgument<string name> : Argument<name>; // A version of the form major.minor[.subminor]. class VersionArgument<string name> : Argument<name>; @@ -89,7 +91,9 @@ class Attr { // The attribute will not be permitted in C++0x attribute-specifiers if // this is empty; the empty string can be used as a namespace. list<string> Namespaces = []; - // Any additional text that should be included verbatim in the class. + // Set to true for attributes with arguments which require delayed parsing. + bit LateParsed = 0; + // Any additional text that should be included verbatim in the class. code AdditionalMembers = [{}]; } @@ -110,7 +114,7 @@ def Alias : InheritableAttr { } def Aligned : InheritableAttr { - let Spellings = ["align", "aligned"]; + let Spellings = ["aligned"]; let Subjects = [NonBitField, NormalVar, Tag]; let Args = [AlignedArgument<"Alignment">]; let Namespaces = ["", "std"]; @@ -128,7 +132,7 @@ def AnalyzerNoReturn : InheritableAttr { let Spellings = ["analyzer_noreturn"]; } -def Annotate : InheritableAttr { +def Annotate : InheritableParamAttr { let Spellings = ["annotate"]; let Args = [StringArgument<"Annotation">]; } @@ -167,6 +171,23 @@ def CDecl : InheritableAttr { let Spellings = ["cdecl", "__cdecl"]; } +// cf_audited_transfer indicates that the given function has been +// audited and has been marked with the appropriate cf_consumed and +// cf_returns_retained attributes. It is generally applied by +// '#pragma clang arc_cf_code_audited' rather than explicitly. +def CFAuditedTransfer : InheritableAttr { + let Spellings = ["cf_audited_transfer"]; + let Subjects = [Function]; +} + +// cf_unknown_transfer is an explicit opt-out of cf_audited_transfer. +// It indicates that the function has unknown or unautomatable +// transfer semantics. +def CFUnknownTransfer : InheritableAttr { + let Spellings = ["cf_unknown_transfer"]; + let Subjects = [Function]; +} + def CFReturnsRetained : InheritableAttr { let Spellings = ["cf_returns_retained"]; let Subjects = [ObjCMethod, Function]; @@ -284,7 +305,7 @@ def IBOutlet : InheritableAttr { def IBOutletCollection : InheritableAttr { let Spellings = ["iboutletcollection"]; - let Args = [TypeArgument<"InterFace">]; + let Args = [TypeArgument<"Interface">, SourceLocArgument<"InterfaceLoc">]; } def Malloc : InheritableAttr { @@ -317,6 +338,10 @@ def Naked : InheritableAttr { let Spellings = ["naked"]; } +def ReturnsTwice : InheritableAttr { + let Spellings = ["returns_twice"]; +} + def NoCommon : InheritableAttr { let Spellings = ["nocommon"]; } @@ -358,6 +383,12 @@ def NoThrow : InheritableAttr { let Spellings = ["nothrow"]; } +def NSBridged : InheritableAttr { + let Spellings = ["ns_bridged"]; + let Subjects = [Record]; + let Args = [IdentifierArgument<"BridgedType">]; +} + def NSReturnsRetained : InheritableAttr { let Spellings = ["ns_returns_retained"]; let Subjects = [ObjCMethod, Function]; @@ -405,6 +436,11 @@ def ObjCPreciseLifetime : Attr { let Subjects = [Var]; } +def ObjCReturnsInnerPointer : Attr { + let Spellings = ["objc_returns_inner_pointer"]; + let Subjects = [ObjCMethod]; +} + def Overloadable : Attr { let Spellings = ["overloadable"]; } @@ -533,3 +569,108 @@ def WeakRef : InheritableAttr { def X86ForceAlignArgPointer : InheritableAttr { let Spellings = []; } + + +// C/C++ Thread safety attributes (e.g. for deadlock, data race checking) + +def GuardedVar : InheritableAttr { + let Spellings = ["guarded_var"]; +} + +def PtGuardedVar : InheritableAttr { + let Spellings = ["pt_guarded_var"]; +} + +def Lockable : InheritableAttr { + let Spellings = ["lockable"]; +} + +def ScopedLockable : InheritableAttr { + let Spellings = ["scoped_lockable"]; +} + +def NoThreadSafetyAnalysis : InheritableAttr { + let Spellings = ["no_thread_safety_analysis"]; +} + +def GuardedBy : InheritableAttr { + let Spellings = ["guarded_by"]; + let Args = [ExprArgument<"Arg">]; + let LateParsed = 1; +} + +def PtGuardedBy : InheritableAttr { + let Spellings = ["pt_guarded_by"]; + let Args = [ExprArgument<"Arg">]; + let LateParsed = 1; +} + +def AcquiredAfter : InheritableAttr { + let Spellings = ["acquired_after"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def AcquiredBefore : InheritableAttr { + let Spellings = ["acquired_before"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def ExclusiveLockFunction : InheritableAttr { + let Spellings = ["exclusive_lock_function"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def SharedLockFunction : InheritableAttr { + let Spellings = ["shared_lock_function"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +// The first argument is an integer or boolean value specifying the return value +// of a successful lock acquisition. +def ExclusiveTrylockFunction : InheritableAttr { + let Spellings = ["exclusive_trylock_function"]; + let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +// The first argument is an integer or boolean value specifying the return value +// of a successful lock acquisition. +def SharedTrylockFunction : InheritableAttr { + let Spellings = ["shared_trylock_function"]; + let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def UnlockFunction : InheritableAttr { + let Spellings = ["unlock_function"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def LockReturned : InheritableAttr { + let Spellings = ["lock_returned"]; + let Args = [ExprArgument<"Arg">]; + let LateParsed = 1; +} + +def LocksExcluded : InheritableAttr { + let Spellings = ["locks_excluded"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def ExclusiveLocksRequired : InheritableAttr { + let Spellings = ["exclusive_locks_required"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} + +def SharedLocksRequired : InheritableAttr { + let Spellings = ["shared_locks_required"]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; +} diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index a3cc6156238e7..e5690c1233939 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -35,6 +35,7 @@ // A -> "reference" to __builtin_va_list // V -> Vector, following num elements and a base type. // X -> _Complex, followed by the base type. +// Y -> ptrdiff_t // P -> FILE // J -> jmp_buf // SJ -> sigjmp_buf @@ -76,6 +77,7 @@ // in that it accepts its arguments as a va_list rather than // through an ellipsis // e -> const, but only when -fmath-errno=0 +// j -> returns_twice (like setjmp) // FIXME: gcc has nonnull #if defined(BUILTIN) && !defined(LIBBUILTIN) @@ -96,9 +98,9 @@ BUILTIN(__builtin_fabsl, "LdLd", "ncF") BUILTIN(__builtin_fmod , "ddd" , "Fnc") BUILTIN(__builtin_fmodf, "fff" , "Fnc") BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc") -BUILTIN(__builtin_frexp , "ddi*" , "Fnc") -BUILTIN(__builtin_frexpf, "ffi*" , "Fnc") -BUILTIN(__builtin_frexpl, "LdLdi*", "Fnc") +BUILTIN(__builtin_frexp , "ddi*" , "Fn") +BUILTIN(__builtin_frexpf, "ffi*" , "Fn") +BUILTIN(__builtin_frexpl, "LdLdi*", "Fn") BUILTIN(__builtin_huge_val, "d", "nc") BUILTIN(__builtin_huge_valf, "f", "nc") BUILTIN(__builtin_huge_vall, "Ld", "nc") @@ -108,9 +110,9 @@ BUILTIN(__builtin_infl , "Ld" , "nc") BUILTIN(__builtin_ldexp , "ddi" , "Fnc") BUILTIN(__builtin_ldexpf, "ffi" , "Fnc") BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc") -BUILTIN(__builtin_modf , "ddd*" , "Fnc") -BUILTIN(__builtin_modff, "fff*" , "Fnc") -BUILTIN(__builtin_modfl, "LdLdLd*", "Fnc") +BUILTIN(__builtin_modf , "ddd*" , "Fn") +BUILTIN(__builtin_modff, "fff*" , "Fn") +BUILTIN(__builtin_modfl, "LdLdLd*", "Fn") BUILTIN(__builtin_nan, "dcC*" , "ncF") BUILTIN(__builtin_nanf, "fcC*" , "ncF") BUILTIN(__builtin_nanl, "LdcC*", "ncF") @@ -233,9 +235,9 @@ BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc") BUILTIN(__builtin_remainder , "ddd", "Fnc") BUILTIN(__builtin_remainderf, "fff", "Fnc") BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc") -BUILTIN(__builtin_remquo , "dddi*", "Fnc") -BUILTIN(__builtin_remquof, "fffi*", "Fnc") -BUILTIN(__builtin_remquol, "LdLdLdi*", "Fnc") +BUILTIN(__builtin_remquo , "dddi*", "Fn") +BUILTIN(__builtin_remquof, "fffi*", "Fn") +BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") BUILTIN(__builtin_rint , "dd", "Fnc") BUILTIN(__builtin_rintf, "ff", "Fnc") BUILTIN(__builtin_rintl, "LdLd", "Fnc") @@ -388,7 +390,7 @@ BUILTIN(__builtin_constant_p, "i.", "nct") BUILTIN(__builtin_classify_type, "i.", "nct") BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc") BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc") -BUILTIN(__builtin_va_start, "vA.", "n") +BUILTIN(__builtin_va_start, "vA.", "nt") BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") BUILTIN(__builtin_stdarg_start, "vA.", "n") @@ -426,7 +428,7 @@ BUILTIN(__builtin_return_address, "v*IUi", "n") BUILTIN(__builtin_extract_return_addr, "v*v*", "n") BUILTIN(__builtin_frame_address, "v*IUi", "n") BUILTIN(__builtin_flt_rounds, "i", "nc") -BUILTIN(__builtin_setjmp, "iv**", "") +BUILTIN(__builtin_setjmp, "iv**", "j") BUILTIN(__builtin_longjmp, "vv**i", "r") BUILTIN(__builtin_unwind_init, "v", "") BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc") @@ -584,12 +586,21 @@ BUILTIN(__sync_swap_4, "iiD*i.", "n") BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "n") BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "n") - +BUILTIN(__atomic_load, "v.", "t") +BUILTIN(__atomic_store, "v.", "t") +BUILTIN(__atomic_exchange, "v.", "t") +BUILTIN(__atomic_compare_exchange_strong, "v.", "t") +BUILTIN(__atomic_compare_exchange_weak, "v.", "t") +BUILTIN(__atomic_fetch_add, "v.", "t") +BUILTIN(__atomic_fetch_sub, "v.", "t") +BUILTIN(__atomic_fetch_and, "v.", "t") +BUILTIN(__atomic_fetch_or, "v.", "t") +BUILTIN(__atomic_fetch_xor, "v.", "t") +BUILTIN(__atomic_thread_fence, "vi", "n") +BUILTIN(__atomic_signal_fence, "vi", "n") // Non-overloaded atomic builtins. BUILTIN(__sync_synchronize, "v.", "n") -// LLVM instruction builtin [Clang extension]. -BUILTIN(__builtin_llvm_memory_barrier,"vbbbbb", "n") // GCC does not support these, they are a Clang extension. BUILTIN(__sync_fetch_and_min, "iiD*i", "n") BUILTIN(__sync_fetch_and_max, "iiD*i", "n") @@ -661,9 +672,26 @@ LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_LANGUAGES) LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_LANGUAGES) // POSIX unistd.h LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_LANGUAGES) +LIBBUILTIN(vfork, "iJ", "fj", "unistd.h", ALL_LANGUAGES) // POSIX setjmp.h + +// In some systems setjmp is a macro that expands to _setjmp. We undefine +// it here to avoid having two identical LIBBUILTIN entries. +#undef setjmp +LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(__sigsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(sigsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) +LIBBUILTIN(getcontext, "iJ", "fj", "setjmp.h", ALL_LANGUAGES) + LIBBUILTIN(_longjmp, "vJi", "fr", "setjmp.h", ALL_LANGUAGES) LIBBUILTIN(siglongjmp, "vSJi", "fr", "setjmp.h", ALL_LANGUAGES) +// non-standard but very common +LIBBUILTIN(strlcpy, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) +LIBBUILTIN(strlcat, "zc*cC*z", "f", "string.h", ALL_LANGUAGES) // id objc_msgSend(id, SEL, ...) LIBBUILTIN(objc_msgSend, "GGH.", "f", "objc/message.h", OBJC_LANG) @@ -687,8 +715,7 @@ LIBBUILTIN(objc_read_weak, "GG*", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_weak(id value, id *location) LIBBUILTIN(objc_assign_weak, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_ivar(id value, id dest, ptrdiff_t offset) -// FIXME. Darwin has ptrdiff_t typedef'ed to int. -LIBBUILTIN(objc_assign_ivar, "GGGi", "f", "/objc/objc-auto.h", OBJC_LANG) +LIBBUILTIN(objc_assign_ivar, "GGGY", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_global(id val, id *dest) LIBBUILTIN(objc_assign_global, "GGG*", "f", "/objc/objc-auto.h", OBJC_LANG) // id objc_assign_strongCast(id val, id *dest @@ -738,5 +765,8 @@ LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES) LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES) // FIXME: Also declare NSConcreteGlobalBlock and NSConcreteStackBlock. +// Annotation function +BUILTIN(__builtin_annotation, "UiUicC*", "nc") + #undef BUILTIN #undef LIBBUILTIN diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index 7469e144c1500..5afa02010040c 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -15,16 +15,13 @@ #ifndef LLVM_CLANG_BASIC_BUILTINS_H #define LLVM_CLANG_BASIC_BUILTINS_H +#include "clang/Basic/LLVM.h" #include <cstring> // VC++ defines 'alloca' as an object-like macro, which interferes with our // builtins. #undef alloca -namespace llvm { - template <typename T> class SmallVectorImpl; -} - namespace clang { class TargetInfo; class IdentifierTable; @@ -65,15 +62,18 @@ class Context { const Info *TSRecords; unsigned NumTSRecords; public: - Context(const TargetInfo &Target); + Context(); + /// \brief Perform target-specific initialization + void InitializeTarget(const TargetInfo &Target); + /// InitializeBuiltins - Mark the identifiers for all the builtins with their /// appropriate builtin ID # and mark any non-portable builtin identifiers as /// such. void InitializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts); /// \brief Popular the vector with the names of all of the builtins. - void GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names, + void GetBuiltinNames(SmallVectorImpl<const char *> &Names, bool NoBuiltins); /// Builtin::GetName - Return the identifier name for the specified builtin, @@ -103,6 +103,11 @@ public: return strchr(GetRecord(ID).Attributes, 'r') != 0; } + /// isReturnsTwice - Return true if we know this builtin can return twice. + bool isReturnsTwice(unsigned ID) const { + return strchr(GetRecord(ID).Attributes, 'j') != 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 { diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index ddd08278c37be..a37dc10398913 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -74,3 +74,4 @@ def Friend : Decl; def FriendTemplate : Decl; def StaticAssert : Decl; def Block : Decl, DeclContext; +def ClassScopeFunctionSpecialization : Decl; diff --git a/include/clang/Basic/DelayedCleanupPool.h b/include/clang/Basic/DelayedCleanupPool.h index 843205f7b011e..8575bc21113fe 100644 --- a/include/clang/Basic/DelayedCleanupPool.h +++ b/include/clang/Basic/DelayedCleanupPool.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H #define LLVM_CLANG_BASIC_DELAYEDCLEANUPPOOL_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -66,7 +67,7 @@ public: } void doCleanup() { - for (llvm::SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator + for (SmallVector<std::pair<void *, CleanupFn>, 8>::reverse_iterator I = Cleanups.rbegin(), E = Cleanups.rend(); I != E; ++I) I->second(I->first); Cleanups.clear(); @@ -79,7 +80,7 @@ public: private: llvm::DenseMap<void *, CleanupFn> Ptrs; - llvm::SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups; + SmallVector<std::pair<void *, CleanupFn>, 8> Cleanups; template <typename T> static void cleanupWithDelete(void *ptr) { diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 6f72976bfcf06..fefc44ce7bc6e 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -16,6 +16,7 @@ #include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/OwningPtr.h" @@ -25,7 +26,7 @@ #include <list> namespace clang { - class DiagnosticClient; + class DiagnosticConsumer; class DiagnosticBuilder; class IdentifierInfo; class DeclContext; @@ -64,7 +65,7 @@ public: /// \brief Create a code modification hint that inserts the given /// code string at a specific location. static FixItHint CreateInsertion(SourceLocation InsertionLoc, - llvm::StringRef Code) { + StringRef Code) { FixItHint Hint; Hint.RemoveRange = CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false); @@ -86,7 +87,7 @@ public: /// \brief Create a code modification hint that replaces the given /// source range with the given code string. static FixItHint CreateReplacement(CharSourceRange RemoveRange, - llvm::StringRef Code) { + StringRef Code) { FixItHint Hint; Hint.RemoveRange = RemoveRange; Hint.CodeToInsert = Code; @@ -94,17 +95,17 @@ public: } static FixItHint CreateReplacement(SourceRange RemoveRange, - llvm::StringRef Code) { + StringRef Code) { return CreateReplacement(CharSourceRange::getTokenRange(RemoveRange), Code); } }; -/// Diagnostic - This concrete class is used by the front-end to report +/// DiagnosticsEngine - This concrete class is used by the front-end to report /// problems and issues. It massages the diagnostics (e.g. handling things like -/// "report warnings as errors" and passes them off to the DiagnosticClient for -/// reporting to the user. Diagnostic is tied to one translation unit and -/// one SourceManager. -class Diagnostic : public llvm::RefCountedBase<Diagnostic> { +/// "report warnings as errors" and passes them off to the DiagnosticConsumer +/// for reporting to the user. DiagnosticsEngine is tied to one translation unit +/// and one SourceManager. +class DiagnosticsEngine : public llvm::RefCountedBase<DiagnosticsEngine> { public: /// Level - The level of the diagnostic, after it has been through mapping. enum Level { @@ -148,7 +149,8 @@ public: 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 EnableAllWarnings; // Enable all warnings. bool ErrorsAsFatal; // Treat errors like fatal errors. bool SuppressSystemWarnings; // Suppress warnings in system headers. bool SuppressAllDiagnostics; // Suppress all diagnostics. @@ -158,7 +160,7 @@ private: // 0 -> no limit. ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors? llvm::IntrusiveRefCntPtr<DiagnosticIDs> Diags; - DiagnosticClient *Client; + DiagnosticConsumer *Client; bool OwnsDiagClient; SourceManager *SourceMgr; @@ -173,22 +175,22 @@ private: /// the state so that we know what is the diagnostic state at any given /// source location. class DiagState { - llvm::DenseMap<unsigned, unsigned> DiagMap; + llvm::DenseMap<unsigned, DiagnosticMappingInfo> DiagMap; public: - typedef llvm::DenseMap<unsigned, unsigned>::const_iterator iterator; + typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::iterator + iterator; + typedef llvm::DenseMap<unsigned, DiagnosticMappingInfo>::const_iterator + const_iterator; - void setMapping(diag::kind Diag, unsigned Map) { DiagMap[Diag] = Map; } - - diag::Mapping getMapping(diag::kind Diag) const { - iterator I = DiagMap.find(Diag); - if (I != DiagMap.end()) - return (diag::Mapping)I->second; - return diag::Mapping(); + void setMappingInfo(diag::kind Diag, DiagnosticMappingInfo Info) { + DiagMap[Diag] = Info; } - iterator begin() const { return DiagMap.begin(); } - iterator end() const { return DiagMap.end(); } + DiagnosticMappingInfo &getOrAddMappingInfo(diag::kind Diag); + + const_iterator begin() const { return DiagMap.begin(); } + const_iterator end() const { return DiagMap.end(); } }; /// \brief Keeps and automatically disposes all DiagStates that we create. @@ -254,10 +256,10 @@ private: /// \brief Indicates that an unrecoverable error has occurred. bool UnrecoverableErrorOccurred; - /// \brief Toggles for DiagnosticErrorTrap to check whether an error occurred + /// \brief Counts for DiagnosticErrorTrap to check whether an error occurred /// during a parsing section, e.g. during parsing a function. - bool TrapErrorOccurred; - bool TrapUnrecoverableErrorOccurred; + unsigned TrapNumErrorsOccurred; + unsigned TrapNumUnrecoverableErrorsOccurred; /// LastDiagLevel - This is the level of the last diagnostic emitted. This is /// used to emit continuation diagnostics with the same level as the @@ -283,9 +285,9 @@ private: const char *Argument, unsigned ArgumentLen, const ArgumentValue *PrevArgs, unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, + SmallVectorImpl<char> &Output, void *Cookie, - llvm::SmallVectorImpl<intptr_t> &QualTypeVals); + SmallVectorImpl<intptr_t> &QualTypeVals); void *ArgToStringCookie; ArgToStringFnTy ArgToStringFn; @@ -301,21 +303,25 @@ private: std::string DelayedDiagArg2; public: - explicit Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &Diags, - DiagnosticClient *client = 0, + explicit DiagnosticsEngine( + const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &Diags, + DiagnosticConsumer *client = 0, bool ShouldOwnClient = true); - ~Diagnostic(); + ~DiagnosticsEngine(); const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &getDiagnosticIDs() const { return Diags; } - DiagnosticClient *getClient() { return Client; } - const DiagnosticClient *getClient() const { return Client; } + DiagnosticConsumer *getClient() { return Client; } + const DiagnosticConsumer *getClient() const { return Client; } + /// \brief Determine whether this \c DiagnosticsEngine object own its client. + bool ownsClient() const { return OwnsDiagClient; } + /// \brief Return the current diagnostic client along with ownership of that /// client. - DiagnosticClient *takeClient() { + DiagnosticConsumer *takeClient() { OwnsDiagClient = false; return Client; } @@ -328,8 +334,8 @@ public: void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; } //===--------------------------------------------------------------------===// - // Diagnostic characterization methods, used by a client to customize how - // diagnostics are emitted. + // DiagnosticsEngine characterization methods, used by a client to customize + // how diagnostics are emitted. // /// pushMappings - Copies the current DiagMappings and pushes the new copy @@ -346,7 +352,7 @@ public: /// /// \param ShouldOwnClient true if the diagnostic object should take /// ownership of \c client. - void setClient(DiagnosticClient *client, bool ShouldOwnClient = true); + void setClient(DiagnosticConsumer *client, bool ShouldOwnClient = true); /// setErrorLimit - Specify a limit for the number of errors we should /// emit before giving up. Zero disables the limit. @@ -369,6 +375,12 @@ public: void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; } bool getIgnoreAllWarnings() const { return IgnoreAllWarnings; } + /// setEnableAllWarnings - When set to true, any unmapped ignored warnings + /// are no longer ignored. If this and IgnoreAllWarnings are both set, + /// then that one wins. + void setEnableAllWarnings(bool Val) { EnableAllWarnings = Val; } + bool getEnableAllWarnngs() const { return EnableAllWarnings; } + /// setWarningsAsErrors - When set to true, any warnings reported are issued /// as errors. void setWarningsAsErrors(bool Val) { WarningsAsErrors = Val; } @@ -435,10 +447,20 @@ public: /// /// 'Loc' is the source location that this change of diagnostic state should /// take affect. It can be null if we are setting the state from command-line. - bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, - SourceLocation Loc = SourceLocation()) { - return Diags->setDiagnosticGroupMapping(Group, Map, Loc, *this); - } + bool setDiagnosticGroupMapping(StringRef Group, diag::Mapping Map, + SourceLocation Loc = SourceLocation()); + + /// \brief Set the warning-as-error flag for the given diagnostic group. This + /// function always only operates on the current diagnostic state. + /// + /// \returns True if the given group is unknown, false otherwise. + bool setDiagnosticGroupWarningAsError(StringRef Group, bool Enabled); + + /// \brief Set the error-as-fatal flag for the given diagnostic group. This + /// function always only operates on the current diagnostic state. + /// + /// \returns True if the given group is unknown, false otherwise. + bool setDiagnosticGroupErrorAsFatal(StringRef Group, bool Enabled); bool hasErrorOccurred() const { return ErrorOccurred; } bool hasFatalErrorOccurred() const { return FatalErrorOccurred; } @@ -457,7 +479,7 @@ public: /// 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, llvm::StringRef Message) { + unsigned getCustomDiagID(Level L, StringRef Message) { return Diags->getCustomDiagID((DiagnosticIDs::Level)L, Message); } @@ -467,8 +489,8 @@ public: const char *Modifier, unsigned ModLen, const char *Argument, unsigned ArgLen, const ArgumentValue *PrevArgs, unsigned NumPrevArgs, - llvm::SmallVectorImpl<char> &Output, - llvm::SmallVectorImpl<intptr_t> &QualTypeVals) const { + SmallVectorImpl<char> &Output, + SmallVectorImpl<intptr_t> &QualTypeVals) const { ArgToStringFn(Kind, Val, Modifier, ModLen, Argument, ArgLen, PrevArgs, NumPrevArgs, Output, ArgToStringCookie, QualTypeVals); @@ -484,18 +506,17 @@ public: void Reset(); //===--------------------------------------------------------------------===// - // Diagnostic classification and reporting interfaces. + // DiagnosticsEngine classification and reporting interfaces. // - /// \brief Based on the way the client configured the Diagnostic + /// \brief Based on the way the client configured the DiagnosticsEngine /// object, classify the specified diagnostic ID into a Level, consumable by - /// the DiagnosticClient. + /// the DiagnosticConsumer. /// /// \param Loc The source location we are interested in finding out the /// diagnostic state. Can be null in order to query the latest state. - Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, - diag::Mapping *mapping = 0) const { - return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this, mapping); + Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc) const { + return (Level)Diags->getDiagnosticLevel(DiagID, Loc, *this); } /// Report - Issue the message to the client. @c DiagID is a member of the @@ -527,13 +548,13 @@ public: /// /// \param Arg1 A string argument that will be provided to the /// diagnostic. A copy of this string will be stored in the - /// Diagnostic object itself. + /// DiagnosticsEngine object itself. /// /// \param Arg2 A string argument that will be provided to the /// diagnostic. A copy of this string will be stored in the - /// Diagnostic object itself. - void SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1 = "", - llvm::StringRef Arg2 = ""); + /// DiagnosticsEngine object itself. + void SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1 = "", + StringRef Arg2 = ""); /// \brief Clear out the current diagnostic. void Clear() { CurDiagID = ~0U; } @@ -542,23 +563,6 @@ private: /// \brief Report the delayed diagnostic. void ReportDelayed(); - - /// 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. - diag::Mapping getDiagnosticMappingInfo(diag::kind Diag, - DiagState *State) const { - return State->getMapping(Diag); - } - - void setDiagnosticMappingInternal(unsigned DiagId, unsigned Map, - DiagState *State, - bool isUser, bool isPragma) const { - if (isUser) Map |= 8; // Set the high bit for user mappings. - if (isPragma) Map |= 0x10; // Set the bit for diagnostic pragma mappings. - State->setMapping((diag::kind)DiagId, Map); - } - // This is private state used by DiagnosticBuilder. We put it here instead of // in DiagnosticBuilder in order to keep DiagnosticBuilder a small lightweight // object. This implementation choice means that we can only have one @@ -567,7 +571,7 @@ private: // diagnostic is in flight at a time. friend class DiagnosticIDs; friend class DiagnosticBuilder; - friend class DiagnosticInfo; + friend class Diagnostic; friend class PartialDiagnostic; friend class DiagnosticErrorTrap; @@ -614,7 +618,7 @@ private: /// only support 10 ranges, could easily be extended if needed. CharSourceRange DiagRanges[10]; - enum { MaxFixItHints = 3 }; + enum { MaxFixItHints = 6 }; /// FixItHints - If valid, provides a hint with some code /// to insert, remove, or modify at a particular position. @@ -637,28 +641,30 @@ private: /// between the time the instance was created and the time it was /// queried. class DiagnosticErrorTrap { - Diagnostic &Diag; + DiagnosticsEngine &Diag; + unsigned NumErrors; + unsigned NumUnrecoverableErrors; public: - explicit DiagnosticErrorTrap(Diagnostic &Diag) + explicit DiagnosticErrorTrap(DiagnosticsEngine &Diag) : Diag(Diag) { reset(); } /// \brief Determine whether any errors have occurred since this /// object instance was created. bool hasErrorOccurred() const { - return Diag.TrapErrorOccurred; + return Diag.TrapNumErrorsOccurred > NumErrors; } /// \brief Determine whether any unrecoverable errors have occurred since this /// object instance was created. bool hasUnrecoverableErrorOccurred() const { - return Diag.TrapUnrecoverableErrorOccurred; + return Diag.TrapNumUnrecoverableErrorsOccurred > NumUnrecoverableErrors; } // Set to initial state of "no errors occurred". void reset() { - Diag.TrapErrorOccurred = false; - Diag.TrapUnrecoverableErrorOccurred = false; + NumErrors = Diag.TrapNumErrorsOccurred; + NumUnrecoverableErrors = Diag.TrapNumUnrecoverableErrorsOccurred; } }; @@ -667,9 +673,9 @@ public: //===----------------------------------------------------------------------===// /// DiagnosticBuilder - This is a little helper class used to produce -/// diagnostics. This is constructed by the Diagnostic::Report method, and -/// allows insertion of extra information (arguments and source ranges) into the -/// currently "in flight" diagnostic. When the temporary for the builder is +/// diagnostics. This is constructed by the DiagnosticsEngine::Report method, +/// and allows insertion of extra information (arguments and source ranges) into +/// the currently "in flight" diagnostic. When the temporary for the builder is /// destroyed, the diagnostic is issued. /// /// Note that many of these will be created as temporary objects (many call @@ -678,12 +684,12 @@ public: /// the common fields to registers, eliminating increments of the NumArgs field, /// for example. class DiagnosticBuilder { - mutable Diagnostic *DiagObj; + mutable DiagnosticsEngine *DiagObj; mutable unsigned NumArgs, NumRanges, NumFixItHints; void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT - friend class Diagnostic; - explicit DiagnosticBuilder(Diagnostic *diagObj) + friend class DiagnosticsEngine; + explicit DiagnosticBuilder(DiagnosticsEngine *diagObj) : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixItHints(0) {} friend class PartialDiagnostic; @@ -731,7 +737,7 @@ public: /// /// \pre \c isActive() unsigned getDiagID() const { - assert(isActive() && "Diagnostic is inactive"); + assert(isActive() && "DiagnosticsEngine is inactive"); return DiagObj->CurDiagID; } @@ -743,17 +749,17 @@ public: /// return Diag(...); operator bool() const { return true; } - void AddString(llvm::StringRef S) const { - assert(NumArgs < Diagnostic::MaxArguments && + void AddString(StringRef S) const { + assert(NumArgs < DiagnosticsEngine::MaxArguments && "Too many arguments to diagnostic!"); if (DiagObj) { - DiagObj->DiagArgumentsKind[NumArgs] = Diagnostic::ak_std_string; + DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string; DiagObj->DiagArgumentsStr[NumArgs++] = S; } } - void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const { - assert(NumArgs < Diagnostic::MaxArguments && + void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { + assert(NumArgs < DiagnosticsEngine::MaxArguments && "Too many arguments to diagnostic!"); if (DiagObj) { DiagObj->DiagArgumentsKind[NumArgs] = Kind; @@ -770,15 +776,17 @@ public: } void AddFixItHint(const FixItHint &Hint) const { - assert(NumFixItHints < Diagnostic::MaxFixItHints && + assert(NumFixItHints < DiagnosticsEngine::MaxFixItHints && "Too many fix-it hints!"); + if (NumFixItHints >= DiagnosticsEngine::MaxFixItHints) + return; // Don't crash in release builds if (DiagObj) DiagObj->FixItHints[NumFixItHints++] = Hint; } }; inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, - llvm::StringRef S) { + StringRef S) { DB.AddString(S); return DB; } @@ -786,30 +794,30 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const char *Str) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(Str), - Diagnostic::ak_c_string); + DiagnosticsEngine::ak_c_string); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) { - DB.AddTaggedVal(I, Diagnostic::ak_sint); + DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,bool I) { - DB.AddTaggedVal(I, Diagnostic::ak_sint); + DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, unsigned I) { - DB.AddTaggedVal(I, Diagnostic::ak_uint); + DB.AddTaggedVal(I, DiagnosticsEngine::ak_uint); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const IdentifierInfo *II) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(II), - Diagnostic::ak_identifierinfo); + DiagnosticsEngine::ak_identifierinfo); return DB; } @@ -823,7 +831,7 @@ 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); + DiagnosticsEngine::ak_declcontext); return DB; } @@ -848,33 +856,33 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, /// Report - Issue the message to the client. DiagID is a member of the /// diag::kind enum. This actually returns a new instance of DiagnosticBuilder /// which emits the diagnostics (through ProcessDiag) when it is destroyed. -inline DiagnosticBuilder Diagnostic::Report(SourceLocation Loc, +inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, unsigned DiagID){ assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!"); CurDiagLoc = Loc; CurDiagID = DiagID; return DiagnosticBuilder(this); } -inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) { +inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { return Report(SourceLocation(), DiagID); } //===----------------------------------------------------------------------===// -// DiagnosticInfo +// Diagnostic //===----------------------------------------------------------------------===// -/// 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. -class DiagnosticInfo { - const Diagnostic *DiagObj; - llvm::StringRef StoredDiagMessage; +/// Diagnostic - This is a little helper class (which is basically a smart +/// pointer that forward info from DiagnosticsEngine) that allows clients to +/// enquire about the currently in-flight diagnostic. +class Diagnostic { + const DiagnosticsEngine *DiagObj; + StringRef StoredDiagMessage; public: - explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {} - DiagnosticInfo(const Diagnostic *DO, llvm::StringRef storedDiagMessage) + explicit Diagnostic(const DiagnosticsEngine *DO) : DiagObj(DO) {} + Diagnostic(const DiagnosticsEngine *DO, StringRef storedDiagMessage) : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {} - const Diagnostic *getDiags() const { return DiagObj; } + const DiagnosticsEngine *getDiags() const { return DiagObj; } unsigned getID() const { return DiagObj->CurDiagID; } const SourceLocation &getLocation() const { return DiagObj->CurDiagLoc; } bool hasSourceManager() const { return DiagObj->hasSourceManager(); } @@ -884,49 +892,49 @@ public: /// 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 { + DiagnosticsEngine::ArgumentKind getArgKind(unsigned Idx) const { assert(Idx < getNumArgs() && "Argument index out of range!"); - return (Diagnostic::ArgumentKind)DiagObj->DiagArgumentsKind[Idx]; + return (DiagnosticsEngine::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 && + assert(getArgKind(Idx) == DiagnosticsEngine::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 && + assert(getArgKind(Idx) == DiagnosticsEngine::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 && + assert(getArgKind(Idx) == DiagnosticsEngine::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 && + assert(getArgKind(Idx) == DiagnosticsEngine::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 && + assert(getArgKind(Idx) == DiagnosticsEngine::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 && + assert(getArgKind(Idx) != DiagnosticsEngine::ak_std_string && "invalid argument accessor!"); return DiagObj->DiagArgumentsVal[Idx]; } @@ -959,12 +967,12 @@ public: /// FormatDiagnostic - Format this diagnostic into a string, substituting the /// formal arguments into the %0 slots. The result is appended onto the Str /// array. - void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const; + void FormatDiagnostic(SmallVectorImpl<char> &OutStr) const; /// FormatDiagnostic - Format the given format-string into the /// output buffer using the arguments stored in this diagnostic. void FormatDiagnostic(const char *DiagStr, const char *DiagEnd, - llvm::SmallVectorImpl<char> &OutStr) const; + SmallVectorImpl<char> &OutStr) const; }; /** @@ -973,7 +981,7 @@ public: */ class StoredDiagnostic { unsigned ID; - Diagnostic::Level Level; + DiagnosticsEngine::Level Level; FullSourceLoc Loc; std::string Message; std::vector<CharSourceRange> Ranges; @@ -981,18 +989,22 @@ class StoredDiagnostic { public: StoredDiagnostic(); - StoredDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info); - StoredDiagnostic(Diagnostic::Level Level, unsigned ID, - llvm::StringRef Message); + StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); + StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, + StringRef Message); + StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, + StringRef Message, FullSourceLoc Loc, + ArrayRef<CharSourceRange> Ranges, + ArrayRef<FixItHint> Fixits); ~StoredDiagnostic(); /// \brief Evaluates true when this object stores a diagnostic. operator bool() const { return Message.size() > 0; } unsigned getID() const { return ID; } - Diagnostic::Level getLevel() const { return Level; } + DiagnosticsEngine::Level getLevel() const { return Level; } const FullSourceLoc &getLocation() const { return Loc; } - llvm::StringRef getMessage() const { return Message; } + StringRef getMessage() const { return Message; } void setLocation(FullSourceLoc Loc) { this->Loc = Loc; } @@ -1007,20 +1019,20 @@ public: unsigned fixit_size() const { return FixIts.size(); } }; -/// DiagnosticClient - This is an abstract interface implemented by clients of +/// DiagnosticConsumer - This is an abstract interface implemented by clients of /// the front-end, which formats and prints fully processed diagnostics. -class DiagnosticClient { +class DiagnosticConsumer { protected: unsigned NumWarnings; // Number of warnings reported unsigned NumErrors; // Number of errors reported public: - DiagnosticClient() : NumWarnings(0), NumErrors(0) { } + DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { } unsigned getNumErrors() const { return NumErrors; } unsigned getNumWarnings() const { return NumWarnings; } - virtual ~DiagnosticClient(); + virtual ~DiagnosticConsumer(); /// BeginSourceFile - Callback to inform the diagnostic client that processing /// of a source file is beginning. @@ -1043,8 +1055,8 @@ public: /// IncludeInDiagnosticCounts - This method (whose default implementation /// returns true) indicates whether the diagnostics handled by this - /// DiagnosticClient should be included in the number of diagnostics reported - /// by Diagnostic. + /// DiagnosticConsumer should be included in the number of diagnostics + /// reported by DiagnosticsEngine. virtual bool IncludeInDiagnosticCounts() const; /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or @@ -1052,8 +1064,24 @@ public: /// /// Default implementation just keeps track of the total number of warnings /// and errors. - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info); + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); + + /// \brief Clone the diagnostic consumer, producing an equivalent consumer + /// that can be used in a different context. + virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0; +}; + +/// IgnoringDiagConsumer - This is a diagnostic client that just ignores all +/// diags. +class IgnoringDiagConsumer : public DiagnosticConsumer { + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) { + // Just ignore it. + } + DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { + return new IgnoringDiagConsumer(); + } }; } // end namespace clang diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td index 50a22c4a91208..8ae69fef27833 100644 --- a/include/clang/Basic/Diagnostic.td +++ b/include/clang/Basic/Diagnostic.td @@ -18,8 +18,6 @@ def MAP_IGNORE : DiagMapping; def MAP_WARNING : DiagMapping; def MAP_ERROR : DiagMapping; def MAP_FATAL : DiagMapping; -def MAP_WARNING_NO_WERROR : DiagMapping; -def MAP_WARNING_SHOW_IN_SYSTEM_HEADER : DiagMapping; // Define the diagnostic classes. class DiagClass; @@ -59,6 +57,8 @@ class Diagnostic<string text, DiagClass DC, DiagMapping defaultmapping> { DiagClass Class = DC; bit SFINAE = 1; bit AccessControl = 0; + bit WarningNoWerror = 0; + bit WarningShowInSystemHeader = 0; DiagMapping DefaultMapping = defaultmapping; DiagGroup Group; string CategoryName = ""; @@ -77,9 +77,11 @@ class DefaultIgnore { DiagMapping DefaultMapping = MAP_IGNORE; } class DefaultWarn { DiagMapping DefaultMapping = MAP_WARNING; } class DefaultError { DiagMapping DefaultMapping = MAP_ERROR; } class DefaultFatal { DiagMapping DefaultMapping = MAP_FATAL; } -class DefaultWarnNoWerror { DiagMapping DefaultMapping= MAP_WARNING_NO_WERROR; } +class DefaultWarnNoWerror { + bit WarningNoWerror = 1; +} class DefaultWarnShowInSystemHeader { - DiagMapping DefaultMapping = MAP_WARNING_SHOW_IN_SYSTEM_HEADER; + bit WarningShowInSystemHeader = 1; } class NoSFINAE { bit SFINAE = 0; } diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 7d45bc58463cb..705c95b7fc276 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -57,6 +57,10 @@ def note_odr_number_of_bases : Note< def note_odr_enumerator : Note<"enumerator %0 with value %1 here">; def note_odr_missing_enumerator : Note<"no corresponding enumerator here">; +def err_odr_field_type_inconsistent : Error< + "field %0 declared with incompatible types in different " + "translation units (%1 vs. %2)">; + // Importing Objective-C ASTs def err_odr_ivar_type_inconsistent : Error< "instance variable %0 declared with incompatible types in different " diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 4b5de366cbc0c..f9a910a1c21e5 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -52,18 +52,31 @@ def err_invalid_storage_class_in_func_decl : Error< "invalid storage class specifier in function declarator">; def err_expected_namespace_name : Error<"expected namespace name">; def ext_variadic_templates : ExtWarn< - "variadic templates are a C++0x extension">, InGroup<CXX0x>; + "variadic templates are a C++11 extension">, InGroup<CXX11>; +def warn_cxx98_compat_variadic_templates : + Warning<"variadic templates are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; def err_default_special_members : Error< "only special member functions may be defaulted">; def err_friends_define_only_namespace_scope : Error< "cannot define a function with non-namespace scope in a friend declaration">; def err_deleted_non_function : Error< "only functions can have deleted definitions">; +def err_module_not_found : Error<"module '%0' not found">, DefaultFatal; +def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal; +def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, + DefaultFatal; +def warn_module_build : Warning<"building module '%0' from source">, + InGroup<ModuleBuild>, DefaultIgnore; +def note_pragma_entered_here : Note<"#pragma entered here">; // Sema && Lex def ext_longlong : Extension< "'long long' is an extension when C99 mode is not enabled">, InGroup<LongLong>; +def warn_cxx98_compat_longlong : Warning< + "'long long' is incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; 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 e33b67ef7a074..3c0e4f53d3c11 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -65,6 +65,9 @@ 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 err_drv_invalid_libcxx_deployment : Error< + "invalid deployment target for -stdlib=libc++ (requires %0 or later)">; + def err_drv_I_dash_not_supported : Error< "'%0' not supported, please use -iquote instead">; def err_drv_unknown_argument : Error<"unknown argument: '%0'">; @@ -123,4 +126,7 @@ def warn_drv_objc_gc_unsupported : Warning< def warn_drv_pch_not_first_include : Warning< "precompiled header '%0' was ignored because '%1' is not first '-include'">; +def note_drv_command_failed_diag_msg : Note< + "diagnostic msg: %0">; + } diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 120ba67dc1f62..fffa42feb2fba 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -112,139 +112,11 @@ def err_relocatable_without_isysroot : Error< 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'">; -def warn_pch_c99 : Error< - "C99 support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_c1x : Error< - "C1X support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_cplusplus : Error< - "C++ support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_cplusplus0x : Error< - "C++0x support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_objective_c : Error< - "Objective-C support was %select{disabled|enabled}0 in PCH file but is " - "currently %select{disabled|enabled}1">; -def warn_pch_objective_c2 : Error< - "Objective-C 2.0 support was %select{disabled|enabled}0 in PCH file but " - "is currently %select{disabled|enabled}1">; -def warn_pch_nonfragile_abi : Error< - "PCH file was compiled with the %select{32-bit|non-fragile}0 Objective-C " - "ABI but the %select{32-bit|non-fragile}1 Objective-C ABI is selected">; -def warn_pch_nonfragile_abi2 : Error< - "PCH file was compiled with the %select{32-bit|enhanced non-fragile}0 " - "Objective-C ABI but the %select{32-bit|enhanced non-fragile}1 " - "Objective-C ABI is selected">; -def warn_pch_auto_ref_count : Error< - "PCH file was compiled %select{without|with} automated reference counting," - "which is currently %select{disabled|enabled}">; -def warn_pch_apple_kext : Error< - "PCH file was compiled %select{with|without}0 support for Apple's kernel " - "extensions ABI but it is currently %select{disabled|enabled}1">; -def warn_pch_objc_auto_properties : Error< - "PCH file was compiled %select{with|without}0 support for auto-synthesized " - "@properties but it is currently %select{disabled|enabled}1">; -def warn_pch_no_constant_cfstrings : Error< - "Objctive-C NSstring generation support was %select{disabled|enabled}0 " - "in PCH file but currently %select{disabled|enabled}1">; -def warn_pch_extensions : Error< - "extensions were %select{enabled|disabled}0 in PCH file but are " - "currently %select{enabled|disabled}1">; -def warn_pch_gnu_extensions : Error< - "GNU extensions were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_gnu_keywords : Error< - "GNU keywords were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_microsoft_extensions : Error< - "Microsoft extensions were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_ms_bitfields : Error< - "Microsoft-compatible structure layout was %select{disabled|enabled}0 in " - "PCH file but is currently %select{disabled|enabled}1">; -def warn_pch_heinous_extensions : Error< - "heinous extensions were %select{disabled|enabled}0 in PCH file but are " - "currently %select{disabled|enabled}1">; -def warn_pch_lax_vector_conversions : Error< - "lax vector conversions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_altivec : Error< - "AltiVec initializers were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -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_cuda : Error< - "CUDA 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">; -def warn_pch_objc_exceptions : Error< - "Objective-C exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_cxx_exceptions : Error< - "C++ exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_sjlj_exceptions : Error< - "sjlj-exceptions were %select{disabled|enabled}0 in PCH file but " - "are currently %select{disabled|enabled}1">; -def warn_pch_objc_runtime : Error< - "PCH file was compiled with the %select{NeXT|GNU}0 runtime but the " - "%select{NeXT|GNU}1 runtime is selected">; -def warn_pch_freestanding : Error< - "PCH file was compiled with a %select{hosted|freestanding}0 " - "implementation but a %select{hosted|freestanding}1 implementation " - "is selected">; -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 " - "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">; -def warn_pch_math_errno : Error< - "math functions %select{do not respect|respect}0 'errno' in PCH " - "file but they are currently set to %select{not respect|respect}1 " - "'errno'">; -def warn_pch_optimize : Error< - "the macro '__OPTIMIZE__' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_optimize_size : Error< - "the macro '__OPTIMIZE_SIZE__' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_static : Error< - "the PCH file was compiled %select{dynamic|static}0 but the " - "current translation unit is being compiled as %select{dynamic|static}1">; -def warn_pch_pic_level : Error< - "PCH file was compiled with PIC level %0, but the current translation " - "unit will be compiled with PIC level %1">; -def warn_pch_gnu_inline : Error< - "PCH file was compiled with %select{C99|GNU|}0 inline semantics but " - "%select{C99|GNU}1 inline semantics are currently selected">; -def warn_pch_no_inline : Error< - "the macro '__NO_INLINE__' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_deprecated : Error< - "the macro '__DEPRECATED' was %select{not defined|defined}0 in " - "the PCH file but is currently %select{undefined|defined}1">; -def warn_pch_gc_mode : Error< - "the PCH file was built with %select{no||hybrid}0 garbage collection but " - "the current translation unit will compiled with %select{no||hybrid}1 " - "garbage collection">; +def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in " + "PCH file but is currently %select{disabled|enabled}2">; +def err_pch_langopt_value_mismatch : Error< + "%0 differs in PCH file vs. current file">; + 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< @@ -266,18 +138,6 @@ def warn_macro_name_used_in_pch : Error< def warn_pch_compiler_options_mismatch : Error< "compiler options used when building the precompiled header differ from " "the options used when using the precompiled header">; -def warn_pch_access_control : Error< - "C++ access control was %select{disabled|enabled}0 in the PCH file but " - "is currently %select{disabled|enabled}1">; -def warn_pch_char_signed : Error< - "char was %select{unsigned|signed}0 in the PCH file but " - "is currently %select{unsigned|signed}1">; -def warn_pch_short_wchar : Error< - "-fshort-wchar was %select{disabled|enabled}0 in the PCH file but " - "is currently %select{disabled|enabled}1">; -def warn_pch_short_enums : Error< - "-fshort-enums was %select{disabled|enabled}0 in the PCH file but " - "is currently %select{disabled|enabled}1">; def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; @@ -291,6 +151,11 @@ def warn_unknown_warning_specifier : Warning< "unknown %0 warning specifier: '%1'">, InGroup<DiagGroup<"unknown-warning-option"> >; -def warn_unkwown_analyzer_checker : Warning< +def warn_unknown_analyzer_checker : Warning< "no analyzer checkers are associated with '%0'">; +def warn_incompatible_analyzer_plugin_api : Warning< + "checker plugin '%0' is not compatible with this version of the analyzer">, + InGroup<DiagGroup<"analyzer-incompatible-plugin"> >; +def note_incompatible_analyzer_plugin_api : Note< + "current API version is '%0', but plugin was compiled with version '%1'">; } diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 8a109149884f1..49603eb69e44a 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -54,9 +54,16 @@ def ExtraTokens : DiagGroup<"extra-tokens">; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; -def CXXHexFloats : DiagGroup<"c++-hex-floats">; +def CXX98Compat : DiagGroup<"c++98-compat">; +// Warnings for C++11 features which are Extensions in C++98 mode. +def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat]>; + +def CXX11Narrowing : DiagGroup<"c++11-narrowing">; +def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>; + +def CXX11Compat : DiagGroup<"c++11-compat", [CXX11Narrowing]>; +def : DiagGroup<"c++0x-compat", [CXX11Compat]>; -def : DiagGroup<"c++0x-compat", [CXXHexFloats]>; def : DiagGroup<"effc++">; def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FourByteMultiChar : DiagGroup<"four-char-constants">; @@ -66,13 +73,15 @@ def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">; def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; def : DiagGroup<"import">; +def IncompatiblePointerTypes : DiagGroup<"incompatible-pointer-types">; def : DiagGroup<"init-self">; def : DiagGroup<"inline">; def : DiagGroup<"int-to-pointer-cast">; def : DiagGroup<"invalid-pch">; def LiteralRange : DiagGroup<"literal-range">; def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args">; -def : DiagGroup<"main">; +def MalformedWarningCheck : DiagGroup<"malformed-warning-check">; +def Main : DiagGroup<"main">; def MissingBraces : DiagGroup<"missing-braces">; def MissingDeclarations: DiagGroup<"missing-declarations">; def : DiagGroup<"missing-format-attribute">; @@ -84,6 +93,7 @@ def : DiagGroup<"newline-eof">; def LongLong : DiagGroup<"long-long">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; +def ModuleBuild : DiagGroup<"module-build">; def NullDereference : DiagGroup<"null-dereference">; def InitializerOverrides : DiagGroup<"initializer-overrides">; def NonNull : DiagGroup<"nonnull">; @@ -95,6 +105,9 @@ def OutOfLineDeclaration : DiagGroup<"out-of-line-declaration">; def : DiagGroup<"overflow">; def OverlengthStrings : DiagGroup<"overlength-strings">; def OverloadedVirtual : DiagGroup<"overloaded-virtual">; +def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; +def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">; +def ObjCContinuationPropertyType :DiagGroup<"objc-continuation-property-type">; def Packed : DiagGroup<"packed">; def Padded : DiagGroup<"padded">; def PointerArith : DiagGroup<"pointer-arith">; @@ -108,6 +121,8 @@ def ReturnType : DiagGroup<"return-type">; def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy">; def SelfAssignment : DiagGroup<"self-assign">; def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; +def Sentinel : DiagGroup<"sentinel">; +def MissingMethodReturnType : DiagGroup<"missing-method-return-type">; def : DiagGroup<"sequence-point">; def Shadow : DiagGroup<"shadow">; def : DiagGroup<"shorten-64-to-32">; @@ -152,6 +167,7 @@ def UnknownPragmas : DiagGroup<"unknown-pragmas">; def UnknownAttributes : DiagGroup<"attributes">; def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">; def UnusedArgument : DiagGroup<"unused-argument">; +def UnusedComparison : DiagGroup<"unused-comparison">; def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">; def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">; def UnneededMemberFunction : DiagGroup<"unneeded-member-function">; @@ -160,9 +176,11 @@ def UnusedMemberFunction : DiagGroup<"unused-member-function", [UnneededMemberFunction]>; def UnusedLabel : DiagGroup<"unused-label">; def UnusedParameter : DiagGroup<"unused-parameter">; -def UnusedValue : DiagGroup<"unused-value">; +def UnusedResult : DiagGroup<"unused-result">; +def UnusedValue : DiagGroup<"unused-value", [UnusedComparison, UnusedResult]>; def UnusedVariable : DiagGroup<"unused-variable">; def UsedButMarkedUnused : DiagGroup<"used-but-marked-unused">; +def UserDefinedLiterals : DiagGroup<"user-defined-literals">; def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">; def Reorder : DiagGroup<"reorder">; def UndeclaredSelector : DiagGroup<"undeclared-selector">; @@ -183,6 +201,7 @@ def Selector : DiagGroup<"selector">; def NonfragileAbi2 : DiagGroup<"nonfragile-abi2">; def Protocol : DiagGroup<"protocol">; def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">; +def OverridingMethodMismatch : DiagGroup<"overriding-method-mismatch">; def : DiagGroup<"variadic-macros">; def VariadicMacros : DiagGroup<"variadic-macros">; def VectorConversions : DiagGroup<"vector-conversions">; // clang specific @@ -202,9 +221,11 @@ def DuplicateArgDecl : DiagGroup<"duplicate-method-arg">; // missing parentheses; it is off by default. We do not include it // in -Wparentheses because most users who use -Wparentheses explicitly // do not want these warnings. +def ParenthesesOnEquality : DiagGroup<"parentheses-equality">; def Parentheses : DiagGroup<"parentheses", [LogicalOpParentheses, - BitwiseOpParentheses]>; + BitwiseOpParentheses, + ParenthesesOnEquality]>; // -Wconversion has its own warnings, but we split a few out for // legacy reasons: @@ -216,6 +237,7 @@ def Conversion : DiagGroup<"conversion", [DiagGroup<"shorten-64-to-32">, DiagGroup<"constant-conversion">, DiagGroup<"literal-conversion">, + DiagGroup<"string-conversion">, DiagGroup<"sign-conversion">, BoolConversions]>, DiagCategory<"Value Conversion Issue">; @@ -228,11 +250,12 @@ def Unused : DiagGroup<"unused", DiagCategory<"Unused Entity Issue">; // Format settings. +def FormatInvalidSpecifier : DiagGroup<"format-invalid-specifier">; def FormatSecurity : DiagGroup<"format-security">; def FormatY2K : DiagGroup<"format-y2k">; def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull, - FormatSecurity, FormatY2K]>, + FormatSecurity, FormatY2K, FormatInvalidSpecifier]>, DiagCategory<"Format String Issue">; def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>; def Format2 : DiagGroup<"format=2", @@ -243,6 +266,7 @@ def Extra : DiagGroup<"extra", [ IgnoredQualifiers, InitializerOverrides, SemiBeforeMethodBody, + MissingMethodReturnType, SignCompare, UnusedParameter ]>; @@ -265,12 +289,15 @@ def Most : DiagGroup<"most", [ Uninitialized, UnknownPragmas, Unused, - VectorConversions, VolatileRegisterVar, + ObjCMissingSuperCalls, OverloadedVirtual ]>; -// -Wall is -Wmost -Wparentheses +// Thread Safety warnings +def ThreadSafety : DiagGroup<"thread-safety">; + +// -Wall is -Wmost -Wparentheses -Wtop-level-comparison def : DiagGroup<"all", [Most, Parentheses]>; // Aliases. @@ -283,14 +310,16 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment def NonGCC : DiagGroup<"non-gcc", [SignCompare, Conversion, LiteralRange]>; -// A warning group for warnings about using C++0x features as extensions in +// A warning group for warnings about using C++11 features as extensions in // earlier C++ versions. -def CXX0xStaticNonIntegralInitializer : - DiagGroup<"c++0x-static-nonintegral-init">; -def CXX0x : DiagGroup<"c++0x-extensions", [CXX0xStaticNonIntegralInitializer]>; +def CXX11 : DiagGroup<"c++11-extensions">; +def : DiagGroup<"c++0x-extensions", [CXX11]>; def DelegatingCtorCycles : DiagGroup<"delegating-ctor-cycles">; +// A warning group for warnings about using C1X features as extensions. +def C1X : DiagGroup<"c1x-extensions">; + // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; @@ -299,3 +328,4 @@ def Microsoft : DiagGroup<"microsoft">; def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">; +def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">; diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index ae4ed5bbb13c3..16d9b39985ed2 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -16,10 +16,16 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringRef.h" +#include "clang/Basic/LLVM.h" + +namespace llvm { + template<typename T, unsigned> class SmallVector; +} namespace clang { - class Diagnostic; + class DiagnosticsEngine; class SourceLocation; + struct WarningOption; // Import the diagnostic enums themselves. namespace diag { @@ -43,7 +49,7 @@ namespace clang { // Get typedefs for common diagnostics. enum { #define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ - SFINAE,ACCESS,CATEGORY,BRIEF,FULL) ENUM, + SFINAE,ACCESS,CATEGORY,NOWERROR,SHOWINSYSHEADER,BRIEF,FULL) ENUM, #include "clang/Basic/DiagnosticCommonKinds.inc" NUM_BUILTIN_COMMON_DIAGNOSTICS #undef DIAG @@ -59,20 +65,47 @@ namespace clang { MAP_IGNORE = 1, //< Map this diagnostic to nothing, ignore it. 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, - /// Map this diagnostic to "warning", but make it immune to - /// -Wno-system-headers. - MAP_WARNING_SHOW_IN_SYSTEM_HEADER = 6, - /// Map this diagnostic to "error", but make it immune to -Wfatal-errors. - /// This happens for -Wno-fatal-errors=foo. - MAP_ERROR_NO_WFATAL = 7 + MAP_FATAL = 4 //< Map this diagnostic to a fatal error. }; } +class DiagnosticMappingInfo { + unsigned Mapping : 3; + unsigned IsUser : 1; + unsigned IsPragma : 1; + unsigned HasShowInSystemHeader : 1; + unsigned HasNoWarningAsError : 1; + unsigned HasNoErrorAsFatal : 1; + +public: + static DiagnosticMappingInfo Make(diag::Mapping Mapping, bool IsUser, + bool IsPragma) { + DiagnosticMappingInfo Result; + Result.Mapping = Mapping; + Result.IsUser = IsUser; + Result.IsPragma = IsPragma; + Result.HasShowInSystemHeader = 0; + Result.HasNoWarningAsError = 0; + Result.HasNoErrorAsFatal = 0; + return Result; + } + + diag::Mapping getMapping() const { return diag::Mapping(Mapping); } + void setMapping(diag::Mapping Value) { Mapping = Value; } + + bool isUser() const { return IsUser; } + bool isPragma() const { return IsPragma; } + + bool hasShowInSystemHeader() const { return HasShowInSystemHeader; } + void setShowInSystemHeader(bool Value) { HasShowInSystemHeader = Value; } + + bool hasNoWarningAsError() const { return HasNoWarningAsError; } + void setNoWarningAsError(bool Value) { HasNoWarningAsError = Value; } + + bool hasNoErrorAsFatal() const { return HasNoErrorAsFatal; } + void setNoErrorAsFatal(bool Value) { HasNoErrorAsFatal = Value; } +}; + /// \brief Used for handling and querying diagnostic IDs. Can be used and shared /// by multiple Diagnostics for multiple translation units. class DiagnosticIDs : public llvm::RefCountedBase<DiagnosticIDs> { @@ -93,7 +126,7 @@ public: /// 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, llvm::StringRef Message); + unsigned getCustomDiagID(Level L, StringRef Message); //===--------------------------------------------------------------------===// // Diagnostic classification and reporting interfaces. @@ -101,14 +134,18 @@ public: /// getDescription - Given a diagnostic ID, return a description of the /// issue. - llvm::StringRef getDescription(unsigned DiagID) const; + StringRef getDescription(unsigned DiagID) const; - /// isBuiltinWarningOrExtension - 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 - /// call on NOTEs. + /// isBuiltinWarningOrExtension - 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 call on + /// NOTEs. static bool isBuiltinWarningOrExtension(unsigned DiagID); + /// \brief Return true if the specified diagnostic is mapped to errors by + /// default. + static bool isDefaultMappingAsError(unsigned DiagID); + /// \brief Determine whether the given built-in diagnostic ID is a /// Note. static bool isBuiltinNote(unsigned DiagID); @@ -132,7 +169,7 @@ public: /// 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. - static llvm::StringRef getWarningOptionForDiag(unsigned DiagID); + static StringRef getWarningOptionForDiag(unsigned DiagID); /// getCategoryNumberForDiag - Return the category number that a specified /// DiagID belongs to, or 0 if no category. @@ -143,7 +180,7 @@ public: /// getCategoryNameFromID - Given a category ID, return the name of the /// category. - static llvm::StringRef getCategoryNameFromID(unsigned CategoryID); + static StringRef getCategoryNameFromID(unsigned CategoryID); /// \brief Enumeration describing how the the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. @@ -182,56 +219,80 @@ public: static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); /// getName - Given a diagnostic ID, return its name - static llvm::StringRef getName(unsigned DiagID); + static StringRef getName(unsigned DiagID); /// getIdFromName - Given a diagnostic name, return its ID, or 0 - static unsigned getIdFromName(llvm::StringRef Name); + static unsigned getIdFromName(StringRef Name); /// getBriefExplanation - Given a diagnostic ID, return a brief explanation /// of the issue - static llvm::StringRef getBriefExplanation(unsigned DiagID); + static StringRef getBriefExplanation(unsigned DiagID); /// getFullExplanation - Given a diagnostic ID, return a full explanation /// of the issue - static llvm::StringRef getFullExplanation(unsigned DiagID); + static StringRef getFullExplanation(unsigned DiagID); + + /// Iterator class used for traversing all statically declared + /// diagnostics. + class diag_iterator { + const void *impl; -private: - /// 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. - bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, - SourceLocation Loc, Diagnostic &Diag) const; + friend class DiagnosticIDs; + diag_iterator(const void *im) : impl(im) {} + public: + diag_iterator &operator++(); + bool operator==(const diag_iterator &x) const { return impl == x.impl; } + bool operator!=(const diag_iterator &x) const { return impl != x.impl; } + + llvm::StringRef getDiagName() const; + unsigned getDiagID() const; + }; - /// \brief Based on the way the client configured the Diagnostic + static diag_iterator diags_begin(); + static diag_iterator diags_end(); + + /// \brief Get the set of all diagnostic IDs in the group with the given name. + /// + /// \param Diags [out] - On return, the diagnostics in the group. + /// \returns True if the given group is unknown, false otherwise. + bool getDiagnosticsInGroup(StringRef Group, + llvm::SmallVectorImpl<diag::kind> &Diags) const; + +private: + /// \brief Get the set of all diagnostic IDs in the given group. + /// + /// \param Diags [out] - On return, the diagnostics in the group. + void getDiagnosticsInGroup(const WarningOption *Group, + llvm::SmallVectorImpl<diag::kind> &Diags) const; + + /// \brief Based on the way the client configured the DiagnosticsEngine /// object, classify the specified diagnostic ID into a Level, consumable by /// the DiagnosticClient. /// /// \param Loc The source location we are interested in finding out the /// diagnostic state. Can be null in order to query the latest state. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, SourceLocation Loc, - const Diagnostic &Diag, - diag::Mapping *mapping = 0) const; + const DiagnosticsEngine &Diag) const; /// getDiagnosticLevel - This is an internal implementation helper used when /// DiagClass is already known. DiagnosticIDs::Level getDiagnosticLevel(unsigned DiagID, unsigned DiagClass, SourceLocation Loc, - const Diagnostic &Diag, - diag::Mapping *mapping = 0) const; + const DiagnosticsEngine &Diag) const; /// ProcessDiag - This is the method used to report a diagnostic that is /// finally fully formed. /// /// \returns true if the diagnostic was emitted, false if it was /// suppressed. - bool ProcessDiag(Diagnostic &Diag) const; + bool ProcessDiag(DiagnosticsEngine &Diag) const; /// \brief Whether the diagnostic may leave the AST in a state where some /// invariants can break. bool isUnrecoverable(unsigned DiagID) const; - friend class Diagnostic; + friend class DiagnosticsEngine; }; } // end namespace clang diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 38d6a80016559..9b3a178cac783 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -24,6 +24,11 @@ def escaped_newline_block_comment_end : Warning< def backslash_newline_space : Warning< "backslash and newline separated by space">; +// Digraphs. +def warn_cxx98_compat_less_colon_colon : Warning< + "'<::' is treated as digraph '<:' (aka '[') followed by ':' in C++98">, + InGroup<CXX98Compat>, DefaultIgnore; + // Trigraphs. def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>; def trigraph_ignored_block_comment : Warning< @@ -38,12 +43,16 @@ def ext_multi_line_bcpl_comment : Extension<"multi-line // comment">, def ext_bcpl_comment : Extension< "// comments are not allowed in this language">, InGroup<Comment>; -def ext_no_newline_eof : Extension<"no newline at end of file">; -def ext_backslash_newline_eof : Extension<"backslash-newline at end of file">; +def ext_no_newline_eof : Extension<"no newline at end of file">, + InGroup<DiagGroup<"newline-eof">>; def ext_dollar_in_identifier : Extension<"'$' in identifier">; def charize_microsoft_ext : Extension<"@# is a microsoft extension">; -def ext_token_used : Extension<"extension used">; +def ext_token_used : Extension<"extension used">, + InGroup<DiagGroup<"language-extension-token">>; + +def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">, + InGroup<CXX11Compat>; def warn_unterminated_string : ExtWarn<"missing terminating '\"' character">; def warn_unterminated_char : ExtWarn<"missing terminating ' character">; @@ -55,6 +64,18 @@ def err_unterminated___pragma : Error<"missing terminating ')' character">; def err_conflict_marker : Error<"version control conflict marker in file">; +def err_raw_delim_too_long : Error< + "raw string delimiter longer than 16 characters" + "; use PREFIX( )PREFIX to delimit raw string">; +def err_invalid_char_raw_delim : Error< + "invalid character '%0' character in raw string delimiter" + "; use PREFIX( )PREFIX to delimit raw string">; +def err_unterminated_raw_string : Error< + "raw string missing terminating delimiter )%0\"">; +def warn_cxx98_compat_raw_string_literal : Warning< + "raw string literals are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; + def ext_multichar_character_literal : ExtWarn< "multi-character character constant">, InGroup<MultiChar>; def ext_four_char_character_literal : Extension< @@ -77,17 +98,14 @@ def err_invalid_suffix_integer_constant : Error< "invalid suffix '%0' on integer constant">; def err_invalid_suffix_float_constant : Error< "invalid suffix '%0' on floating constant">; -def warn_extraneous_wide_char_constant : Warning< - "extraneous characters in wide character constant ignored">; +def warn_extraneous_char_constant : Warning< + "extraneous characters in character constant ignored">; def warn_char_constant_too_large : Warning< "character constant too long for its type">; def err_exponent_has_no_digits : Error<"exponent has no digits">; def ext_imaginary_constant : Extension<"imaginary constants are an extension">; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; -def ext_hexconstant_cplusplus : Extension< - "hexadecimal floating constants are a C99 feature that is incompatible with " - "C++0x">, InGroup<CXXHexFloats>; def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">; def ext_binary_literal : Extension< @@ -102,6 +120,11 @@ def warn_ucn_escape_too_large : ExtWarn< "character unicode escape sequence too long for its type">; def warn_ucn_not_valid_in_c89 : ExtWarn< "unicode escape sequences are only valid in C99 or C++">; +def warn_cxx98_compat_unicode_literal : Warning< + "unicode literals are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; +def err_unsupported_string_concat : Error< + "unsupported non-standard concatenation of string literals">; //===----------------------------------------------------------------------===// // PTH Diagnostics @@ -167,6 +190,9 @@ def ext_pp_bad_vaargs_use : Extension< def ext_pp_macro_redef : ExtWarn<"%0 macro redefined">; def ext_variadic_macro : Extension<"variadic macros were introduced in C99">, InGroup<VariadicMacros>; +def warn_cxx98_compat_variadic_macro : Warning< + "variadic macros are incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; def ext_named_variadic_macro : Extension< "named variadic macros are a GNU extension">, InGroup<VariadicMacros>; def ext_embedded_directive : Extension< @@ -175,10 +201,13 @@ def ext_missing_varargs_arg : Extension< "varargs argument missing, but tolerated as an extension">; def ext_empty_fnmacro_arg : Extension< "empty macro arguments were standardized in C99">; +def warn_cxx98_compat_empty_fnmacro_arg : Warning< + "empty macro argument list is incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; def err_pp_invalid_directive : Error<"invalid preprocessing directive">; def err_pp_hash_error : Error<"#error%0">; -def warn_pp_file_not_found : Warning<"'%0' file not found">, DefaultFatal; +def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; def err_pp_empty_filename : Error<"empty filename">; @@ -230,6 +259,13 @@ def err_pp_used_poisoned_id : Error<"attempt to use a poisoned identifier">; def err_feature_check_malformed : Error< "builtin feature check macro requires a parenthesized identifier">; +def err_warning_check_malformed : Error< + "builtin warning check macro requires a parenthesized string">, + InGroup<MalformedWarningCheck>; +def warn_has_warning_invalid_option : + ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">, + InGroup<MalformedWarningCheck>; + def err__Pragma_malformed : Error< "_Pragma takes a parenthesized string literal">; def err_pragma_comment_malformed : Error< @@ -315,5 +351,20 @@ def err_pp_linemarker_invalid_pop : Error< "invalid line marker flag '2': cannot pop empty include stack">; def ext_pp_line_too_big : Extension< "C requires #line number to be less than %0, allowed as extension">; +def warn_cxx98_compat_pp_line_too_big : Warning< + "#line number greater than 32767 is incompatible with C++98">, + InGroup<CXX98CompatPedantic>, DefaultIgnore; + +def err_pp_export_non_macro : Error<"no macro named %0 to export">; + +def err_pp_arc_cf_code_audited_syntax : Error<"expected 'begin' or 'end'">; +def err_pp_double_begin_of_arc_cf_code_audited : Error< + "already inside '#pragma clang arc_cf_code_audited'">; +def err_pp_unmatched_end_of_arc_cf_code_audited : Error< + "not currently inside '#pragma clang arc_cf_code_audited'">; +def err_pp_include_in_arc_cf_code_audited : Error< + "cannot #include files inside '#pragma clang arc_cf_code_audited'">; +def err_pp_eof_in_arc_cf_code_audited : Error< + "'#pragma clang arc_cf_code_audited' was not ended within this file">; } diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 3764a4091546b..73437b217b186 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -28,10 +28,6 @@ def ext_extra_struct_semi : Extension< def ext_extra_ivar_semi : Extension< "extra ';' inside instance variable list">; -def auto_storage_class : ExtWarn< - "'auto' storage class specifier is redundant and will be " - "removed in future releases">; - def ext_duplicate_declspec : Extension<"duplicate '%0' declaration specifier">; def ext_plain_complex : ExtWarn< "plain '_Complex' requires a type specifier; assuming '_Complex double'">; @@ -57,7 +53,7 @@ def ext_c99_variable_decl_in_for_loop : Extension< def ext_c99_compound_literal : Extension< "compound literals are a C99-specific feature">; def ext_enumerator_list_comma : Extension< - "commas at the end of enumerator lists are a %select{C99|C++0x}0-specific " + "commas at the end of enumerator lists are a %select{C99|C++11}0-specific " "feature">; def err_enumerator_list_missing_comma : Error< "missing ',' between enumerators">; @@ -68,12 +64,15 @@ def ext_ms_enum_fixed_underlying_type : Extension< InGroup<Microsoft>; def ext_c1x_generic_selection : Extension< - "generic selections are a C1X-specific feature">; + "generic selections are a C1X-specific feature">, InGroup<C1X>; def err_duplicate_default_assoc : Error< "duplicate default generic association">; def note_previous_default_assoc : Note< "previous default generic association is here">; +def ext_c1x_alignas : Extension< + "_Alignas is a C1X-specific feature">, InGroup<C1X>; + def ext_gnu_indirect_goto : Extension< "use of GNU indirect-goto extension">, InGroup<GNU>; def ext_gnu_address_of_label : Extension< @@ -188,16 +187,26 @@ def err_invalid_reference_qualifier_application : Error< def err_illegal_decl_reference_to_reference : Error< "%0 declared as a reference to a reference">; def ext_rvalue_reference : ExtWarn< - "rvalue references are a C++0x extension">, InGroup<CXX0x>; + "rvalue references are a C++11 extension">, InGroup<CXX11>; def ext_ref_qualifier : ExtWarn< - "reference qualifiers on functions are a C++0x extension">, InGroup<CXX0x>; + "reference qualifiers on functions are a C++11 extension">, InGroup<CXX11>; def ext_inline_namespace : ExtWarn< - "inline namespaces are a C++0x feature">, InGroup<CXX0x>; + "inline namespaces are a C++11 feature">, InGroup<CXX11>; def err_generalized_initializer_lists : Error< - "generalized initializer lists are a C++0x extension unsupported in Clang">; + "generalized initializer lists are a C++11 extension unsupported in Clang">; def ext_generalized_initializer_lists : ExtWarn< - "generalized initializer lists are a C++0x extension unsupported in Clang">, - InGroup<CXX0x>; + "generalized initializer lists are a C++11 extension unsupported in Clang">, + InGroup<CXX11>; +def ext_auto_type_specifier : ExtWarn< + "'auto' type specifier is a C++11 extension">, InGroup<CXX11>; +def warn_auto_storage_class : Warning< + "'auto' storage class specifier is redundant and incompatible with C++11">, + InGroup<CXX11Compat>; +def ext_auto_storage_class : ExtWarn< + "'auto' storage class specifier is not permitted in C++11, and will not " + "be supported in future releases">; +def ext_for_range : ExtWarn< + "range-based for loop is a C++11 extension">, InGroup<CXX11>; def err_argument_required_after_attribute : Error< "argument required after attribute">; def err_missing_param : Error<"expected parameter declarator">; @@ -219,6 +228,9 @@ def err_typename_invalid_storageclass : Error< "type name does not allow storage class to be specified">; def err_typename_invalid_functionspec : Error< "type name does not allow function specifier to be specified">; +def err_typename_identifiers_only : Error< + "typename is allowed for identifiers only">; + def err_invalid_decl_spec_combination : Error< "cannot combine with previous '%0' declaration specifier">; def err_invalid_vector_decl_spec_combination : Error< @@ -250,7 +262,7 @@ def err_unexected_colon_in_nested_name_spec : Error< def err_bool_redeclaration : Error< "redeclaration of C++ built-in type 'bool'">; def ext_c1x_static_assert : Extension< - "_Static_assert is a C1X-specific feature">; + "_Static_assert is a C1X-specific feature">, InGroup<C1X>; /// Objective-C parser diagnostics def err_expected_minus_or_plus : Error< @@ -342,6 +354,8 @@ def err_destructor_template_id : Error< "destructor name %0 does not refer to a template">; def err_default_arg_unparsed : Error< "unexpected end of default argument expression">; +def err_parser_impl_limit_overflow : Error< + "parser recursion limit reached, program too complex">, DefaultFatal; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; @@ -357,10 +371,15 @@ def err_default_delete_in_multiple_declaration : Error< "'= %select{default|delete}0' is a function definition and must occur in a " "standalone declaration">; +def warn_cxx98_compat_alignas : Warning<"'alignas' is incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; +def warn_cxx98_compat_attribute : Warning< + "attributes are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; def err_cxx0x_attribute_forbids_arguments : Error< - "C++0x attribute '%0' cannot have an argument list">; + "C++11 attribute '%0' cannot have an argument list">; def err_cxx0x_attribute_requires_arguments : Error< - "C++0x attribute '%0' must have an argument list">; + "C++1 attribute '%0' must have an argument list">; def err_attributes_not_allowed : Error<"an attribute list cannot appear here">; /// C++ Templates @@ -385,7 +404,7 @@ def err_two_right_angle_brackets_need_space : Error< "a space is required between consecutive right angle brackets (use '> >')">; def warn_cxx0x_right_shift_in_template_arg : Warning< "use of right-shift operator ('>>') in template argument will require " - "parentheses in C++0x">; + "parentheses in C++11">; def err_multiple_template_declarators : Error< "%select{|a template declaration|an explicit template specialization|" "an explicit template instantiation}0 can " @@ -446,31 +465,31 @@ def err_missing_whitespace_digraph : Error< " which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">; def warn_deleted_function_accepted_as_extension: ExtWarn< - "deleted function definition accepted as a C++0x extension">, InGroup<CXX0x>; + "deleted function definition accepted as a C++11 extension">, InGroup<CXX11>; def warn_defaulted_function_accepted_as_extension: ExtWarn< - "defaulted function definition accepted as a C++0x extension">, - InGroup<CXX0x>; + "defaulted function definition accepted as a C++11 extension">, + InGroup<CXX11>; -// C++0x in-class member initialization +// C++11 in-class member initialization def warn_nonstatic_member_init_accepted_as_extension: ExtWarn< - "in-class initialization of non-static data member accepted as a C++0x extension">, - InGroup<CXX0x>; + "in-class initialization of non-static data member accepted as a C++11 extension">, + InGroup<CXX11>; def err_bitfield_member_init: Error< "bitfield member cannot have an in-class initializer">; def err_incomplete_array_member_init: Error< "array bound cannot be deduced from an in-class initializer">; -// C++0x alias-declaration +// C++11 alias-declaration def ext_alias_declaration : ExtWarn< - "alias declarations accepted as a C++0x extension">, InGroup<CXX0x>; + "alias declarations accepted as a C++11 extension">, InGroup<CXX11>; def err_alias_declaration_not_identifier : Error< "name defined in alias declaration must be an identifier">; def err_alias_declaration_specialization : Error< "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">; -// C++0x override control +// C++11 override control def ext_override_control_keyword : Extension< - "'%0' keyword accepted as a C++0x extension">, InGroup<CXX0x>; + "'%0' keyword accepted as a C++11 extension">, InGroup<CXX11>; def err_duplicate_virt_specifier : Error< "class member already marked '%0'">; @@ -487,6 +506,15 @@ def err_paren_sizeof_parameter_pack : Error< def err_sizeof_parameter_pack : Error< "expected parenthesized parameter pack name in 'sizeof...' expression">; +// C++11 lambda expressions +def err_expected_comma_or_rsquare : Error< + "expected ',' or ']' in lambda capture list">; +def err_this_captured_by_reference : Error< + "'this' cannot be captured by reference">; +def err_expected_capture : Error< + "expected variable name or 'this' in lambda capture list">; +def err_expected_lambda_body : Error<"expected body of lambda expression">; + // Availability attribute def err_expected_version : Error< "expected a version of the form 'major[.minor[.subminor]]'">; @@ -559,6 +587,14 @@ def err_seh___except_filter : Error< def err_seh___finally_block : Error< "%0 only allowed in __finally block">; - + } // end of Parse Issue category. + +let CategoryName = "Modules Issue" in { +def err_module_expected_ident : Error< + "expected a module name after '__import_module__'">; +def err_module_expected_semi : Error< + "expected a semicolon name after module name">; +} + } // end of Parser diagnostics diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 97414f23d796d..0fbf0cee0a5d7 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -23,7 +23,8 @@ def ext_expr_not_ice : Extension< // Semantic analysis of constant literals. def ext_predef_outside_function : Warning< - "predefined identifier is only valid inside function">; + "predefined identifier is only valid inside function">, + InGroup<DiagGroup<"predefined-identifier-outside-function">>; def warn_float_overflow : Warning< "magnitude of floating-point constant too large for type %0; maximum is %1">, InGroup<LiteralRange>; @@ -102,7 +103,7 @@ def ext_flexible_array_init : Extension< def ext_anon_param_requires_type_specifier : Extension< "type specifier required for unnamed parameter, defaults to int">; def err_bad_variable_name : Error< - "'%0' cannot be the name of a variable or data member">; + "%0 cannot be the name of a variable or data member">; def err_bad_parameter_name : Error< "'%0' cannot be the name of a parameter">; def err_parameter_name_omitted : Error<"parameter name omitted">; @@ -236,10 +237,10 @@ def err_maybe_falloff_nonvoid_block : Error< def err_falloff_nonvoid_block : Error< "control reaches end of non-void block">; def warn_suggest_noreturn_function : Warning< - "function could be attribute 'noreturn'">, + "%select{function|method}0 %1 could be declared with attribute 'noreturn'">, InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore; def warn_suggest_noreturn_block : Warning< - "block could be attribute 'noreturn'">, + "block could be declared with attribute 'noreturn'">, InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore; def warn_unreachable : Warning<"will never be executed">, InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore; @@ -264,8 +265,9 @@ 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; def warn_dyn_class_memaccess : Warning< - "%select{destination for|source of}0 this %1 call is a pointer to dynamic " - "class %2; vtable pointer will be overwritten">, + "%select{destination for|source of|first operand of|second operand of}0 this " + "%1 call is a pointer to dynamic class %2; vtable pointer will be " + "%select{overwritten|copied|moved|compared}3">, InGroup<DiagGroup<"dynamic-class-memaccess">>; def note_bad_memaccess_silence : Note< "explicitly cast the pointer to silence this warning">; @@ -278,18 +280,25 @@ def warn_sizeof_pointer_type_memaccess : Warning< "argument to 'sizeof' in %0 call is the same pointer type %1 as the " "%select{destination|source}2; expected %3 or an explicit length">, InGroup<DiagGroup<"sizeof-pointer-memaccess">>; +def warn_strlcpycat_wrong_size : Warning< + "size argument in %0 call appears to be size of the source; expected the size of " + "the destination">, + InGroup<DiagGroup<"strlcpy-strlcat-size">>; +def note_strlcpycat_wrong_size : Note< + "change size argument to be the size of the destination">; /// 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 warn_static_main : Warning<"'main' should not be declared static">, + InGroup<Main>; +def err_static_main : Error<"'main' is not allowed to be declared static">; +def err_inline_main : Error<"'main' is not allowed to be declared inline">; def err_main_template_decl : Error<"'main' cannot be a template">; def err_main_returns_nonint : Error<"'main' must return 'int'">; def err_main_surplus_args : Error<"too many parameters (%0) for 'main': " "must be 0, 2, or 3">; -def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">; +def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">, + InGroup<Main>; def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 " "parameter of 'main' (%select{argument count|argument array|environment|" "platform-specific data}0) must be of type %1">; @@ -303,6 +312,8 @@ def err_statically_allocated_object : Error< def err_object_cannot_be_passed_returned_by_value : Error< "interface type %1 cannot be %select{returned|passed}0 by value" "; did you forget * in %1">; +def err_parameters_retval_cannot_have_fp16_type : Error< + "%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; def warn_pragma_options_align_unsupported_option : Warning< "unsupported alignment option in '#pragma options align'">; @@ -383,27 +394,75 @@ def note_undef_method_impl : Note<"method definition for %0 not found">; def note_required_for_protocol_at : Note<"required for direct or indirect protocol %0">; +def warn_conflicting_overriding_ret_types : Warning< + "conflicting return type in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_ret_types : Warning< - "conflicting return type in implementation of %0: %1 vs %2">; + "conflicting return type in " + "implementation of %0: %1 vs %2">; + +def warn_conflicting_overriding_ret_type_modifiers : Warning< + "conflicting distributed object modifiers on return type " + "in declaration of %0">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_ret_type_modifiers : Warning< "conflicting distributed object modifiers on return type " "in implementation of %0">, InGroup<DiagGroup<"distributed-object-modifiers">>; + +def warn_non_covariant_overriding_ret_types : Warning< + "conflicting return type in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_non_covariant_ret_types : Warning< - "conflicting return type in implementation of %0: %1 vs %2">, + "conflicting return type in " + "implementation of %0: %1 vs %2">, InGroup<DiagGroup<"method-signatures">>, DefaultIgnore; +def warn_conflicting_overriding_param_types : Warning< + "conflicting parameter types in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_param_types : Warning< - "conflicting parameter types in implementation of %0: %1 vs %2">; + "conflicting parameter types in " + "implementation of %0: %1 vs %2">; def warn_conflicting_param_modifiers : Warning< "conflicting distributed object modifiers on parameter type " "in implementation of %0">, InGroup<DiagGroup<"distributed-object-modifiers">>; + +def warn_conflicting_overriding_param_modifiers : Warning< + "conflicting distributed object modifiers on parameter type " + "in declaration of %0">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + +def warn_non_contravariant_overriding_param_types : Warning< + "conflicting parameter types in " + "declaration of %0: %1 vs %2">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_non_contravariant_param_types : Warning< - "conflicting parameter types in implementation of %0: %1 vs %2">, + "conflicting parameter types in " + "implementation of %0: %1 vs %2">, InGroup<DiagGroup<"method-signatures">>, DefaultIgnore; + +def warn_conflicting_overriding_variadic :Warning< + "conflicting variadic declaration of method and its " + "implementation">, + InGroup<OverridingMethodMismatch>, DefaultIgnore; + def warn_conflicting_variadic :Warning< - "conflicting variadic declaration of method and its implementation">; + "conflicting variadic declaration of method and its " + "implementation">; + +def warn_category_method_impl_match:Warning< + "category is implementing a method which will also be implemented" + " by its primary class">, InGroup<ObjCProtocolMethodImpl>; def warn_implements_nscopying : Warning< "default assign attribute on property %0 which implements " @@ -437,12 +496,22 @@ def warn_property_attr_mismatch : Warning< def warn_objc_property_copy_missing_on_block : Warning< "'copy' attribute must be specified for the block property " "when -fobjc-gc-only is specified">; +def warn_objc_property_retain_of_block : Warning< + "retain'ed block property does not copy the block " + "- use copy attribute instead">, InGroup<ObjCRetainBlockProperty>; def warn_atomic_property_rule : Warning< - "writable atomic property %0 cannot pair a synthesized setter/getter " - "with a user defined setter/getter">; -def warn_ownin_getter_rule : Warning< + "writable atomic property %0 cannot pair a synthesized %select{getter|setter}1 " + "with a user defined %select{getter|setter}2">, + InGroup<DiagGroup<"atomic-property-with-user-defined-accessor">>; +def note_atomic_property_fixup_suggest : Note<"setter and getter must both be " + "synthesized, or both be user defined,or the property must be nonatomic">; +def warn_atomic_property_nontrivial_assign_op : Warning< + "atomic property of type %0 synthesizing setter using non-trivial assignment" + " operator">, InGroup<DiagGroup<"objc-property-atomic-setter-synthesis">>; +def warn_owning_getter_rule : Warning< "property's synthesized getter follows Cocoa naming" - " convention for returning 'owned' objects">; + " convention for returning 'owned' objects">, + InGroup<DiagGroup<"objc-property-matches-cocoa-ownership-rule">>; def warn_property_getter_owning_mismatch : Warning< "property declared as returning non-retained objects" "; getter returning retained objects">; @@ -456,6 +525,9 @@ def warn_default_atomic_custom_getter_setter : Warning< def err_use_continuation_class : Error< "illegal redeclaration of property in continuation class %0" " (attribute must be 'readwrite', while its primary must be 'readonly')">; +def warn_type_mismatch_continuation_class : Warning< + "type of property %0 in continuation class does not match " + "property type in primary class">, InGroup<ObjCContinuationPropertyType>; def err_use_continuation_class_redeclaration_readwrite : Error< "illegal redeclaration of 'readwrite' property in continuation class %0" " (perhaps you intended this to be a 'readwrite' redeclaration of a " @@ -489,7 +561,10 @@ def error_synthesize_weak_non_arc_or_gc : Error< def err_arc_perform_selector_retains : Error< "performSelector names a selector which retains the object">; def warn_arc_perform_selector_leaks : Warning< - "performSelector may cause a leak because its selector is unknown">; + "performSelector may cause a leak because its selector is unknown">, + InGroup<DiagGroup<"arc-performSelector-leaks">>; +def err_gc_weak_property_strong_type : Error< + "weak attribute declared on a __strong type property in GC mode">; def error_synthesized_ivar_yet_not_supported : Error< "instance variable synthesis not yet supported" @@ -511,6 +586,12 @@ def error_property_implemented : Error<"property %0 is already implemented">; def warn_objc_property_attr_mutually_exclusive : Warning< "property attributes '%0' and '%1' are mutually exclusive">, InGroup<ReadOnlySetterAttrs>, DefaultIgnore; +def warn_objc_missing_super_dealloc : Warning< + "method possibly missing a [super dealloc] call">, + InGroup<ObjCMissingSuperCalls>; +def warn_objc_missing_super_finalize : Warning< + "method possibly missing a [super finalize] call">, + InGroup<ObjCMissingSuperCalls>; def warn_undeclared_selector : Warning< "undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore; def warn_implicit_atomic_property : Warning< @@ -539,12 +620,12 @@ def err_unexpected_friend : Error< def ext_enum_friend : ExtWarn< "enumeration type %0 cannot be a friend">; def ext_nonclass_type_friend : ExtWarn< - "non-class friend type %0 is a C++0x extension">, InGroup<CXX0x>; + "non-class friend type %0 is a C++11 extension">, InGroup<CXX11>; def err_friend_is_member : Error< "friends cannot be members of the declaring class">; def ext_unelaborated_friend_type : ExtWarn< "specify '%select{struct|union|class|enum}0' to befriend %1; accepted " - "as a C++0x extension">, InGroup<CXX0x>; + "as a C++11 extension">, InGroup<CXX11>; 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< @@ -554,9 +635,15 @@ def err_tagless_friend_type_template : Error< "friend type templates must use an elaborated type">; def err_no_matching_local_friend : Error< "no matching function found in local scope">; +def err_no_matching_local_friend_suggest : Error< + "no matching function %0 found in local scope; did you mean %2">; def err_partial_specialization_friend : Error< "partial specialization cannot be declared as a friend">; - +def err_qualified_friend_def : Error< + "friend function definition cannot be qualified with '%0'">; +def err_friend_def_in_local_class : Error< + "friend function cannot be defined in a local class">; + def err_abstract_type_in_decl : Error< "%select{return|parameter|variable|field}0 type %1 is an abstract class">; def err_allocation_of_abstract_type : Error< @@ -963,7 +1050,7 @@ def warn_maybe_uninit_var_captured_by_block : Warning< "variable %0 may be uninitialized when captured by block">, InGroup<UninitializedMaybe>, DefaultIgnore; def note_var_fixit_add_initialization : Note< - "add initialization to silence this warning">; + "initialize the variable %0 to silence this warning">; def err_init_incomplete_type : Error<"initialization of incomplete type %0">; def err_temp_copy_no_viable : Error< @@ -991,11 +1078,11 @@ def err_temp_copy_deleted : Error< def err_temp_copy_incomplete : Error< "copying a temporary object of incomplete type %0">; -// C++0x decltype +// C++11 decltype def err_cannot_determine_declared_type_of_overloaded_function : Error< "cannot determine the type of an overloaded function">; -// C++0x auto +// C++11 auto def err_auto_variable_cannot_appear_in_own_initializer : Error< "variable %0 declared with 'auto' type cannot appear in its own initializer">; def err_illegal_decl_array_of_auto : Error< @@ -1028,7 +1115,7 @@ def err_auto_new_deduction_failure : Error< def err_auto_different_deductions : Error< "'auto' deduced as %0 in declaration of %1 and deduced as %2 in declaration of %3">; -// C++0x override control +// C++11 override control def override_keyword_only_allowed_on_virtual_member_functions : Error< "only virtual member functions can be marked '%0'">; def err_function_marked_override_not_overriding : Error< @@ -1036,16 +1123,16 @@ def err_function_marked_override_not_overriding : Error< def err_class_marked_final_used_as_base : Error< "base %0 is marked 'final'">; -// C++0x attributes +// C++11 attributes def err_repeat_attribute : Error<"'%0' attribute cannot be repeated">; -// C++0x [[final]] +// C++11 [[final]] def err_final_function_overridden : Error< "declaration of %0 overrides a 'final' function">; def err_final_base : Error< "derivation from 'final' %0">; -// C++0x scoped enumerations +// C++11 scoped enumerations def err_enum_invalid_underlying : Error< "non-integral type %0 is an invalid underlying type">; def err_enumerator_too_large : Error< @@ -1066,9 +1153,9 @@ def err_only_enums_have_underlying_types : Error< def err_incomplete_type_no_underlying_type : Error< "an incomplete enumeration type has no underlying type yet">; -// C++0x delegating constructors +// C++11 delegating constructors def err_delegation_0x_only : Error< - "delegating constructors are permitted only in C++0x">; + "delegating constructors are permitted only in C++11">; def err_delegating_initializer_alone : Error< "an initializer for a delegating constructor must appear alone">; def warn_delegating_ctor_cycle : Warning< @@ -1081,7 +1168,7 @@ def note_which_delegates_to : Note< def err_delegating_codegen_not_implemented : Error< "code generation for delegating constructors not implemented">; -// C++0x range-based for loop +// C++11 range-based for loop def err_for_range_decl_must_be_var : Error< "for range declaration must declare a variable">; def err_for_range_storage_class : Error< @@ -1102,7 +1189,88 @@ def err_for_range_begin_end_types_differ : Error< def note_for_range_type : Note<"range has type %0">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; - + +// C++11 constexpr +def err_invalid_constexpr : Error< + "%select{function parameter|typedef|non-static data member}0 " + "cannot be constexpr">; +def err_constexpr_tag : Error< + "%select{class|struct|union|enum}0 cannot be marked constexpr">; +def err_constexpr_dtor : Error<"destructor cannot be marked constexpr">; +def err_constexpr_no_declarators : Error< + "constexpr can only be used in variable and function declarations">; +def err_invalid_constexpr_var_decl : Error< + "constexpr variable declaration must be a definition">; +def err_constexpr_var_requires_init : Error< + "declaration of constexpr variable %0 requires an initializer">; +def err_constexpr_var_requires_const_init : Error< + "constexpr variable %0 must be initialized by a constant expression">; +def err_constexpr_redecl_mismatch : Error< + "%select{non-constexpr declaration of %0 follows constexpr declaration" + "|constexpr declaration of %0 follows non-constexpr declaration}1">; +def note_constexpr_redecl_mismatch : Note< + "previous declaration was %select{not |}0marked constexpr">; +def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; +def note_constexpr_tmpl_virtual : Note<"function template instantiation is not " + "constexpr because it is virtual">; +def err_constexpr_virtual_base : Error<"constexpr constructor not allowed in " + "%select{class|struct}0 with virtual base %plural{1:class|:classes}1">; +def note_constexpr_tmpl_virtual_base : Note<"constructor template instantiation is " + "not constexpr because %select{class|struct}0 has virtual base " + "%plural{1:class|:classes}1">; +def note_non_literal_virtual_base : Note<"%select{class|struct}0 with virtual " + "base %plural{1:class|:classes}1 is not a literal type">; +def note_constexpr_virtual_base_here : Note<"virtual base class declared here">; +def err_constexpr_non_literal_return : Error< + "constexpr function's return type %0 is not a literal type">; +def note_constexpr_tmpl_non_literal_return : Note< + "function template instantiation is not constexpr because return type %0 is " + "not a literal type">; +def err_constexpr_non_literal_param : Error< + "constexpr %select{function|constructor}1's %ordinal0 parameter type %2 is " + "not a literal type">; +def note_constexpr_tmpl_non_literal_param : Note< + "%select{function|constructor}1 template instantiation is not constexpr " + "because %ordinal0 parameter type %2 is not a literal type">; +def err_constexpr_body_invalid_stmt : Error< + "statement not allowed in constexpr %select{function|constructor}0">; +def err_constexpr_type_definition : Error< + "types cannot be defined in a constexpr %select{function|constructor}0">; +def err_constexpr_vla : Error< + "variably-modified type %0 cannot be used in a constexpr " + "%select{function|constructor}1">; +def err_constexpr_var_declaration : Error< + "variables cannot be declared in a constexpr %select{function|constructor}0">; +def err_constexpr_body_no_return : Error< + "no return statement in constexpr function">; +def err_constexpr_body_multiple_return : Error< + "multiple return statements in constexpr function">; +def note_constexpr_body_previous_return : Note< + "previous return statement is here">; +def err_constexpr_function_try_block : Error< + "function try block not allowed in constexpr %select{function|constructor}0">; +def err_constexpr_union_ctor_no_init : Error< + "constexpr union constructor does not initialize any member">; +def err_constexpr_ctor_missing_init : Error< + "constexpr constructor must initialize all members">; +def note_constexpr_ctor_missing_init : Note< + "member not initialized by constructor">; +def err_constexpr_method_non_literal : Error< + "non-literal type %0 cannot have constexpr members">; +def note_non_literal_no_constexpr_ctors : Note< + "%0 is not literal because it is not an aggregate and has no constexpr " + "constructors other than copy or move constructors">; +def note_non_literal_base_class : Note< + "%0 is not literal because it has base class %1 of non-literal type">; +def note_non_literal_field : Note< + "%0 is not literal because it has data member %1 of non-literal type %2">; +def note_non_literal_user_provided_dtor : Note< + "%0 is not literal because it has a user-provided destructor">; +def note_non_literal_nontrivial_dtor : Note< + "%0 is not literal because it has a non-trivial destructor">; +def note_non_literal_mutable_field : Note< + "%0 is not literal because it has a mutable data member">; + // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< "Objective-C declarations may only appear in global scope">; @@ -1119,11 +1287,8 @@ def err_attribute_wrong_number_arguments : Error< ":requires exactly %0 arguments}0">; def err_attribute_too_many_arguments : Error< "attribute takes no more than %0 argument%s0">; -def err_iboutletcollection_type : Error< - "invalid type %0 as argument of iboutletcollection attribute">; -def err_iboutletcollection_object_type : Error< - "%select{ivar|property}1 with iboutletcollection attribute must " - "have object type (invalid %0)">; +def err_attribute_too_few_arguments : Error< + "attribute takes at least %0 argument%s0">; def err_attribute_missing_parameter_name : Error< "attribute requires unquoted parameter">; def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; @@ -1131,6 +1296,10 @@ def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; def err_attribute_argument_not_int : Error< "'%0' attribute requires integer constant">; +def err_attribute_argument_not_class : Error< + "%0 attribute requires arguments that are class type or point to class type">; +def err_attribute_first_argument_not_int_or_bool : Error< + "%0 attribute first argument must be of int or bool type">; def err_attribute_argument_outof_range : Error< "init_priority attribute requires integer constant between " "101 and 65535 inclusive">; @@ -1186,6 +1355,8 @@ 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_attribute_address_function_type : Error< + "function type may not be qualified with an address space">; def err_as_qualified_auto_decl : Error< "automatic variable qualified with an address space">; def err_arg_with_address_space : Error< @@ -1196,6 +1367,8 @@ def err_attr_objc_ownership_redundant : Error< "the type %0 already has retainment attributes set on it">; def err_attribute_not_string : Error< "argument to %0 attribute was not a string literal">; +def err_only_annotate_after_access_spec : Error< + "access specifier can only have annotation attributes">; def err_attribute_section_invalid_for_target : Error< "argument to 'section' attribute is not valid for this target: %0">; def err_attribute_section_local_variable : Error< @@ -1238,13 +1411,13 @@ def warn_attribute_wrong_decl_type : Warning< "parameters and methods|functions, methods and blocks|" "classes and virtual methods|functions, methods, and parameters|" "classes|virtual methods|class members|variables|methods|" - "variables, functions and labels}1">; + "variables, functions and labels|fields and global variables}1">; def err_attribute_wrong_decl_type : Error< "%0 attribute only applies to %select{functions|unions|" "variables and functions|functions and methods|parameters|" "parameters and methods|functions, methods and blocks|" "classes and virtual methods|functions, methods, and parameters|" - "classes|virtual methods|class members|variables|methods}1">; + "classes|virtual methods|class members|variables|methods|structs}1">; def warn_function_attribute_wrong_type : Warning< "'%0' only applies to function types; type here is %1">; def warn_pointer_attribute_wrong_type : Warning< @@ -1268,6 +1441,9 @@ def err_cconv_varargs : Error< def err_regparm_mismatch : Error<"function declared with with regparm(%0) " "attribute was previously declared " "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">; +def err_returns_retained_mismatch : Error< + "function declared with the ns_returns_retained attribute " + "was previously declared without the ns_returns_retained attribute">; def err_objc_precise_lifetime_bad_type : Error< "objc_precise_lifetime only applies to retainable types; type here is %0">; def warn_objc_precise_lifetime_meaningless : Error< @@ -1276,6 +1452,11 @@ def warn_objc_precise_lifetime_meaningless : Error< def warn_label_attribute_not_unused : Warning< "The only valid attribute for labels is 'unused'">; def err_invalid_pcs : Error<"Invalid PCS type">; +def err_attribute_can_be_applied_only_to_value_decl : Error< + "%0 attribute can only be applied to value declarations">; +def warn_attribute_not_on_decl : Error< + "%0 attribute ignored when parsing type">; + // Availability attribute def warn_availability_unknown_platform : Warning< @@ -1284,6 +1465,68 @@ def warn_availability_version_ordering : Warning< "feature cannot be %select{introduced|deprecated|obsoleted}0 in %1 version " "%2 before it was %select{introduced|deprecated|obsoleted}3 in version %4; " "attribute ignored">; + +// Thread Safety Attributes +// Errors when parsing the attributes +def err_attribute_argument_out_of_range : Error< + "%0 attribute parameter %1 is out of bounds: " + "%plural{0:no parameters to index into|" + "1:can only be 1, since there is one parameter|" + ":must be between 1 and %2}2">; +def err_attribute_argument_not_lockable : Error< + "%0 attribute requires arguments whose type is annotated " + "with 'lockable' attribute">; +def err_attribute_decl_not_lockable : Error< + "%0 attribute can only be applied in a context annotated " + "with 'lockable' attribute">; +def warn_unlock_but_no_lock : Warning< + "unlocking '%0' that was not locked">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_double_lock : Warning< + "locking '%0' that is already locked">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_no_unlock : Warning< + "mutex '%0' is still locked at the end of function">, + InGroup<ThreadSafety>, DefaultIgnore; +// FIXME: improve the error message about locks not in scope +def warn_lock_at_end_of_scope : Warning< + "mutex '%0' is still locked at the end of its scope">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_expecting_lock_held_on_loop : Warning< + "expecting mutex '%0' to be locked at start of each loop">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_lock_exclusive_and_shared : Warning< + "mutex '%0' is locked exclusively and shared in the same scope">, + InGroup<ThreadSafety>, DefaultIgnore; +def note_lock_exclusive_and_shared : Note< + "the other lock of mutex '%0' is here">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_variable_requires_lock : Warning< + "%select{reading|writing}2 variable '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_var_deref_requires_lock : Warning< + "%select{reading|writing}2 the value pointed to by '%0' requires locking " + "%select{'%1'|'%1' exclusively}2">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_variable_requires_any_lock : Warning< + "%select{reading|writing}1 variable '%0' requires locking " + "%select{any mutex|any mutex exclusively}1">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_var_deref_requires_any_lock : Warning< + "%select{reading|writing}1 the value pointed to by '%0' requires locking " + "%select{any mutex|any mutex exclusively}1">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_fun_requires_lock : Warning< + "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_fun_excludes_mutex : Warning< + "cannot call function '%0' while mutex '%1' is locked">, + InGroup<ThreadSafety>, DefaultIgnore; +def warn_cannot_resolve_lock : Warning< + "cannot resolve lock expression to a specific lockable object">, + InGroup<ThreadSafety>, DefaultIgnore; + def warn_impcast_vector_scalar : Warning< "implicit conversion turns vector to scalar: %0 to %1">, @@ -1319,13 +1562,14 @@ def warn_impcast_literal_float_to_integer : Warning< "implicit conversion turns literal floating-point number into integer: " "%0 to %1">, InGroup<DiagGroup<"literal-conversion">>, DefaultIgnore; -def note_fix_integral_float_as_integer : Note< - "this can be rewritten as an integer literal with the exact same value">; +def warn_impcast_string_literal_to_bool : Warning< + "implicit conversion turns string literal into bool: %0 to %1">, + InGroup<DiagGroup<"string-conversion">>, DefaultIgnore; def warn_impcast_different_enum_types : Warning< "implicit conversion from enumeration type %0 to different enumeration type " "%1">, InGroup<DiagGroup<"conversion">>; def warn_impcast_bool_to_null_pointer : Warning< - "initialization of pointer of type %0 to NULL from a constant boolean " + "initialization of pointer of type %0 to null from a constant boolean " "expression">, InGroup<BoolConversions>; def warn_impcast_null_pointer_to_integer : Warning< "implicit conversion of NULL constant to integer">, @@ -1398,6 +1642,11 @@ def warn_attribute_iboutlet : Warning< "%0 attribute can only be applied to instance variables or properties">; def warn_attribute_ibaction: Warning< "ibaction attribute can only be applied to Objective-C instance methods">; +def err_iboutletcollection_type : Error< + "invalid type %0 as argument of iboutletcollection attribute">; +def err_iboutlet_object_type : Error< + "%select{ivar|property}2 with %0 attribute must " + "be an object type (invalid %1)">; def err_attribute_overloadable_not_function : Error< "'overloadable' attribute can only be applied to a function">; def err_attribute_overloadable_missing : Error< @@ -1409,10 +1658,12 @@ def err_attribute_overloadable_no_prototype : Error< "'overloadable' function %0 must have a prototype">; def warn_ns_attribute_wrong_return_type : Warning< "%0 attribute only applies to %select{functions|methods}1 that " - "return %select{an Objective-C object|a pointer}2">; + "return %select{an Objective-C object|a pointer|a non-retainable pointer}2">; def warn_ns_attribute_wrong_parameter_type : Warning< "%0 attribute only applies to %select{Objective-C object|pointer}1 " "parameters">; +def err_ns_bridged_not_interface : Error< + "parameter of 'ns_bridged' attribute does not name an Objective-C class">; // Function Parameter Semantic Analysis. def err_param_with_void_type : Error<"argument may not have 'void' type">; @@ -1572,6 +1823,16 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate " "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 " "not viable: cannot convert argument of incomplete type %2 to %3">; +def note_ovl_candidate_bad_list_argument : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0%1 " + "not viable: cannot convert initializer list argument to %3">; def note_ovl_candidate_bad_overload : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -1592,7 +1853,22 @@ def note_ovl_candidate_bad_conv : Note<"candidate " "function (the implicit move assignment operator)|" "constructor (inherited)}0%1" " not viable: no known conversion from %2 to %3 for " - "%select{%ordinal5 argument|object argument}4">; + "%select{%ordinal5 argument|object argument}4; " + "%select{|dereference the argument with *|" + "take the address of the argument with &|" + "remove *|" + "remove &}6">; +def note_ovl_candidate_bad_arc_conv : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0%1" + " not viable: cannot implicitly convert argument of type %2 to %3 for " + "%select{%ordinal5 argument|object argument}4 under ARC">; def note_ovl_candidate_bad_addrspace : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -1620,15 +1896,18 @@ def note_ovl_candidate_bad_ownership : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) has " "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership," " but parameter has %select{no|__unsafe_unretained|__strong|__weak|" "__autoreleasing}4 ownership">; def note_ovl_candidate_bad_cvr_this : Note<"candidate " - "%select{|function|||function||||" - "function (the implicit copy assignment operator)|}0 not viable: " + "%select{|function|||function|||||" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|}0 not viable: " "'this' argument has type %2, but method is not marked " "%select{const|restrict|const or restrict|volatile|const or volatile|" "volatile or restrict|const, volatile, or restrict}3">; @@ -1658,6 +1937,17 @@ def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate " "%select{base class pointer|superclass|base class object of type}2 %3 to " "%select{derived class pointer|subclass|derived class reference}2 %4 for " "%ordinal5 argument">; +def note_ovl_candidate_bad_target : Note< + "candidate %select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "constructor (inherited)}0 not viable: call to " + "%select{__device__|__global__|__host__|__host__ __device__}1 function from" + " %select{__device__|__global__|__host__|__host__ __device__}2 function">; def note_ambiguous_type_conversion: Note< "because of ambiguity in conversion of %0 to %1">; @@ -1694,9 +1984,13 @@ def err_ovl_no_viable_subscript : Error<"no viable overloaded operator[] for type %0">; def err_ovl_no_oper : Error<"type %0 does not provide a %select{subscript|call}1 operator">; -def err_ovl_unresolvable : - Error<"cannot resolve overloaded function %0 from context">; - +def err_ovl_unresolvable : Error< + "reference to overloaded function could not be resolved; " + "did you mean to call it%select{| with no arguments}0?">; +def err_bound_member_function : Error< + "reference to non-static member function must be called" + "%select{|; did you mean to call it with no arguments?}0">; +def note_possible_target_of_call : Note<"possible target for call">; def err_ovl_no_viable_object_call : Error< "no matching function for call to object of type %0">; @@ -1761,8 +2055,8 @@ def note_template_param_prev_default_arg : Note< def err_template_param_default_arg_missing : Error< "template parameter missing a default argument">; def ext_template_parameter_default_in_function_template : ExtWarn< - "default template arguments for a function template are a C++0x extension">, - InGroup<CXX0x>; + "default template arguments for a function template are a C++11 extension">, + InGroup<CXX11>; def err_template_parameter_default_template_member : Error< "cannot add a default template argument to the definition of a member of a " "class template">; @@ -1774,6 +2068,9 @@ def err_template_template_parm_no_parms : Error< 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_member : Error<"member %0 declared as a template">; +def err_template_member_noparams : Error< + "extraneous 'template<>' in declaration of member %0">; def err_template_tag_noparams : Error< "extraneous 'template<>' in declaration of %0 %1">; def err_template_decl_ref : Error< @@ -1895,8 +2192,8 @@ def err_template_spec_decl_out_of_scope_global : Error< def ext_template_spec_decl_out_of_scope_global : ExtWarn< "%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; accepted as a C++0x extension">, - InGroup<CXX0x>; + "originally be declared in the global scope; accepted as a C++11 extension">, + InGroup<CXX11>; def err_template_spec_decl_out_of_scope : Error< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 must " @@ -1904,8 +2201,8 @@ def err_template_spec_decl_out_of_scope : Error< def ext_template_spec_decl_out_of_scope : ExtWarn< "%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; accepted as a C++0x extension">, - InGroup<CXX0x>; + "originally be declared in namespace %2; accepted as a C++11 extension">, + InGroup<CXX11>; def err_template_spec_redecl_out_of_scope : Error< "%select{class template|class template partial|function template|member " "function|static data member|member class}0 specialization of %1 not in a " @@ -1931,6 +2228,9 @@ def err_not_class_template_specialization : Error< "parameter}0">; def err_function_specialization_in_class : Error< "cannot specialize a function %0 within class scope">; +def ext_function_specialization_in_class : ExtWarn< + "explicit specialization of %0 within class scope is a Microsoft extension">, + InGroup<Microsoft>; def ext_explicit_specialization_storage_class : ExtWarn< "explicit specialization cannot have a storage class">; def err_explicit_specialization_inconsistent_storage_class : Error< @@ -2068,8 +2368,8 @@ def note_previous_explicit_instantiation : Note< "previous explicit instantiation is here">; def ext_explicit_instantiation_after_specialization : Extension< "explicit instantiation of %0 that occurs after an explicit " - "specialization will be ignored (C++0x extension)">, - InGroup<CXX0x>; + "specialization will be ignored (C++11 extension)">, + InGroup<CXX11>; def note_previous_template_specialization : Note< "previous template specialization is here">; def err_explicit_instantiation_enum : Error< @@ -2086,10 +2386,10 @@ def err_explicit_instantiation_must_be_global : Error< "explicit instantiation of %0 must occur at global scope">; def warn_explicit_instantiation_out_of_scope_0x : Warning< "explicit instantiation of %0 not in a namespace enclosing %1">, - InGroup<DiagGroup<"-Wc++0x-compat"> >; + InGroup<CXX11Compat>; def warn_explicit_instantiation_must_be_global_0x : Warning< "explicit instantiation of %0 must occur at global scope">, - InGroup<DiagGroup<"-Wc++0x-compat"> >; + InGroup<CXX11Compat>; def err_explicit_instantiation_requires_name : Error< "explicit instantiation declaration requires a name">; @@ -2114,6 +2414,8 @@ def note_explicit_instantiation_candidate : Note< "explicit instantiation candidate function template here %0">; def err_explicit_instantiation_inline : Error< "explicit instantiation cannot be 'inline'">; +def err_explicit_instantiation_constexpr : Error< + "explicit instantiation cannot be 'constexpr'">; def ext_explicit_instantiation_without_qualified_id : Extension< "qualifier in explicit instantiation of %q0 requires a template-id " "(a typedef is not permitted)">; @@ -2121,7 +2423,7 @@ def err_explicit_instantiation_unqualified_wrong_namespace : Error< "explicit instantiation of %q0 must occur in %1">; def warn_explicit_instantiation_unqualified_wrong_namespace_0x : Warning< "explicit instantiation of %q0 must occur in %1">, - InGroup<DiagGroup<"c++0x-compat"> >; + InGroup<CXX11Compat>; def err_explicit_instantiation_undefined_member : Error< "explicit instantiation of undefined %select{member class|member function|" "static data member}0 %1 of class template %2">; @@ -2142,9 +2444,10 @@ def note_typename_refers_here : Note< def err_typename_missing : Error< "missing 'typename' prior to dependent type name '%0%1'">; def warn_typename_missing : ExtWarn< - "missing 'typename' prior to dependent type name '%0%1'">; + "missing 'typename' prior to dependent type name '%0%1'">, + InGroup<DiagGroup<"typename-missing">>; def ext_typename_outside_of_template : ExtWarn< - "'typename' occurs outside of a template">, InGroup<CXX0x>; + "'typename' occurs outside of a template">, InGroup<CXX11>; def err_typename_refers_to_using_value_decl : Error< "typename specifier refers to a dependent using declaration for a value " "%0 in %1">; @@ -2162,7 +2465,7 @@ def note_referenced_class_template : Error< def err_template_kw_missing : Error< "missing 'template' keyword prior to dependent template name '%0%1'">; def ext_template_outside_of_template : ExtWarn< - "'template' keyword outside of a template">, InGroup<CXX0x>; + "'template' keyword outside of a template">, InGroup<CXX11>; def err_non_type_template_in_nested_name_specifier : Error< "qualified name refers into a specialization of function template '%0'">; @@ -2172,7 +2475,7 @@ def note_template_declared_here : Note< "%select{function template|class template|type alias template|template template parameter}0 " "%1 declared here">; -// C++0x Variadic Templates +// C++11 Variadic Templates def err_template_param_pack_default_arg : Error< "template parameter pack cannot have a default argument">; def err_template_param_pack_must_be_last_template_parameter : Error< @@ -2240,6 +2543,9 @@ def err_unexpected_typedef : Error< def err_unexpected_namespace : Error< "unexpected namespace name %0: expected expression">; def err_undeclared_var_use : Error<"use of undeclared identifier %0">; +def warn_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 " + "found via unqualified lookup into dependent bases of class templates is a " + "Microsoft extension">, InGroup<Microsoft>; def note_dependent_var_use : Note<"must qualify identifier to find this " "declaration in dependent base class">; def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither " @@ -2265,9 +2571,11 @@ def note_unavailable_here : Note< "%select{declaration|function}0 has been explicitly marked " "%select{unavailable|deleted|deprecated}1 here">; def warn_not_enough_argument : Warning< - "not enough variable arguments in %0 declaration to fit a sentinel">; + "not enough variable arguments in %0 declaration to fit a sentinel">, + InGroup<Sentinel>; def warn_missing_sentinel : Warning < - "missing sentinel in %select{function call|method dispatch|block call}0">; + "missing sentinel in %select{function call|method dispatch|block call}0">, + InGroup<Sentinel>; def note_sentinel_here : Note< "%select{function|method|block}0 has been explicitly marked sentinel here">; def warn_missing_prototype : Warning< @@ -2410,6 +2718,8 @@ def err_at_least_one_initializer_needed_to_size_array : Error< def err_array_size_non_int : Error<"size of array has non-integer type %0">; def err_init_element_not_constant : Error< "initializer element is not a compile-time constant">; +def err_local_cant_init : Error< + "'__local' variable cannot have an initializer">; def err_block_extern_cant_init : Error< "'extern' variable cannot have an initializer">; def warn_extern_init : Warning<"'extern' variable has an initializer">; @@ -2436,10 +2746,28 @@ def warn_braces_around_scalar_init : Warning< "braces around scalar initializer">; def warn_many_braces_around_scalar_init : ExtWarn< "too many braces around scalar initializer">; +def ext_complex_component_init : Extension< + "complex initialization specifying real and imaginary components " + "is an extension">, InGroup<DiagGroup<"complex-component-init">>; def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">; def err_illegal_initializer : Error< "illegal initializer (only variables can be initialized)">; def err_illegal_initializer_type : Error<"illegal initializer type %0">; +def err_init_list_variable_narrowing : Error< + "non-constant-expression cannot be narrowed from type %0 to %1 in " + "initializer list">; +def err_init_list_constant_narrowing : Error< + "constant expression evaluates to %0 which cannot be narrowed to type %1">; +def warn_init_list_variable_narrowing : Warning< + "non-constant-expression cannot be narrowed from type %0 to %1 in " + "initializer list in C++11">, + InGroup<CXX11Narrowing>, DefaultIgnore; +def warn_init_list_constant_narrowing : Warning< + "constant expression evaluates to %0 which cannot be narrowed to type %1 in " + "C++11">, + InGroup<CXX11Narrowing>, DefaultIgnore; +def note_init_list_narrowing_override : Note< + "override this message by inserting an explicit cast">; def err_init_objc_class : Error< "cannot initialize Objective-C class type %0">; def err_implicit_empty_initializer : Error< @@ -2474,6 +2802,8 @@ def warn_unused_label : Warning<"unused label %0">, InGroup<UnusedLabel>, DefaultIgnore; def err_goto_into_protected_scope : Error<"goto into protected scope">; +def warn_goto_into_protected_scope : ExtWarn<"goto into protected scope">, + InGroup<Microsoft>; def err_switch_into_protected_scope : Error< "switch case is in protected scope">; def err_indirect_goto_without_addrlabel : Error< @@ -2563,8 +2893,8 @@ def ext_flexible_array_in_struct : Extension< "%0 may not be nested in a struct due to flexible array member">; def ext_flexible_array_in_array : Extension< "%0 may not be used as an array element due to flexible array member">; -def err_flexible_array_init_nonempty : Error< - "non-empty initialization of flexible array member inside subobject">; +def err_flexible_array_init : Error< + "initialization of flexible array member is not allowed">; def ext_flexible_array_empty_aggregate_ms : Extension< "flexible array member %0 in otherwise empty %select{struct|class}1 " "is a Microsoft extension">, InGroup<Microsoft>; @@ -2603,7 +2933,7 @@ def err_arc_objc_object_in_struct : Error< "ARC forbids Objective-C objects in structs or unions">; def err_arc_objc_property_default_assign_on_object : Error< "ARC forbids synthesizing a property of an Objective-C object " - "with unspecified storage attribute">; + "with unspecified ownership or storage attribute">; def err_arc_illegal_selector : Error< "ARC forbids use of %0 in a @selector">; def err_arc_illegal_method_def : Error< @@ -2672,10 +3002,11 @@ def err_arc_method_not_found : Error< def err_arc_receiver_forward_class : Error< "receiver %0 for class message is a forward declaration">; def err_arc_may_not_respond : Error< - "receiver type %0 for instance message does not declare a method with " - "selector %1">; + "no visible @interface for %0 declares the selector %1">; def err_arc_receiver_forward_instance : Error< "receiver type %0 for instance message is a forward declaration">; +def err_arc_collection_forward : Error< + "collection expression type %0 is a forward declaration">; def err_arc_multiple_method_decl : Error< "multiple methods named %0 found with mismatched result, " "parameter type or attributes">; @@ -2696,9 +3027,10 @@ def err_arc_strong_property_ownership : Error< "existing ivar %1 for strong property %0 may not be " "%select{|__unsafe_unretained||__weak}2">; def err_arc_assign_property_ownership : Error< - "existing ivar %1 for unsafe_unretained property %0 must be __unsafe_unretained">; + "existing ivar %1 for property %0 with %select{unsafe_unretained| assign}2 " + "attribute must be __unsafe_unretained">; def err_arc_inconsistent_property_ownership : Error< - "%select{strong|weak|unsafe_unretained}1 property %0 may not also be " + "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be " "declared %select{|__unsafe_unretained|__strong|__weak|__autoreleasing}2">; def err_arc_atomic_ownership : Error< "cannot perform atomic operation on a pointer to type %0: type has " @@ -2759,6 +3091,10 @@ def err_block_with_return_type_requires_args : Error< "block with explicit return type requires argument list">; def err_func_def_incomplete_result : Error< "incomplete result type %0 in function definition">; +def err_atomic_specifier_bad_type : Error< + "_Atomic cannot be applied to " + "%select{incomplete |array |function |reference |atomic |qualified |}0type " + "%1 %select{||||||which is not trivially copyable}0">; // Expressions. def ext_sizeof_function_type : Extension< @@ -2793,8 +3129,10 @@ def warn_floatingpoint_eq : Warning< def warn_division_by_zero : Warning<"division by zero is undefined">; def warn_remainder_by_zero : Warning<"remainder by zero is undefined">; -def warn_shift_negative : Warning<"shift count is negative">; -def warn_shift_gt_typewidth : Warning<"shift count >= width of type">; +def warn_shift_negative : Warning<"shift count is negative">, + InGroup<DiagGroup<"shift-count-negative">>; +def warn_shift_gt_typewidth : Warning<"shift count >= width of type">, + InGroup<DiagGroup<"shift-count-overflow">>; def warn_shift_result_gt_typewidth : Warning< "signed shift result (%0) requires %1 bits to represent, but %2 only has " "%3 bits">, InGroup<DiagGroup<"shift-overflow">>; @@ -2820,8 +3158,12 @@ def note_precedence_conditional_silence : Note< "place parentheses around the '%0' expression to silence this warning">; def warn_logical_instead_of_bitwise : Warning< - "use of logical %0 with constant operand; switch to bitwise %1 or " - "remove constant">, InGroup<DiagGroup<"constant-logical-operand">>; + "use of logical '%0' with constant operand">, + InGroup<DiagGroup<"constant-logical-operand">>; +def note_logical_instead_of_bitwise_change_operator : Note< + "use '%0' for a bitwise operation">; +def note_logical_instead_of_bitwise_remove_constant : Note< + "remove constant to silence this warning">; def warn_bitwise_and_in_bitwise_or : Warning< "'&' within '|'">, InGroup<BitwiseOpParentheses>; @@ -2883,10 +3225,8 @@ def err_typecheck_member_reference_type : Error< def err_typecheck_member_reference_unknown : Error< "cannot refer to member %0 in %1 with '%select{.|->}2'">; def err_member_reference_needs_call : Error< - "base of member reference is %select{a function|an overloaded function}0; " - "perhaps you meant to call it%select{| with no arguments}1?">; -def note_member_ref_possible_intended_overload : Note< - "possibly valid overload here">; + "base of member reference is a function; perhaps you meant to call " + "it%select{| with no arguments}?">; def warn_subscript_is_char : Warning<"array subscript is of type 'char'">, InGroup<CharSubscript>, DefaultIgnore; @@ -2904,6 +3244,9 @@ def err_member_def_undefined_record : Error< "out-of-line definition of %0 from class %1 without definition">; def err_member_def_does_not_match : Error< "out-of-line definition of %0 does not match any declaration in %1">; +def err_member_def_does_not_match_suggest : Error< + "out-of-line definition of %0 does not match any declaration in %1; " + "did you mean %2">; def err_member_def_does_not_match_ret_type : Error< "out-of-line definition of %q0 differs from the declaration in the return type">; def err_nonstatic_member_out_of_line : Error< @@ -2922,6 +3265,12 @@ def warn_member_extra_qualification : Warning< def err_member_qualification : Error< "non-friend class member %0 cannot have a qualified name">; def note_member_def_close_match : Note<"member declaration nearly matches">; +def note_member_def_close_const_match : Note< + "member declaration does not match because " + "it %select{is|is not}0 const qualified">; +def note_member_def_close_param_match : Note< + "type of %ordinal0 parameter of member declaration does not match " + "definition (%1 vs %2)">; def err_typecheck_ivar_variable_size : Error< "instance variables must have a constant size">; def err_ivar_reference_type : Error< @@ -2938,7 +3287,8 @@ def err_typecheck_pointer_arith_void_type : Error< 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">; + "tentative definition of variable with internal linkage has incomplete non-array type %0">, + InGroup<DiagGroup<"tentative-definition-incomplete-type">>; def err_tentative_def_incomplete_type : Error< "tentative definition has type %0 that is never completed">; def err_tentative_def_incomplete_type_arr : Error< @@ -2969,7 +3319,8 @@ def warn_standalone_specifier : Warning<"'%0' ignored on this declaration">; def err_typecheck_sclass_func : Error<"illegal storage class on function">; def err_static_block_func : Error< "function declared in block scope cannot have 'static' storage class">; -def err_typecheck_address_of : Error<"address of %0 requested">; +def err_typecheck_address_of : Error<"address of %select{bit-field" + "|vector element|property expression|register variable}0 requested">; def ext_typecheck_addrof_void : Extension< "ISO C forbids taking the address of an expression of type 'void'">; def err_unqualified_pointer_member_function : Error< @@ -3039,9 +3390,6 @@ def err_stmtexpr_file_scope : Error< def warn_mixed_sign_comparison : Warning< "comparison of integers of different signs: %0 and %1">, InGroup<SignCompare>, DefaultIgnore; -def warn_mixed_sign_conditional : Warning< - "operands of ? are integers of different signs: %0 and %1">, - InGroup<SignCompare>, DefaultIgnore; def warn_lunsigned_always_true_comparison : Warning< "comparison of unsigned%select{| enum}2 expression %0 is always %1">, InGroup<TautologicalCompare>; @@ -3054,6 +3402,10 @@ def warn_comparison_of_mixed_enum_types : Warning< def warn_null_in_arithmetic_operation : Warning< "use of NULL in arithmetic operation">, InGroup<DiagGroup<"null-arithmetic">>; +def warn_null_in_comparison_operation : Warning< + "comparison between NULL and non-pointer " + "%select{(%1 and NULL)|(NULL and %1)}0">, + InGroup<DiagGroup<"null-arithmetic">>; def err_invalid_this_use : Error< "invalid use of 'this' outside of a nonstatic member function">; @@ -3140,7 +3492,9 @@ def error_nosetter_property_assignment : Error< "setter method is needed to assign to object using property" " assignment syntax">; def error_no_subobject_property_setting : Error< "expression is not assignable">; - +def err_qualified_objc_access : Error< + "%select{property|ivar}0 access cannot be qualified with '%1'">; + def ext_freestanding_complex : Extension< "complex numbers are an extension in a freestanding C99 implementation">; @@ -3205,10 +3559,11 @@ def err_incomplete_type_objc_at_encode : Error< def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " - "use @synthesize, @dynamic or provide a method implementation">; + "use @synthesize, @dynamic or provide a method implementation " + "in this class implementation">; def warn_setter_getter_impl_required_in_category : Warning< "property %0 requires method %1 to be defined - " - "use @dynamic or provide a method implementation in category">; + "use @dynamic or provide a method implementation in this category">; def note_property_impl_required : Note< "implementation is here">; def note_parameter_named_here : Note< @@ -3326,8 +3681,8 @@ def err_array_size_ambiguous_conversion : Error< "enumeration type">; def ext_array_size_conversion : Extension< "implicit conversion from array size expression of type %0 to " - "%select{integral|enumeration}1 type %2 is a C++0x extension">, - InGroup<CXX0x>; + "%select{integral|enumeration}1 type %2 is a C++11 extension">, + InGroup<CXX11>; def err_address_space_qualified_new : Error< "'new' cannot allocate objects of type %0 in address space '%1'">; def err_address_space_qualified_delete : Error< @@ -3343,7 +3698,7 @@ 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_delete_incomplete_class_type : Warning< +def err_delete_incomplete_class_type : Error< "deleting incomplete class type %0; no conversions to pointer type">; def warn_delete_array_type : Warning< "'delete' applied to a pointer-to-array type %0 treated as delete[]">; @@ -3385,6 +3740,9 @@ def warn_non_virtual_dtor : Warning< def warn_delete_non_virtual_dtor : Warning< "delete called on %0 that has virtual functions but non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, DefaultIgnore; +def warn_delete_abstract_non_virtual_dtor : Warning< + "delete called on %0 that is abstract but has non-virtual destructor">, + InGroup<DeleteNonVirtualDtor>; def warn_overloaded_virtual : Warning< "%q0 hides overloaded virtual %select{function|functions}1">, InGroup<OverloadedVirtual>, DefaultIgnore; @@ -3458,8 +3816,6 @@ def err_not_tag_in_scope : Error< 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 err_invalid_use_of_bound_member_func : Error< - "a bound member function may only be called">; def err_incomplete_object_call : Error< "incomplete type in call to object of type %0">; def err_incomplete_pointer_to_member_return : Error< @@ -3480,7 +3836,7 @@ def note_condition_assign_silence : Note< "place parentheses around the assignment to silence this warning">; def warn_equality_with_extra_parens : Warning<"equality comparison with " - "extraneous parentheses">, InGroup<Parentheses>; + "extraneous parentheses">, InGroup<ParenthesesOnEquality>; def note_equality_comparison_to_assign : Note< "use '=' to turn this equality comparison into an assignment">; def note_equality_comparison_silence : Note< @@ -3501,7 +3857,11 @@ def err_typecheck_convert_incompatible : Error< "%select{from incompatible type|to parameter of incompatible type|" "from a function with incompatible result type|to incompatible type|" "with an expression of incompatible type|to parameter of incompatible type|" - "to incompatible type}2 %1">; + "to incompatible type}2 %1; " + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">; def warn_incompatible_qualified_id : Warning< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " @@ -3514,13 +3874,21 @@ def ext_typecheck_convert_pointer_int : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">; + "with an expression of type|to parameter of type|to type}2 %1; " + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">; def ext_typecheck_convert_int_pointer : ExtWarn< "incompatible integer to pointer conversion " "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">; + "with an expression of type|to parameter of type|to type}2 %1; " + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">; def ext_typecheck_convert_pointer_void_func : Extension< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " @@ -3539,20 +3907,26 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">, - InGroup<DiagGroup<"incompatible-pointer-types">>; + "with an expression of type|to parameter of type|to type}2 %1" + "%select{|dereference with *|" + "take the address with &|" + "remove *|" + "remove &}3">, + InGroup<IncompatiblePointerTypes>; def ext_typecheck_convert_discards_qualifiers : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" "with an expression of type|to parameter of type|to type}2 %1 discards " - "qualifiers">; + "qualifiers">, + InGroup<IncompatiblePointerTypes>; def ext_nested_pointer_qualifier_mismatch : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" "with an expression of type|to parameter of type|to type}2 %1 discards " - "qualifiers in nested pointer types">; + "qualifiers in nested pointer types">, + InGroup<IncompatiblePointerTypes>; def warn_incompatible_vectors : Warning< "incompatible vector types " "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" @@ -3621,19 +3995,23 @@ def note_function_with_incomplete_return_type_declared_here : Note< def err_call_incomplete_argument : Error< "argument type %0 is incomplete">; def err_typecheck_call_too_few_args : Error< - "too few arguments to %select{function|block|method}0 call, " + "too few %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected %1, have %2">; def err_typecheck_call_too_few_args_at_least : Error< - "too few arguments to %select{function|block|method}0 call, " + "too few %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected at least %1, have %2">; def err_typecheck_call_too_many_args : Error< - "too many arguments to %select{function|block|method}0 call, " + "too many %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected %1, have %2">; -def note_typecheck_call_too_many_args : Note< - "%0 declared here">; def err_typecheck_call_too_many_args_at_most : Error< - "too many arguments to %select{function|block|method}0 call, " + "too many %select{|||execution configuration }0arguments to " + "%select{function|block|method|kernel function}0 call, " "expected at most %1, have %2">; +def note_callee_decl : Note< + "%0 declared here">; def warn_call_wrong_number_of_arguments : Warning< "too %select{few|many}0 arguments in call to %1">; def err_atomic_builtin_must_be_pointer : Error< @@ -3644,6 +4022,15 @@ def err_atomic_builtin_must_be_pointer_intptr : Error< def err_atomic_builtin_pointer_size : Error< "first argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte " "type (%0 invalid)">; +def err_atomic_op_needs_atomic : Error< + "first argument to atomic operation must be a pointer to _Atomic " + "type (%0 invalid)">; +def err_atomic_op_needs_atomic_int_or_ptr : Error< + "first argument to atomic operation must be a pointer to atomic " + "integer or pointer (%0 invalid)">; +def err_atomic_op_logical_needs_atomic_int : Error< + "first argument to logical atomic operation must be a pointer to atomic " + "integer (%0 invalid)">; def err_deleted_function_use : Error<"attempt to use a deleted function">; @@ -3653,6 +4040,11 @@ def err_config_scalar_return : Error< "CUDA special function 'cudaConfigureCall' must have scalar return type">; def err_kern_call_not_global_function : Error< "kernel call to non-global function %0">; +def err_global_call_not_config : Error< + "call to global function %0 not configured">; +def err_ref_bad_target : Error< + "reference to %select{__device__|__global__|__host__|__host__ __device__}0 " + "function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function">; def err_cannot_pass_objc_interface_to_vararg : Error< @@ -3696,9 +4088,11 @@ def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn< def err_cast_selector_expr : Error< "cannot type cast @selector expression">; def warn_typecheck_cond_incompatible_pointers : ExtWarn< - "pointer type mismatch (%0 and %1)">; + "pointer type mismatch (%0 and %1)">, + InGroup<DiagGroup<"pointer-type-mismatch">>; def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn< - "pointer/integer type mismatch in conditional expression (%0 and %1)">; + "pointer/integer type mismatch in conditional expression (%0 and %1)">, + InGroup<DiagGroup<"conditional-type-mismatch">>; def err_typecheck_choose_expr_requires_constant : Error< "'__builtin_choose_expr' requires a constant expression">; def ext_typecheck_expression_not_constant_but_accepted : Extension< @@ -3715,6 +4109,14 @@ def warn_unused_property_expr : Warning< def warn_unused_call : Warning< "ignoring return value of function declared with %0 attribute">, InGroup<UnusedValue>; +def warn_unused_result : Warning< + "ignoring return value of function declared with warn_unused_result " + "attribute">, InGroup<DiagGroup<"unused-result">>; +def warn_unused_comparison : Warning< + "%select{equality|inequality}0 comparison result unused">, + InGroup<UnusedComparison>; +def note_inequality_comparison_to_or_assign : Note< + "use '|=' to turn this inequality comparison into an or-assignment">; def err_incomplete_type_used_in_type_trait_expr : Error< "incomplete type %0 used in type trait expression">; @@ -3798,11 +4200,18 @@ def err_not_direct_base_or_virtual : Error< def err_in_class_initializer_non_const : Error< "non-const static data member must be initialized out of line">; +def err_in_class_initializer_volatile : Error< + "static const volatile data member must be initialized out of line">; def err_in_class_initializer_bad_type : Error< "static data member of type %0 must be initialized out of line">; def ext_in_class_initializer_float_type : ExtWarn< - "in-class initializer for static data member of type %0 " - "is a C++0x extension">, InGroup<CXX0xStaticNonIntegralInitializer>; + "in-class initializer for static data member of type %0 is a GNU extension">, + InGroup<GNU>; +def note_in_class_initializer_float_type_constexpr : Note< + "use 'constexpr' specifier to silence this warning">; +def err_in_class_initializer_literal_type : Error< + "in-class initializer for static data member of type %0 requires " + "'constexpr' specifier">; def err_in_class_initializer_non_constant : Error< "in-class initializer is not a constant expression">; @@ -3941,7 +4350,13 @@ def err_literal_operator_outside_namespace : Error< // FIXME: This diagnostic sucks def err_literal_operator_params : Error< "parameter declaration for literal operator %0 is not valid">; - +def warn_user_literal_hexfloat : Warning< + "user-defined literal with suffix '%0' is preempted by C99 hexfloat " + "extension">, InGroup<UserDefinedLiterals>; +def warn_user_literal_reserved : Warning< + "user-defined literals not starting with '_' are reserved by the " + "implementation">, InGroup<UserDefinedLiterals>; + // C++ conversion functions def err_conv_function_not_member : Error< "conversion function must be a non-static member function">; @@ -3969,11 +4384,11 @@ def warn_conv_to_void_not_used : Warning< def warn_not_compound_assign : Warning< "use of unary operator that may be intended as compound assignment (%0=)">; -// C++0x explicit conversion operators +// C++11 explicit conversion operators def warn_explicit_conversion_functions : Warning< - "explicit conversion functions are a C++0x extension">, InGroup<CXX0x>; + "explicit conversion functions are a C++11 extension">, InGroup<CXX11>; -// C++0x defaulted functions +// C++11 defaulted functions def err_defaulted_default_ctor_params : Error< "an explicitly-defaulted default constructor must have no parameters">; def err_defaulted_copy_ctor_params : Error< @@ -4000,8 +4415,34 @@ def err_defaulted_copy_assign_const_param : Error< "the parameter for this explicitly-defaulted copy assignment operator is " "const, but a member or base requires it to be non-const">; def err_defaulted_copy_assign_quals : Error< - "an explicitly-defaulted copy assignment operator may not have 'const' " - "or 'volatile' qualifiers">; + "an explicitly-defaulted copy assignment operator may not have 'const', " + "'constexpr' or 'volatile' qualifiers">; +def err_defaulted_move_ctor_params : Error< + "an explicitly-defaulted move constructor must have exactly one parameter">; +def err_defaulted_move_ctor_volatile_param : Error< + "the parameter for an explicitly-defaulted move constructor may not be " + "volatile">; +def err_defaulted_move_ctor_const_param : Error< + "the parameter for an explicitly-defaulted move constructor may not be " + "const">; +def err_defaulted_move_assign_params : Error< + "an explicitly-defaulted move assignment operator must have exactly one " + "parameter">; +def err_defaulted_move_assign_return_type : Error< + "an explicitly-defaulted move assignment operator must return an unqualified " + "lvalue reference to its class type">; +def err_defaulted_move_assign_not_ref : Error< + "the parameter for an explicitly-defaulted move assignment operator must be an " + "rvalue reference type">; +def err_defaulted_move_assign_volatile_param : Error< + "the parameter for an explicitly-defaulted move assignment operator may not " + "be volatile">; +def err_defaulted_move_assign_const_param : Error< + "the parameter for an explicitly-defaulted move assignment operator may not " + "be const">; +def err_defaulted_move_assign_quals : Error< + "an explicitly-defaulted move assignment operator may not have 'const', " + "'constexpr' or 'volatile' qualifiers">; def err_incorrect_defaulted_exception_spec : Error< "exception specification of explicitly defaulted %select{default constructor|" "copy constructor|move constructor|copy assignment operator|move assignment " @@ -4011,15 +4452,20 @@ def err_out_of_line_default_deletes : Error< "defaulting this %select{default constructor|copy constructor|move " "constructor|copy assignment operator|move assignment operator|destructor}0 " "would delete it after its first declaration">; -def err_defaulted_move_unsupported : Error< - "defaulting move functions not yet supported">; +def warn_ptr_arith_precedes_bounds : Warning< + "the pointer decremented by %0 refers before the beginning of the array">, + InGroup<DiagGroup<"array-bounds-pointer-arithmetic">>, DefaultIgnore; +def warn_ptr_arith_exceeds_bounds : Warning< + "the pointer incremented by %0 refers past the end of the array (that " + "contains %1 element%s2)">, + InGroup<DiagGroup<"array-bounds-pointer-arithmetic">>, DefaultIgnore; def warn_array_index_precedes_bounds : Warning< "array index of '%0' indexes before the beginning of the array">, InGroup<DiagGroup<"array-bounds">>; def warn_array_index_exceeds_bounds : Warning< - "array index of '%0' indexes past the end of an array (that contains %1 elements)">, - InGroup<DiagGroup<"array-bounds">>; + "array index of '%0' indexes past the end of an array (that contains %1 " + "element%s2)">, InGroup<DiagGroup<"array-bounds">>; def note_array_index_out_of_bounds : Note< "array %0 declared here">; @@ -4031,7 +4477,7 @@ def warn_printf_insufficient_data_args : Warning< def warn_printf_data_arg_not_used : Warning< "data argument not used by format string">, InGroup<FormatExtraArgs>; def warn_format_invalid_conversion : Warning< - "invalid conversion specifier '%0'">, InGroup<Format>; + "invalid conversion specifier '%0'">, InGroup<FormatInvalidSpecifier>; def warn_printf_incomplete_specifier : Warning< "incomplete format specifier">, InGroup<Format>; def warn_missing_format_string : Warning< @@ -4086,20 +4532,38 @@ def warn_scanf_scanlist_incomplete : Warning< // CHECK: returning address/reference of stack memory def warn_ret_stack_addr : Warning< - "address of stack memory associated with local variable %0 returned">; + "address of stack memory associated with local variable %0 returned">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_stack_ref : Warning< - "reference to stack memory associated with local variable %0 returned">; + "reference to stack memory associated with local variable %0 returned">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_local_temp_addr : Warning< - "returning address of local temporary object">; + "returning address of local temporary object">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_local_temp_ref : Warning< - "returning reference to local temporary object">; + "returning reference to local temporary object">, + InGroup<DiagGroup<"return-stack-address">>; def warn_ret_addr_label : Warning< - "returning address of label, which is local">; + "returning address of label, which is local">, + InGroup<DiagGroup<"return-stack-address">>; def err_ret_local_block : Error< "returning block that lives on the local stack">; def note_ref_var_local_bind : Note< "binding reference variable %0 here">; +// Check for initializing a member variable with the address or a reference to +// a constructor parameter. +def warn_bind_ref_member_to_parameter : Warning< + "binding reference member %0 to stack allocated parameter %1">, + InGroup<DiagGroup<"dangling-field">>; +def warn_init_ptr_member_to_parameter_addr : Warning< + "initializing pointer member %0 with the stack address of parameter %1">, + InGroup<DiagGroup<"dangling-field">>; +def warn_bind_ref_member_to_temporary : Warning< + "binding reference member %0 to a temporary value">, + InGroup<DiagGroup<"dangling-field">>; +def note_ref_or_ptr_member_declared_here : Note< + "%select{reference|pointer}0 member declared here">; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -4110,7 +4574,8 @@ def warn_comparison_always : Warning< def warn_stringcompare : Warning< "result of comparison against %select{a string literal|@encode}0 is " - "unspecified (use strncmp instead)">; + "unspecified (use strncmp instead)">, + InGroup<DiagGroup<"string-compare">>; // Generic selections. def err_assoc_type_incomplete : Error< @@ -4138,13 +4603,18 @@ def err_return_in_block_expression : Error< def err_block_returning_array_function : Error< "block cannot return %select{array|function}0 type %1">; +// Builtin annotation string. +def err_builtin_annotation_not_string_constant : Error< + "__builtin_annotation requires a non wide string constant">; // CFString checking def err_cfstring_literal_not_string_constant : Error< - "CFString literal is not a string constant">; + "CFString literal is not a string constant">, + InGroup<DiagGroup<"CFString-literal">>; def warn_cfstring_truncated : Warning< "input conversion stopped due to an input byte that does not " - "belong to the input codeset UTF-8">; + "belong to the input codeset UTF-8">, + InGroup<DiagGroup<"CFString-literal">>; // Statements. def err_continue_not_in_loop : Error< @@ -4208,6 +4678,9 @@ def err_second_parameter_to_va_arg_abstract: Error< def warn_second_parameter_to_va_arg_not_pod : Warning< "second argument to 'va_arg' is of non-POD type %0">, InGroup<DiagGroup<"non-pod-varargs">>, DefaultError; +def warn_second_parameter_to_va_arg_ownership_qualified : Warning< + "second argument to 'va_arg' is of ARC ownership-qualified type %0">, + InGroup<DiagGroup<"non-pod-varargs">>, DefaultError; def warn_second_parameter_to_va_arg_never_compatible : Warning< "second argument to 'va_arg' is of promotable type %0; this va_arg has " "undefined behavior because arguments will be promoted to %1">; @@ -4306,13 +4779,20 @@ def err_c99_array_usage_cxx : Error< "C99-specific array features are not permitted in C++">; def err_double_requires_fp64 : Error< "use of type 'double' requires cl_khr_fp64 extension to be enabled">; +def err_nsconsumed_attribute_mismatch : Error< + "overriding method has mismatched ns_consumed attribute on its" + " parameter">; +def err_nsreturns_retained_attribute_mismatch : Error< + "overriding method has mismatched ns_returns_%select{not_retained|retained}0" + " attributes">; def note_getter_unavailable : Note< "or because setter is declared here, but no getter method %0 is found">; def err_invalid_protocol_qualifiers : Error< "invalid protocol qualifiers on non-ObjC type">; def warn_ivar_use_hidden : Warning< - "local declaration of %0 hides instance variable">; + "local declaration of %0 hides instance variable">, + InGroup<DiagGroup<"shadow-ivar">>; def error_ivar_use_in_class_method : Error< "instance variable %0 accessed in class method">; def error_implicit_ivar_access : Error< @@ -4327,6 +4807,9 @@ def warn_attribute_method_def : Warning< def ext_typecheck_base_super : Warning< "method parameter type %0 does not match " "super class method parameter type %1">, InGroup<SuperSubClassMismatch>, DefaultIgnore; +def warn_missing_method_return_type : Warning< + "method has no return type specified; defaults to 'id'">, + InGroup<MissingMethodReturnType>, DefaultIgnore; // Spell-checking diagnostics def err_unknown_typename_suggest : Error< @@ -4377,9 +4860,12 @@ def err_sizeof_pack_no_pack_name_suggest : Error< def note_parameter_pack_here : Note<"parameter pack %0 declared here">; def err_uncasted_use_of_unknown_any : Error< - "%0 has unknown type; cast it to its declared type to use it">; + "%0 has unknown type; cast it to its declared type to use it">; def err_uncasted_call_of_unknown_any : Error< - "%0 has unknown return type; cast the call to its declared return type">; + "%0 has unknown return type; cast the call to its declared return type">; +def err_uncasted_send_to_unknown_any_method : Error< + "no known method %select{%objcinstance1|%objcclass1}0; cast the " + "message send to the method's return type">; def err_unsupported_unknown_any_decl : Error< "%0 has unknown type, which is unsupported for this kind of declaration">; def err_unsupported_unknown_any_expr : Error< @@ -4391,6 +4877,8 @@ def err_unknown_any_addrof : Error< "can only be cast to a pointer type">; def err_unknown_any_var_function_type : Error< "variable %0 with unknown type cannot be given a function type">; +def err_unknown_any_function : Error< + "function %0 with unknown type must be given a function type">; def err_filter_expression_integral : Error< "filter expression type should be an integral value not %0">; @@ -4409,14 +4897,31 @@ def warn_related_result_type_compatibility_class : Warning< def warn_related_result_type_compatibility_protocol : Warning< "protocol method is expected to return an instance of the implementing " "class, but is declared to return %0">; -def note_related_result_type_overridden : Note< +def note_related_result_type_overridden_family : Note< "overridden method is part of the '%select{|alloc|copy|init|mutableCopy|" - "new|autorelease|dealloc|release|retain|retainCount|self}0' method family">; + "new|autorelease|dealloc|finalize|release|retain|retainCount|self}0' method " + "family">; +def note_related_result_type_overridden : Note< + "overridden method returns an instance of its class type">; def note_related_result_type_inferred : Note< "%select{class|instance}0 method %1 is assumed to return an instance of " "its receiver type (%2)">; } +let CategoryName = "Modules Issue" in { +def err_module_private_follows_public : Error< + "__module_private__ declaration of %0 follows public declaration">; +def err_module_private_specialization : Error< + "%select{template|partial|member}0 specialization cannot be " + "declared __module_private__">; +def err_module_private_local : Error< + "%select{local variable|parameter|typedef}0 %1 cannot be declared " + "__module_private__">; +def err_module_private_local_class : Error< + "local %select{struct|union|class|enum}0 cannot be declared " + "__module_private__">; +} + } // end of sema component. diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index 1324533fa03e8..ea8ed9f02fed7 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_FILEMANAGER_H #include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -123,9 +124,9 @@ class FileManager : public llvm::RefCountedBase<FileManager> { /// \brief The virtual directories that we have allocated. For each /// virtual file (e.g. foo/bar/baz.cpp), we add all of its parent /// directories (foo/ and foo/bar/) here. - llvm::SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries; + SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries; /// \brief The virtual files that we have allocated. - llvm::SmallVector<FileEntry*, 4> VirtualFileEntries; + SmallVector<FileEntry*, 4> VirtualFileEntries; /// SeenDirEntries/SeenFileEntries - This is a cache that maps paths /// to directory/file entries (either real or virtual) we have @@ -153,7 +154,7 @@ class FileManager : public llvm::RefCountedBase<FileManager> { /// Add all ancestors of the given path (pointing to either a file /// or a directory) as virtual directories. - void addAncestorsAsVirtualDirs(llvm::StringRef Path); + void addAncestorsAsVirtualDirs(StringRef Path); public: FileManager(const FileSystemOptions &FileSystemOpts); @@ -178,41 +179,51 @@ public: /// getDirectory - Lookup, cache, and verify the specified directory /// (real or virtual). This returns NULL if the directory doesn't exist. /// - const DirectoryEntry *getDirectory(llvm::StringRef DirName); + /// \param CacheFailure If true and the file does not exist, we'll cache + /// the failure to find this file. + const DirectoryEntry *getDirectory(StringRef DirName, + bool CacheFailure = true); /// \brief Lookup, cache, and verify the specified file (real or /// virtual). This returns NULL if the file doesn't exist. /// - /// \param openFile if true and the file exists, it will be opened. - const FileEntry *getFile(llvm::StringRef Filename, bool openFile = false); + /// \param OpenFile if true and the file exists, it will be opened. + /// + /// \param CacheFailure If true and the file does not exist, we'll cache + /// the failure to find this file. + const FileEntry *getFile(StringRef Filename, bool OpenFile = false, + bool CacheFailure = true); + + /// \brief Returns the current file system options + const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; } /// \brief Retrieve a file entry for a "virtual" file that acts as /// if there were a file with the given name on disk. The file /// itself is not accessed. - const FileEntry *getVirtualFile(llvm::StringRef Filename, off_t Size, + const FileEntry *getVirtualFile(StringRef Filename, off_t Size, time_t ModificationTime); /// \brief Open the specified file as a MemoryBuffer, returning a new /// MemoryBuffer if successful, otherwise returning null. llvm::MemoryBuffer *getBufferForFile(const FileEntry *Entry, std::string *ErrorStr = 0); - llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename, + llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); // getNoncachedStatValue - Will get the 'stat' information for the given path. // If the path is relative, it will be resolved against the WorkingDir of the // FileManager's FileSystemOptions. - bool getNoncachedStatValue(llvm::StringRef Path, struct stat &StatBuf); + bool getNoncachedStatValue(StringRef Path, struct stat &StatBuf); /// \brief If path is not absolute and FileSystemOptions set the working /// directory, the path is modified to be relative to the given /// working directory. - void FixupRelativePath(llvm::SmallVectorImpl<char> &path) const; + void FixupRelativePath(SmallVectorImpl<char> &path) const; /// \brief Produce an array mapping from the unique IDs assigned to each /// file to the corresponding FileEntry pointer. void GetUniqueIDMapping( - llvm::SmallVectorImpl<const FileEntry *> &UIDToFiles) const; + SmallVectorImpl<const FileEntry *> &UIDToFiles) const; void PrintStats() const; }; diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index bebcffdddede6..5e48a86619743 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -17,6 +17,7 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/TokenKinds.h" +#include "clang/Basic/LLVM.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/SmallString.h" @@ -49,14 +50,15 @@ namespace clang { /// 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. + // signed char and TokenKinds > 255 won't be handled correctly. + unsigned TokenID : 9; // 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 :11; bool HasMacro : 1; // True if there is a #define for this. bool IsExtension : 1; // True if identifier is a lang extension. + bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11. bool IsPoisoned : 1; // True if identifier is poisoned. bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". @@ -64,7 +66,7 @@ class IdentifierInfo { // file and wasn't modified since. bool RevertedTokenID : 1; // True if RevertTokenIDToIdentifier was // called. - // 6 bits left in 32-bit word. + // 5 bits left in 32-bit word. void *FETokenInfo; // Managed by the language front-end. llvm::StringMapEntry<IdentifierInfo*> *Entry; @@ -113,8 +115,8 @@ public: } /// getName - Return the actual identifier string. - llvm::StringRef getName() const { - return llvm::StringRef(getNameStart(), getLength()); + StringRef getName() const { + return StringRef(getNameStart(), getLength()); } /// hasMacroDefinition - Return true if this identifier is #defined to some @@ -198,6 +200,19 @@ public: RecomputeNeedsHandleIdentifier(); } + /// is/setIsCXX11CompatKeyword - Initialize information about whether or not + /// this language token is a keyword in C++11. This controls compatibility + /// warnings, and is only true when not parsing C++11. Once a compatibility + /// problem has been diagnosed with this keyword, the flag will be cleared. + bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; } + void setIsCXX11CompatKeyword(bool Val) { + IsCXX11CompatKeyword = Val; + if (Val) + NeedsHandleIdentifier = 1; + 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) { @@ -251,7 +266,8 @@ private: void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | - isExtensionToken()); + isExtensionToken() | isCXX11CompatKeyword() || + (getTokenID() == tok::kw___import_module__)); } }; @@ -299,8 +315,8 @@ public: /// advances the iterator for the following string. /// /// \returns The next string in the identifier table. If there is - /// no such string, returns an empty \c llvm::StringRef. - virtual llvm::StringRef Next() = 0; + /// no such string, returns an empty \c StringRef. + virtual StringRef Next() = 0; }; /// IdentifierInfoLookup - An abstract class used by IdentifierTable that @@ -314,7 +330,7 @@ public: /// 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(llvm::StringRef Name) = 0; + virtual IdentifierInfo* get(StringRef Name) = 0; /// \brief Retrieve an iterator into the set of all identifiers /// known to this identifier lookup source. @@ -376,7 +392,7 @@ public: /// get - Return the identifier token info for the specified named identifier. /// - IdentifierInfo &get(llvm::StringRef Name) { + IdentifierInfo &get(StringRef Name) { llvm::StringMapEntry<IdentifierInfo*> &Entry = HashTable.GetOrCreateValue(Name); @@ -405,9 +421,10 @@ public: return *II; } - IdentifierInfo &get(llvm::StringRef Name, tok::TokenKind TokenCode) { + IdentifierInfo &get(StringRef Name, tok::TokenKind TokenCode) { IdentifierInfo &II = get(Name); II.TokenID = TokenCode; + assert(II.TokenID == (unsigned) TokenCode && "TokenCode too large"); return II; } @@ -417,7 +434,7 @@ public: /// This is a version of get() meant for external sources that want to /// introduce or modify an identifier. If they called get(), they would /// likely end up in a recursion. - IdentifierInfo &getOwn(llvm::StringRef Name) { + IdentifierInfo &getOwn(StringRef Name) { llvm::StringMapEntry<IdentifierInfo*> &Entry = HashTable.GetOrCreateValue(Name); @@ -485,6 +502,7 @@ enum ObjCMethodFamily { // selector with the given name. OMF_autorelease, OMF_dealloc, + OMF_finalize, OMF_release, OMF_retain, OMF_retainCount, @@ -507,7 +525,7 @@ enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; /// 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; + friend class Diagnostic; enum IdentifierInfoFlag { // MultiKeywordSelector = 0. @@ -595,7 +613,7 @@ public: /// /// \returns the name for this slot, which may be the empty string if no /// name was supplied. - llvm::StringRef getNameForSlot(unsigned argIndex) const; + StringRef getNameForSlot(unsigned argIndex) const; /// getAsString - Derive the full selector name (e.g. "foo:bar:") and return /// it as an std::string. diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h new file mode 100644 index 0000000000000..27c459dee4e24 --- /dev/null +++ b/include/clang/Basic/LLVM.h @@ -0,0 +1,53 @@ +//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file forward declares and imports various common LLVM datatypes that +// clang wants to use unqualified. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_BASIC_LLVM_H +#define CLANG_BASIC_LLVM_H + +// This should be the only #include, force #includes of all the others on +// clients. +#include "llvm/Support/Casting.h" + +namespace llvm { + // ADT's. + class StringRef; + class Twine; + template<typename T> class ArrayRef; + template<typename T, unsigned N> class SmallVector; + template<typename T> class SmallVectorImpl; + + class raw_ostream; + // TODO: DenseMap, ... +} + + +namespace clang { + // Casting operators. + using llvm::isa; + using llvm::cast; + using llvm::dyn_cast; + using llvm::dyn_cast_or_null; + using llvm::cast_or_null; + + // ADT's. + using llvm::StringRef; + using llvm::Twine; + using llvm::ArrayRef; + using llvm::SmallVector; + using llvm::SmallVectorImpl; + + using llvm::raw_ostream; +} // end namespace clang. + +#endif diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def new file mode 100644 index 0000000000000..03882f8cdb099 --- /dev/null +++ b/include/clang/Basic/LangOptions.def @@ -0,0 +1,158 @@ +//===--- LangOptions.def - Language option database --------------- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the language options. Users of this file must +// define the LANGOPT macro to make use of this information. +// Optionally, the user may also define BENIGN_LANGOPT +// (for options that don't affect the construction of the AST in an +// incompatible way), ENUM_LANGOPT (for options that have enumeration, +// rather than unsigned, type), BENIGN_ENUM_LANGOPT (for benign +// options that have enumeration type), and VALUE_LANGOPT is a language option +// that describes a value rather than a flag. +// +//===----------------------------------------------------------------------===// +#ifndef LANGOPT +# error Define the LANGOPT macro to handle language options +#endif + +#ifndef VALUE_LANGOPT +# define VALUE_LANGOPT(Name, Bits, Default, Description) \ + LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef BENIGN_LANGOPT +# define BENIGN_LANGOPT(Name, Bits, Default, Description) \ + LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef ENUM_LANGOPT +# define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef BENIGN_ENUM_LANGOPT +# define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + ENUM_LANGOPT(Name, Type, Bits, Default, Description) +#endif + +LANGOPT(C99 , 1, 0, "C99") +LANGOPT(C1X , 1, 0, "C1X") +LANGOPT(MicrosoftExt , 1, 0, "Microsoft extensions") +LANGOPT(MicrosoftMode , 1, 0, "Microsoft compatibility mode") +LANGOPT(Borland , 1, 0, "Borland extensions") +LANGOPT(CPlusPlus , 1, 0, "C++") +LANGOPT(CPlusPlus0x , 1, 0, "C++0x") +LANGOPT(ObjC1 , 1, 0, "Objective-C 1") +LANGOPT(ObjC2 , 1, 0, "Objective-C 2") +LANGOPT(ObjCNonFragileABI , 1, 0, "Objective-C modern abi") +LANGOPT(ObjCNonFragileABI2 , 1, 0, "Objective-C enhanced modern abi") +BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, + "Objective-C auto-synthesized properties") +BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, + "Objective-C related result type inference") +LANGOPT(Trigraphs , 1, 0,"trigraphs") +LANGOPT(BCPLComment , 1, 0, "BCPL-style '//' comments") +LANGOPT(Bool , 1, 0, "bool, true, and false keywords") +BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers") +BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode") +BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions") +LANGOPT(GNUKeywords , 1, 1, "GNU keywords") +BENIGN_LANGOPT(ImplicitInt, 1, !C99 && !CPlusPlus, "C89 implicit 'int'") +LANGOPT(Digraphs , 1, 0, "digraphs") +BENIGN_LANGOPT(HexFloats , 1, C99, "C99 hexadecimal float constants") +LANGOPT(CXXOperatorNames , 1, 0, "C++ operator name keywords") +LANGOPT(AppleKext , 1, 0, "Apple kext support") +BENIGN_LANGOPT(PascalStrings, 1, 0, "Pascal string support") +LANGOPT(WritableStrings , 1, 0, "writable string support") +LANGOPT(ConstStrings , 1, 0, "const-qualified string support") +LANGOPT(LaxVectorConversions , 1, 1, "lax vector conversions") +LANGOPT(AltiVec , 1, 0, "AltiVec-style vector initializers") +LANGOPT(Exceptions , 1, 0, "exception handling") +LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions") +LANGOPT(CXXExceptions , 1, 0, "C++ exceptions") +LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling") +LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") +LANGOPT(RTTI , 1, 1, "run-time type information") +LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout") +LANGOPT(NeXTRuntime , 1, 1, "NeXT Objective-C runtime") +LANGOPT(Freestanding, 1, 0, "freestanding implementation") +LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") + +BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") +LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") +LANGOPT(Blocks , 1, 0, "blocks extension to C") +BENIGN_LANGOPT(EmitAllDecls , 1, 0, "support for emitting all declarations") +LANGOPT(MathErrno , 1, 1, "errno support for math functions") +BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time") + +LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") +LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") +LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") +VALUE_LANGOPT(PackStruct , 32, 0, + "default struct packing maximum alignment") +VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") +LANGOPT(GNUInline , 1, 0, "GNU inline semantics") +LANGOPT(NoInline , 1, 0, "__NO_INLINE__ predefined macro") +LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") + +BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") + +BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control") +LANGOPT(CharIsSigned , 1, 1, "signed char") +LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t") + +LANGOPT(ShortEnums , 1, 0, "short enum types") + +LANGOPT(OpenCL , 1, 0, "OpenCL") +LANGOPT(CUDA , 1, 0, "CUDA") + +LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") +BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") +BENIGN_LANGOPT(CatchUndefined , 1, 0, "catching undefined behavior at run time") +BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records") +BENIGN_LANGOPT(DumpVTableLayouts , 1, 0, "dumping the layouts of emitted vtables") +LANGOPT(NoConstantCFStrings , 1, 0, "no constant CoreFoundation strings") +BENIGN_LANGOPT(InlineVisibilityHidden , 1, 0, "hidden default visibility for inline C++ methods") +BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype") +BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support") + +BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking") +LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants") +LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math") +LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT") +LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment") +LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") +LANGOPT(ObjCRuntimeHasWeak , 1, 0, "__weak support in the ARC runtime") +LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") + +LANGOPT(MRTD , 1, 0, "-mrtd calling convention") +BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") +LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime") + +ENUM_LANGOPT(GC, GCMode, 2, NonGC, "Objective-C Garbage Collection mode") +ENUM_LANGOPT(VisibilityMode, Visibility, 3, DefaultVisibility, + "symbol visibility") +ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, + "stack protector mode") +ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, + "signed integer overflow handling") + +BENIGN_LANGOPT(InstantiationDepth, 32, 1024, + "maximum template instantiation depth") +BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0, + "if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.") +VALUE_LANGOPT(MSCVersion, 32, 0, + "version of Microsoft Visual C/C++") + +#undef LANGOPT +#undef VALUE_LANGOPT +#undef BENIGN_LANGOPT +#undef ENUM_LANGOPT +#undef BENIGN_ENUM_LANGOPT + diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index dc77d4c1496bc..688047ff5bdf9 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -23,254 +23,53 @@ namespace clang { /// enabled, which controls the dialect of C that is accepted. class LangOptions { public: - unsigned Trigraphs : 1; // Trigraphs in source files. - unsigned BCPLComment : 1; // BCPL-style '//' comments. - unsigned Bool : 1; // 'bool', 'true', 'false' keywords. - unsigned DollarIdents : 1; // '$' allowed in identifiers. - unsigned AsmPreprocessor : 1; // Preprocessor in asm mode. - unsigned GNUMode : 1; // True in gnu99 mode false in c99 mode (etc) - unsigned GNUKeywords : 1; // True if GNU-only keywords are allowed - unsigned ImplicitInt : 1; // C89 implicit 'int'. - unsigned Digraphs : 1; // C94, C99 and C++ - unsigned HexFloats : 1; // C99 Hexadecimal float constants. - unsigned C99 : 1; // C99 Support - unsigned C1X : 1; // C1X Support - unsigned Microsoft : 1; // Microsoft extensions. - unsigned Borland : 1; // Borland extensions. - 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 ObjCNonFragileABI : 1; // Objective-C modern abi enabled - unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled - unsigned ObjCDefaultSynthProperties : 1; // Objective-C auto-synthesized properties. - unsigned ObjCInferRelatedResultType : 1; // Infer Objective-C related return - // types - unsigned AppleKext : 1; // Allow apple kext features. - - unsigned PascalStrings : 1; // Allow Pascal strings - unsigned WritableStrings : 1; // Allow writable strings - unsigned ConstStrings : 1; // Add const qualifier to strings (-Wwrite-strings) - unsigned LaxVectorConversions : 1; - unsigned AltiVec : 1; // Support AltiVec-style vector initializers. - unsigned Exceptions : 1; // Support exception handling. - unsigned ObjCExceptions : 1; // Support Objective-C exceptions. - unsigned CXXExceptions : 1; // Support C++ exceptions. - unsigned SjLjExceptions : 1; // Use setjmp-longjump exception handling. - unsigned TraditionalCPP : 1; /// Enable some traditional CPP emulation. - unsigned RTTI : 1; // Support RTTI information. - - unsigned MSBitfields : 1; // MS-compatible structure layout - unsigned NeXTRuntime : 1; // Use NeXT runtime. - unsigned Freestanding : 1; // Freestanding implementation - unsigned NoBuiltin : 1; // Do not use builtin functions (-fno-builtin) - - 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. - unsigned MathErrno : 1; // Math functions must respect errno - // (modulo the platform support). - - unsigned HeinousExtensions : 1; // Extensions that we really don't like and - // may be ripped out at any time. - - unsigned Optimize : 1; // Whether __OPTIMIZE__ should be defined. - unsigned OptimizeSize : 1; // Whether __OPTIMIZE_SIZE__ should be - // defined. - unsigned Static : 1; // Should __STATIC__ be defined (as - // opposed to __DYNAMIC__). - unsigned PICLevel : 2; // The value for __PIC__, if non-zero. - - unsigned GNUInline : 1; // Should GNU inline semantics be - // used (instead of C99 semantics). - unsigned NoInline : 1; // Should __NO_INLINE__ be defined. - - unsigned Deprecated : 1; // Should __DEPRECATED be defined. - - unsigned ObjCGCBitmapPrint : 1; // Enable printing of gc's bitmap layout - // for __weak/__strong ivars. - - unsigned AccessControl : 1; // Whether C++ access control should - // be enabled. - unsigned CharIsSigned : 1; // Whether char is a signed or unsigned type - unsigned ShortWChar : 1; // Force wchar_t to be unsigned short int. - - unsigned ShortEnums : 1; // The enum type will be equivalent to the - // smallest integer type with enough room. - - unsigned OpenCL : 1; // OpenCL C99 language extensions. - unsigned CUDA : 1; // CUDA C++ language extensions. - - unsigned AssumeSaneOperatorNew : 1; // Whether to add __attribute__((malloc)) - // to the declaration of C++'s new - // operators - unsigned ElideConstructors : 1; // Whether C++ copy constructors should be - // elided if possible. - unsigned CatchUndefined : 1; // Generate code to check for undefined ops. - unsigned DumpRecordLayouts : 1; /// Dump the layout of IRgen'd records. - unsigned DumpVTableLayouts : 1; /// Dump the layouts of emitted vtables. - unsigned NoConstantCFStrings : 1; // Do not do CF strings - unsigned InlineVisibilityHidden : 1; // Whether inline C++ methods have - // hidden visibility by default. - unsigned ParseUnknownAnytype: 1; /// Let the user write __unknown_anytype. - unsigned DebuggerSupport : 1; /// Do things that only make sense when - /// supporting a debugger - - unsigned SpellChecking : 1; // Whether to perform spell-checking for error - // recovery. - unsigned SinglePrecisionConstants : 1; // Whether to treat double-precision - // floating point constants as - // single precision constants. - unsigned FastRelaxedMath : 1; // OpenCL fast relaxed math (on its own, - // defines __FAST_RELAXED_MATH__). - unsigned DefaultFPContract : 1; // Default setting for FP_CONTRACT - // FIXME: This is just a temporary option, for testing purposes. - unsigned NoBitFieldTypeAlign : 1; - unsigned ObjCAutoRefCount : 1; // Objective C automated reference counting - unsigned ObjCRuntimeHasWeak : 1; // The ARC runtime supports __weak - unsigned ObjCInferRelatedReturnType : 1; // Infer Objective-C related return - // types - unsigned FakeAddressSpaceMap : 1; // Use a fake address space map, for - // testing languages such as OpenCL. - - unsigned MRTD : 1; // -mrtd calling convention - unsigned DelayedTemplateParsing : 1; // Delayed template parsing - -private: - // We declare multibit enums as unsigned because MSVC insists on making enums - // signed. Set/Query these values using accessors. - unsigned GC : 2; // Objective-C Garbage Collection modes. - unsigned SymbolVisibility : 3; // Symbol's visibility. - unsigned StackProtector : 2; // Whether stack protectors are on. - unsigned SignedOverflowBehavior : 2; // How to handle signed integer overflow. - -public: - unsigned InstantiationDepth; // Maximum template instantiation depth. - unsigned NumLargeByValueCopy; // Warn if parameter/return value is larger - // in bytes than this setting. 0 is no check. - - // Version of Microsoft Visual C/C++ we are pretending to be. This is - // temporary until we support all MS extensions used in Windows SDK and stdlib - // headers. Sets _MSC_VER. - unsigned MSCVersion; - - std::string ObjCConstantStringClass; - + typedef clang::Visibility Visibility; + enum GCMode { NonGC, GCOnly, HybridGC }; enum StackProtectorMode { SSPOff, SSPOn, SSPReq }; - + enum SignedOverflowBehaviorTy { SOB_Undefined, // Default C standard behavior. SOB_Defined, // -fwrapv SOB_Trapping // -ftrapv }; + + // Define simple language options (with no accessors). +#define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) +#include "clang/Basic/LangOptions.def" + +private: + // Define language options of enumeration type. These are private, and will + // have accessors (below). +#define LANGOPT(Name, Bits, Default, Description) +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + unsigned Name : Bits; +#include "clang/Basic/LangOptions.def" + +public: + std::string ObjCConstantStringClass; + /// The name of the handler function to be called when -ftrapv is specified. /// If none is specified, abort (GCC-compatible behaviour). std::string OverflowHandler; - LangOptions() { - Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0; - GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0; - HexFloats = 0; - ObjCAutoRefCount = 0; - ObjCRuntimeHasWeak = 0; - ObjCInferRelatedReturnType = 0; - GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0; - AppleKext = 0; - ObjCDefaultSynthProperties = 0; - ObjCInferRelatedResultType = 1; - NoConstantCFStrings = 0; InlineVisibilityHidden = 0; - C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0; - CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0; - Exceptions = ObjCExceptions = CXXExceptions = SjLjExceptions = 0; - TraditionalCPP = Freestanding = NoBuiltin = 0; - MSBitfields = 0; - NeXTRuntime = 1; - RTTI = 1; - LaxVectorConversions = 1; - HeinousExtensions = 0; - AltiVec = OpenCL = CUDA = StackProtector = 0; - - SymbolVisibility = (unsigned) DefaultVisibility; - - ThreadsafeStatics = 1; - POSIXThreads = 0; - Blocks = 0; - EmitAllDecls = 0; - MathErrno = 1; - SignedOverflowBehavior = SOB_Undefined; - - AssumeSaneOperatorNew = 1; - AccessControl = 1; - ElideConstructors = 1; - - SignedOverflowBehavior = 0; - ObjCGCBitmapPrint = 0; - - InstantiationDepth = 1024; - - NumLargeByValueCopy = 0; - MSCVersion = 0; - - Optimize = 0; - OptimizeSize = 0; - - Static = 0; - PICLevel = 0; - - GNUInline = 0; - NoInline = 0; - - Deprecated = 0; - - CharIsSigned = 1; - ShortWChar = 0; - ShortEnums = 0; - CatchUndefined = 0; - DumpRecordLayouts = 0; - DumpVTableLayouts = 0; - SpellChecking = 1; - SinglePrecisionConstants = 0; - FastRelaxedMath = 0; - DefaultFPContract = 0; - NoBitFieldTypeAlign = 0; - FakeAddressSpaceMap = 0; - MRTD = 0; - DelayedTemplateParsing = 0; - ParseUnknownAnytype = DebuggerSupport = 0; - } - - GCMode getGCMode() const { return (GCMode) GC; } - void setGCMode(GCMode m) { GC = (unsigned) m; } - - StackProtectorMode getStackProtectorMode() const { - return static_cast<StackProtectorMode>(StackProtector); - } - void setStackProtectorMode(StackProtectorMode m) { - StackProtector = static_cast<unsigned>(m); - } - - Visibility getVisibilityMode() const { - return (Visibility) SymbolVisibility; - } - void setVisibilityMode(Visibility v) { SymbolVisibility = (unsigned) v; } - - SignedOverflowBehaviorTy getSignedOverflowBehavior() const { - return (SignedOverflowBehaviorTy)SignedOverflowBehavior; - } - void setSignedOverflowBehavior(SignedOverflowBehaviorTy V) { - SignedOverflowBehavior = (unsigned)V; - } + LangOptions(); + // Define accessors/mutators for language options of enumeration type. +#define LANGOPT(Name, Bits, Default, Description) +#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "clang/Basic/LangOptions.def" + bool isSignedOverflowDefined() const { return getSignedOverflowBehavior() == SOB_Defined; } + + /// \brief Reset all of the options that are not considered when building a + /// module. + void resetNonModularOptions(); }; /// Floating point control options @@ -296,6 +95,18 @@ public: } }; +/// \brief Describes the kind of translation unit being processed. +enum TranslationUnitKind { + /// \brief The translation unit is a complete translation unit. + TU_Complete, + /// \brief The translation unit is a prefix to a translation unit, and is + /// not complete. + TU_Prefix, + /// \brief The translation unit is a module. + TU_Module +}; + + /// \brief } // end namespace clang #endif diff --git a/include/clang/Basic/MacroBuilder.h b/include/clang/Basic/MacroBuilder.h index 3287b304c97f5..1d0f1e899c9e8 100644 --- a/include/clang/Basic/MacroBuilder.h +++ b/include/clang/Basic/MacroBuilder.h @@ -20,23 +20,23 @@ namespace clang { class MacroBuilder { - llvm::raw_ostream &Out; + raw_ostream &Out; public: - MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {} + MacroBuilder(raw_ostream &Output) : Out(Output) {} /// Append a #define line for macro of the form "#define Name Value\n". - void defineMacro(const llvm::Twine &Name, const llvm::Twine &Value = "1") { + void defineMacro(const Twine &Name, const Twine &Value = "1") { Out << "#define " << Name << ' ' << Value << '\n'; } /// Append a #undef line for Name. Name should be of the form XXX /// and we emit "#undef XXX". - void undefineMacro(const llvm::Twine &Name) { + void undefineMacro(const Twine &Name) { Out << "#undef " << Name << '\n'; } /// Directly append Str and a newline to the underlying buffer. - void append(const llvm::Twine &Str) { + void append(const Twine &Str) { Out << Str << '\n'; } }; diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile index 1338464fd5d92..eeffe2dfb6cd2 100644 --- a/include/clang/Basic/Makefile +++ b/include/clang/Basic/Makefile @@ -29,26 +29,26 @@ else CLANG_HAS_VERSION_PATCHLEVEL := 1 endif -$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(TBLGEN) $(ObjDir)/.dir +$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td Diagnostic%Kinds.td $(CLANG_TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen" - $(Verb) $(TableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $< + $(Verb) $(ClangTableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $< -$(ObjDir)/DiagnosticIndexName.inc.tmp : Diagnostic.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir +$(ObjDir)/DiagnosticIndexName.inc.tmp : Diagnostic.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang diagnostic name index with tblgen" - $(Verb) $(TableGen) -gen-clang-diags-index-name -o $(call SYSPATH, $@) $< + $(Verb) $(ClangTableGen) -gen-clang-diags-index-name -o $(call SYSPATH, $@) $< -$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(TBLGEN) $(ObjDir)/.dir +$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang diagnostic groups with tblgen" - $(Verb) $(TableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $< + $(Verb) $(ClangTableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $< -$(ObjDir)/AttrList.inc.tmp : Attr.td $(TBLGEN) $(ObjDir)/.dir +$(ObjDir)/AttrList.inc.tmp : Attr.td $(CLANG_TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang attribute list with tblgen" - $(Verb) $(TableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \ + $(Verb) $(ClangTableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \ -I $(PROJ_SRC_DIR)/../.. $< -$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(TBLGEN) $(ObjDir)/.dir +$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir $(Echo) "Building Clang arm_neon.inc with tblgen" - $(Verb) $(TableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $< + $(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) $< $(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir $(Echo) "Updating Clang version info." diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h index 267ecbcd6df47..7328b1a6bbfab 100644 --- a/include/clang/Basic/OnDiskHashTable.h +++ b/include/clang/Basic/OnDiskHashTable.h @@ -28,31 +28,31 @@ namespace io { typedef uint32_t Offset; -inline void Emit8(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit8(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); } -inline void Emit16(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit16(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); assert((V >> 16) == 0); } -inline void Emit24(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit24(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); Out << (unsigned char)(V >> 16); assert((V >> 24) == 0); } -inline void Emit32(llvm::raw_ostream& Out, uint32_t V) { +inline void Emit32(raw_ostream& Out, uint32_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); Out << (unsigned char)(V >> 16); Out << (unsigned char)(V >> 24); } -inline void Emit64(llvm::raw_ostream& Out, uint64_t V) { +inline void Emit64(raw_ostream& Out, uint64_t V) { Out << (unsigned char)(V); Out << (unsigned char)(V >> 8); Out << (unsigned char)(V >> 16); @@ -63,7 +63,7 @@ inline void Emit64(llvm::raw_ostream& Out, uint64_t V) { Out << (unsigned char)(V >> 56); } -inline void Pad(llvm::raw_ostream& Out, unsigned A) { +inline void Pad(raw_ostream& Out, unsigned A) { Offset off = (Offset) Out.tell(); uint32_t n = ((uintptr_t)(off+A-1) & ~(uintptr_t)(A-1)) - off; for (; n ; --n) @@ -182,12 +182,12 @@ public: InfoObj)); } - io::Offset Emit(llvm::raw_ostream &out) { + io::Offset Emit(raw_ostream &out) { Info InfoObj; return Emit(out, InfoObj); } - io::Offset Emit(llvm::raw_ostream &out, Info &InfoObj) { + io::Offset Emit(raw_ostream &out, Info &InfoObj) { using namespace clang::io; // Emit the payload of the table. @@ -464,6 +464,8 @@ public: } item_iterator item_end() { return item_iterator(); } + Info &getInfoObj() { return InfoObj; } + static OnDiskChainedHashTable* Create(const unsigned char* buckets, const unsigned char* const base, const Info &InfoObj = Info()) { diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def index 95cc1a9a513f6..103fa839b8dfb 100644 --- a/include/clang/Basic/OpenCLExtensions.def +++ b/include/clang/Basic/OpenCLExtensions.def @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +// OpenCL 1.1. OPENCLEXT(cl_khr_fp64) OPENCLEXT(cl_khr_int64_base_atomics) OPENCLEXT(cl_khr_int64_extended_atomics) @@ -25,4 +26,7 @@ OPENCLEXT(cl_khr_local_int32_extended_atomics) OPENCLEXT(cl_khr_byte_addressable_store) OPENCLEXT(cl_khr_3d_image_writes) +// Clang Extensions. +OPENCLEXT(cl_clang_storage_class_specifiers) + #undef OPENCLEXT diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h index 7d7c0896f505f..c6ca98976555b 100644 --- a/include/clang/Basic/PartialDiagnostic.h +++ b/include/clang/Basic/PartialDiagnostic.h @@ -33,7 +33,7 @@ public: /// 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 + MaxArguments = DiagnosticsEngine::MaxArguments }; /// NumDiagArgs - This contains the number of entries in Arguments. @@ -65,7 +65,7 @@ public: /// only support 10 ranges, could easily be extended if needed. CharSourceRange DiagRanges[10]; - enum { MaxFixItHints = 3 }; + enum { MaxFixItHints = DiagnosticsEngine::MaxFixItHints }; /// FixItHints - If valid, provides a hint with some code /// to insert, remove, or modify at a particular position. @@ -165,6 +165,8 @@ private: assert(DiagStorage->NumFixItHints < Storage::MaxFixItHints && "Too many code modification hints!"); + if (DiagStorage->NumFixItHints >= Storage::MaxFixItHints) + return; // Don't crash in release builds DiagStorage->FixItHints[DiagStorage->NumFixItHints++] = Hint; } @@ -190,12 +192,12 @@ public: *this->DiagStorage = *Other.DiagStorage; } - PartialDiagnostic(const DiagnosticInfo &Other, StorageAllocator &Allocator) + PartialDiagnostic(const Diagnostic &Other, StorageAllocator &Allocator) : DiagID(Other.getID()), DiagStorage(0), Allocator(&Allocator) { // Copy arguments. for (unsigned I = 0, N = Other.getNumArgs(); I != N; ++I) { - if (Other.getArgKind(I) == Diagnostic::ak_std_string) + if (Other.getArgKind(I) == DiagnosticsEngine::ak_std_string) AddString(Other.getArgStdStr(I)); else AddTaggedVal(Other.getRawArg(I), Other.getArgKind(I)); @@ -230,7 +232,7 @@ public: unsigned getDiagID() const { return DiagID; } - void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const { + void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { if (!DiagStorage) DiagStorage = getStorage(); @@ -240,14 +242,14 @@ public: DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V; } - void AddString(llvm::StringRef V) const { + void AddString(StringRef V) const { if (!DiagStorage) DiagStorage = getStorage(); assert(DiagStorage->NumDiagArgs < Storage::MaxArguments && "Too many arguments to diagnostic!"); DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] - = Diagnostic::ak_std_string; + = DiagnosticsEngine::ak_std_string; DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V; } @@ -257,12 +259,12 @@ public: // Add all arguments. for (unsigned i = 0, e = DiagStorage->NumDiagArgs; i != e; ++i) { - if ((Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i] - == Diagnostic::ak_std_string) + if ((DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i] + == DiagnosticsEngine::ak_std_string) DB.AddString(DiagStorage->DiagArgumentsStr[i]); else DB.AddTaggedVal(DiagStorage->DiagArgumentsVal[i], - (Diagnostic::ArgumentKind)DiagStorage->DiagArgumentsKind[i]); + (DiagnosticsEngine::ArgumentKind)DiagStorage->DiagArgumentsKind[i]); } // Add all ranges. @@ -285,24 +287,25 @@ public: friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, unsigned I) { - PD.AddTaggedVal(I, Diagnostic::ak_uint); + PD.AddTaggedVal(I, DiagnosticsEngine::ak_uint); return PD; } friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, int I) { - PD.AddTaggedVal(I, Diagnostic::ak_sint); + PD.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return PD; } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, const char *S) { - PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), Diagnostic::ak_c_string); + PD.AddTaggedVal(reinterpret_cast<intptr_t>(S), + DiagnosticsEngine::ak_c_string); return PD; } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, - llvm::StringRef S) { + StringRef S) { PD.AddString(S); return PD; diff --git a/include/clang/Basic/PrettyStackTrace.h b/include/clang/Basic/PrettyStackTrace.h index 5a5d55192b69e..06a12644c36e4 100644 --- a/include/clang/Basic/PrettyStackTrace.h +++ b/include/clang/Basic/PrettyStackTrace.h @@ -30,7 +30,7 @@ namespace clang { public: PrettyStackTraceLoc(SourceManager &sm, SourceLocation L, const char *Msg) : SM(sm), Loc(L), Message(Msg) {} - virtual void print(llvm::raw_ostream &OS) const; + virtual void print(raw_ostream &OS) const; }; } diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index ee5f96fe937a4..154148c16b03c 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SOURCELOCATION_H #define LLVM_CLANG_SOURCELOCATION_H +#include "clang/Basic/LLVM.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include <utility> #include <functional> @@ -21,8 +22,6 @@ namespace llvm { class MemoryBuffer; - class raw_ostream; - class StringRef; template <typename T> struct DenseMapInfo; template <typename T> struct isPodLike; } @@ -35,8 +34,9 @@ class SourceManager; /// a source file (MemoryBuffer) along with its #include path and #line data. /// class FileID { - /// ID - Opaque identifier, 0 is "invalid". - unsigned ID; + /// ID - Opaque identifier, 0 is "invalid". >0 is this module, <-1 is + /// something loaded from another module. + int ID; public: FileID() : ID(0) {} @@ -49,49 +49,63 @@ public: 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; } + static FileID getSentinel() { return get(-1); } + unsigned getHashValue() const { return static_cast<unsigned>(ID); } private: friend class SourceManager; friend class ASTWriter; friend class ASTReader; - static FileID get(unsigned V) { + static FileID get(int V) { FileID F; F.ID = V; return F; } - unsigned getOpaqueValue() const { return ID; } + int 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. +/// \brief Encodes a location in the source. The SourceManager can decode this +/// to get at the full include stack, line and column information. +/// +/// Technically, a source location is simply an offset into the manager's view +/// of the input source, which is all input buffers (including macro +/// expansions) concatenated in an effectively arbitrary order. The manager +/// actually maintains two blocks of input buffers. One, starting at offset +/// 0 and growing upwards, contains all buffers from this module. The other, +/// starting at the highest possible offset and growing downwards, contains +/// buffers of loaded modules. +/// +/// In addition, one bit of SourceLocation is used for quick access to the +/// information whether the location is in a file or a macro expansion. +/// +/// It is important that this type remains small. It is currently 32 bits wide. class SourceLocation { unsigned ID; friend class SourceManager; + friend class ASTReader; + friend class ASTWriter; enum { MacroIDBit = 1U << 31 }; public: - SourceLocation() : ID(0) {} // 0 is an invalid FileID. + SourceLocation() : ID(0) {} 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). + /// \brief 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. + /// \brief Return the offset into the manager's global input view. unsigned getOffset() const { return ID & ~MacroIDBit; } @@ -111,10 +125,10 @@ private: } public: - /// getFileLocWithOffset - Return a source location with the specified offset - /// from this file SourceLocation. - SourceLocation getFileLocWithOffset(int Offset) const { - assert(((getOffset()+Offset) & MacroIDBit) == 0 && "invalid location"); + /// \brief Return a source location with the specified offset from this + /// SourceLocation. + SourceLocation getLocWithOffset(int Offset) const { + assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow"); SourceLocation L; L.ID = ID+Offset; return L; @@ -150,7 +164,7 @@ public: return getFromRawEncoding((unsigned)(uintptr_t)Encoding); } - void print(llvm::raw_ostream &OS, const SourceManager &SM) const; + void print(raw_ostream &OS, const SourceManager &SM) const; void dump(const SourceManager &SM) const; }; @@ -261,11 +275,11 @@ public: FileID getFileID() const; - FullSourceLoc getInstantiationLoc() const; + FullSourceLoc getExpansionLoc() const; FullSourceLoc getSpellingLoc() const; - unsigned getInstantiationLineNumber(bool *Invalid = 0) const; - unsigned getInstantiationColumnNumber(bool *Invalid = 0) const; + unsigned getExpansionLineNumber(bool *Invalid = 0) const; + unsigned getExpansionColumnNumber(bool *Invalid = 0) const; unsigned getSpellingLineNumber(bool *Invalid = 0) const; unsigned getSpellingColumnNumber(bool *Invalid = 0) const; @@ -276,7 +290,7 @@ public: /// getBufferData - Return a StringRef to the source buffer data for the /// specified FileID. - llvm::StringRef getBufferData(bool *Invalid = 0) const; + StringRef getBufferData(bool *Invalid = 0) const; /// getDecomposedLoc - Decompose the specified location into a raw FileID + /// Offset pair. The first element is the FileID, the second is the @@ -326,8 +340,8 @@ public: /// 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 -/// of a normal location. +/// #line and GNU line marker directives and is always the expansion point of +/// a normal location. /// /// You can get a PresumedLoc from a SourceLocation with SourceManager. class PresumedLoc { diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 6301f31978596..985ddd641271c 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SOURCEMANAGER_H #define LLVM_CLANG_SOURCEMANAGER_H +#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/DataTypes.h" @@ -22,22 +23,37 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/MemoryBuffer.h" +#include <map> #include <vector> #include <cassert> -namespace llvm { -class StringRef; -} - namespace clang { -class Diagnostic; +class DiagnosticsEngine; class SourceManager; class FileManager; class FileEntry; class LineTableInfo; class LangOptions; - +class ASTWriter; +class ASTReader; + +/// There are three different types of locations in a file: a spelling +/// location, an expansion location, and a presumed location. +/// +/// Given an example of: +/// #define min(x, y) x < y ? x : y +/// +/// and then later on a use of min: +/// #line 17 +/// return min(a, b); +/// +/// The expansion location is the line in the source code where the macro +/// was expanded (the return statement), the spelling location is the +/// location in the source where the macro was originally defined, +/// and the presumed location is where the line directive states that +/// the line is 17, or any other line. + /// SrcMgr - Public enums and private classes that are part of the /// SourceManager implementation. /// @@ -46,7 +62,7 @@ namespace SrcMgr { /// holds normal user code, system code, or system code which is implicitly /// 'extern "C"' in C++ mode. Entire directories can be tagged with this /// (this is maintained by DirectoryLookup and friends) as can specific - /// FileIDInfos when a #pragma system_header is seen or various other cases. + /// FileInfos when a #pragma system_header is seen or various other cases. /// enum CharacteristicKind { C_User, C_System, C_ExternCSystem @@ -61,7 +77,7 @@ namespace SrcMgr { /// \brief Whether the buffer should not be freed on destruction. DoNotFreeFlag = 0x02 }; - + /// Buffer - The actual buffer containing the characters from the input /// file. This is owned by the ContentCache object. /// The bits indicate indicates whether the buffer is invalid. @@ -92,12 +108,12 @@ namespace SrcMgr { /// /// \param Diag Object through which diagnostics will be emitted if the /// buffer cannot be retrieved. - /// + /// /// \param Loc If specified, is the location that invalid file diagnostics /// will be emitted at. /// /// \param Invalid If non-NULL, will be set \c true if an error occurred. - const llvm::MemoryBuffer *getBuffer(Diagnostic &Diag, + const llvm::MemoryBuffer *getBuffer(DiagnosticsEngine &Diag, const SourceManager &SM, SourceLocation Loc = SourceLocation(), bool *Invalid = 0) const; @@ -109,10 +125,10 @@ namespace SrcMgr { 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. + /// this ContentCache. This can be 0 if the MemBuffer was not actually + /// expanded. unsigned getSizeBytesMapped() const; - + /// Returns the kind of memory used to back the memory buffer for /// this content cache. This is used for performance analysis. llvm::MemoryBuffer::BufferKind getMemoryBufferKind() const; @@ -122,7 +138,7 @@ namespace SrcMgr { Buffer.setPointer(B); Buffer.setInt(false); } - + /// \brief Get the underlying buffer, returning NULL if the buffer is not /// yet available. const llvm::MemoryBuffer *getRawBuffer() const { @@ -137,12 +153,12 @@ namespace SrcMgr { bool isBufferInvalid() const { return Buffer.getInt() & InvalidFlag; } - + /// \brief Determine whether the buffer should be freed. bool shouldFreeBuffer() const { return (Buffer.getInt() & DoNotFreeFlag) == 0; } - + ContentCache(const FileEntry *Ent = 0) : Buffer(0, false), OrigEntry(Ent), ContentsEntry(Ent), SourceLineCache(0), NumLines(0) {} @@ -156,14 +172,14 @@ namespace SrcMgr { /// The copy ctor does not allow copies where source object has either /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory /// is not transferred, so this is a logical error. - ContentCache(const ContentCache &RHS) - : Buffer(0, false), SourceLineCache(0) + ContentCache(const ContentCache &RHS) + : Buffer(0, false), SourceLineCache(0) { OrigEntry = RHS.OrigEntry; ContentsEntry = RHS.ContentsEntry; - assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 - && "Passed ContentCache object cannot own a buffer."); + assert (RHS.Buffer.getPointer() == 0 && RHS.SourceLineCache == 0 && + "Passed ContentCache object cannot own a buffer."); NumLines = RHS.NumLines; } @@ -177,8 +193,8 @@ namespace SrcMgr { /// that it represents and include stack information. /// /// Each FileInfo has include stack information, indicating where it came - /// from. This information encodes the #include chain that a token was - /// instantiated from. The main include file has an invalid IncludeLoc. + /// from. This information encodes the #include chain that a token was + /// expanded from. The main include file has an invalid IncludeLoc. /// /// FileInfos contain a "ContentCache *", with the contents of the file. /// @@ -187,16 +203,26 @@ namespace SrcMgr { /// This is an invalid SLOC for the main file (top of the #include chain). unsigned IncludeLoc; // Really a SourceLocation + /// \brief Number of FileIDs (files and macros) that were created during + /// preprocessing of this #include, including this SLocEntry. + /// Zero means the preprocessor didn't provide such info for this SLocEntry. + unsigned NumCreatedFIDs; + /// Data - This contains the ContentCache* and the bits indicating the /// characteristic of the file and whether it has #line info, all bitmangled /// together. uintptr_t Data; + + friend class clang::SourceManager; + friend class clang::ASTWriter; + friend class clang::ASTReader; public: /// get - Return a FileInfo object. static FileInfo get(SourceLocation IL, const ContentCache *Con, CharacteristicKind FileCharacter) { FileInfo X; X.IncludeLoc = IL.getRawEncoding(); + X.NumCreatedFIDs = 0; X.Data = (uintptr_t)Con; assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); assert((unsigned)FileCharacter < 4 && "invalid file character"); @@ -227,70 +253,68 @@ namespace SrcMgr { } }; - /// 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. + /// ExpansionInfo - Each ExpansionInfo encodes the expansion location - where + /// the token was ultimately expanded, and the SpellingLoc - where the actual + /// character data for the token came from. + class ExpansionInfo { + // 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 - /// start will be the identifier and the end will be the ')'. Finally, in + /// ExpansionLocStart/ExpansionLocEnd - In a macro expansion, these + /// indicate the start and end of the expansion. In object-like macros, + /// these will be the same. In a function-like macro expansion, the start + /// will be the identifier and the end will be the ')'. Finally, in /// macro-argument instantitions, the end will be 'SourceLocation()', an /// invalid location. - unsigned InstantiationLocStart, InstantiationLocEnd; + unsigned ExpansionLocStart, ExpansionLocEnd; public: SourceLocation getSpellingLoc() const { return SourceLocation::getFromRawEncoding(SpellingLoc); } - SourceLocation getInstantiationLocStart() const { - return SourceLocation::getFromRawEncoding(InstantiationLocStart); + SourceLocation getExpansionLocStart() const { + return SourceLocation::getFromRawEncoding(ExpansionLocStart); } - SourceLocation getInstantiationLocEnd() const { + SourceLocation getExpansionLocEnd() const { SourceLocation EndLoc = - SourceLocation::getFromRawEncoding(InstantiationLocEnd); - return EndLoc.isInvalid() ? getInstantiationLocStart() : EndLoc; + SourceLocation::getFromRawEncoding(ExpansionLocEnd); + return EndLoc.isInvalid() ? getExpansionLocStart() : EndLoc; } - std::pair<SourceLocation,SourceLocation> getInstantiationLocRange() const { - return std::make_pair(getInstantiationLocStart(), - getInstantiationLocEnd()); + std::pair<SourceLocation,SourceLocation> getExpansionLocRange() const { + return std::make_pair(getExpansionLocStart(), getExpansionLocEnd()); } - bool isMacroArgInstantiation() const { + bool isMacroArgExpansion() const { // Note that this needs to return false for default constructed objects. - return getInstantiationLocStart().isValid() && - SourceLocation::getFromRawEncoding(InstantiationLocEnd).isInvalid(); + return getExpansionLocStart().isValid() && + SourceLocation::getFromRawEncoding(ExpansionLocEnd).isInvalid(); } - /// create - Return a InstantiationInfo for an expansion. ILStart and - /// ILEnd specify the instantiation range (where the macro is expanded), - /// and SL specifies the spelling location (where the characters from the - /// token come from). All three can refer to normal File SLocs or - /// instantiation locations. - static InstantiationInfo create(SourceLocation SL, - SourceLocation ILStart, - SourceLocation ILEnd) { - InstantiationInfo X; - X.SpellingLoc = SL.getRawEncoding(); - X.InstantiationLocStart = ILStart.getRawEncoding(); - X.InstantiationLocEnd = ILEnd.getRawEncoding(); + /// create - Return a ExpansionInfo for an expansion. Start and End specify + /// the expansion range (where the macro is expanded), and SpellingLoc + /// specifies the spelling location (where the characters from the token + /// come from). All three can refer to normal File SLocs or expansion + /// locations. + static ExpansionInfo create(SourceLocation SpellingLoc, + SourceLocation Start, SourceLocation End) { + ExpansionInfo X; + X.SpellingLoc = SpellingLoc.getRawEncoding(); + X.ExpansionLocStart = Start.getRawEncoding(); + X.ExpansionLocEnd = End.getRawEncoding(); return X; } - /// createForMacroArg - Return a special InstantiationInfo for the - /// expansion of a macro argument into a function-like macro's body. IL - /// specifies the instantiation location (where the macro is expanded). - /// This doesn't need to be a range because a macro is always instantiated - /// at a macro parameter reference, and macro parameters are always exactly - /// one token. SL specifies the spelling location (where the characters - /// from the token come from). IL and SL can both refer to normal File - /// SLocs or instantiation locations. + /// createForMacroArg - Return a special ExpansionInfo for the expansion of + /// a macro argument into a function-like macro's body. ExpansionLoc + /// specifies the expansion location (where the macro is expanded). This + /// doesn't need to be a range because a macro is always expanded at + /// a macro parameter reference, and macro parameters are always exactly + /// one token. SpellingLoc specifies the spelling location (where the + /// characters from the token come from). ExpansionLoc and SpellingLoc can + /// both refer to normal File SLocs or expansion locations. /// /// Given the code: /// \code @@ -298,41 +322,41 @@ namespace SrcMgr { /// F(42); /// \endcode /// - /// When expanding '\c F(42)', the '\c x' would call this with an SL - /// pointing at '\c 42' anad an IL pointing at its location in the - /// definition of '\c F'. - static InstantiationInfo createForMacroArg(SourceLocation SL, - SourceLocation IL) { + /// When expanding '\c F(42)', the '\c x' would call this with an + /// SpellingLoc pointing at '\c 42' anad an ExpansionLoc pointing at its + /// location in the definition of '\c F'. + static ExpansionInfo createForMacroArg(SourceLocation SpellingLoc, + SourceLocation ExpansionLoc) { // We store an intentionally invalid source location for the end of the - // instantiation range to mark that this is a macro argument instantation - // rather than a normal one. - return create(SL, IL, SourceLocation()); + // expansion range to mark that this is a macro argument ion rather than + // a normal one. + return create(SpellingLoc, ExpansionLoc, SourceLocation()); } }; /// SLocEntry - This is a discriminated union of FileInfo and - /// InstantiationInfo. SourceManager keeps an array of these objects, and + /// ExpansionInfo. SourceManager keeps an array of these objects, and /// they are uniquely identified by the FileID datatype. class SLocEntry { - unsigned Offset; // low bit is set for instantiation info. + unsigned Offset; // low bit is set for expansion info. union { FileInfo File; - InstantiationInfo Instantiation; + ExpansionInfo Expansion; }; public: unsigned getOffset() const { return Offset >> 1; } - bool isInstantiation() const { return Offset & 1; } - bool isFile() const { return !isInstantiation(); } + bool isExpansion() const { return Offset & 1; } + bool isFile() const { return !isExpansion(); } const FileInfo &getFile() const { assert(isFile() && "Not a file SLocEntry!"); return File; } - const InstantiationInfo &getInstantiation() const { - assert(isInstantiation() && "Not an instantiation SLocEntry!"); - return Instantiation; + const ExpansionInfo &getExpansion() const { + assert(isExpansion() && "Not a macro expansion SLocEntry!"); + return Expansion; } static SLocEntry get(unsigned Offset, const FileInfo &FI) { @@ -342,10 +366,10 @@ namespace SrcMgr { return E; } - static SLocEntry get(unsigned Offset, const InstantiationInfo &II) { + static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) { SLocEntry E; E.Offset = (Offset << 1) | 1; - E.Instantiation = II; + E.Expansion = Expansion; return E; } }; @@ -356,13 +380,14 @@ class ExternalSLocEntrySource { public: virtual ~ExternalSLocEntrySource(); - /// \brief Read the source location entry with index ID. + /// \brief Read the source location entry with index ID, which will always be + /// less than -1. /// /// \returns true if an error occurred that prevented the source-location /// entry from being loaded. - virtual bool ReadSLocEntry(unsigned ID) = 0; + virtual bool ReadSLocEntry(int ID) = 0; }; - + /// IsBeforeInTranslationUnitCache - This class holds the cache used by /// isBeforeInTranslationUnit. The cache structure is complex enough to be @@ -371,24 +396,28 @@ class IsBeforeInTranslationUnitCache { /// L/R QueryFID - These are the FID's of the cached query. If these match up /// with a subsequent query, the result can be reused. FileID LQueryFID, RQueryFID; - + + /// \brief True if LQueryFID was created before RQueryFID. This is used + /// to compare macro expansion locations. + bool IsLQFIDBeforeRQFID; + /// CommonFID - This is the file found in common between the two #include /// traces. It is the nearest common ancestor of the #include tree. FileID CommonFID; - + /// L/R CommonOffset - This is the offset of the previous query in CommonFID. /// Usually, this represents the location of the #include for QueryFID, but if /// LQueryFID is a parent of RQueryFID (or vise versa) then these can be a /// random token in the parent. unsigned LCommonOffset, RCommonOffset; public: - + /// isCacheValid - Return true if the currently cached values match up with /// the specified LHS/RHS query. If not, we can't use the cache. bool isCacheValid(FileID LHS, FileID RHS) const { return LQueryFID == LHS && RQueryFID == RHS; } - + /// getCachedResult - If the cache is valid, compute the result given the /// specified offsets in the LHS/RHS FID's. bool getCachedResult(unsigned LOffset, unsigned ROffset) const { @@ -396,38 +425,56 @@ public: // use the #include loc in the common file. if (LQueryFID != CommonFID) LOffset = LCommonOffset; if (RQueryFID != CommonFID) ROffset = RCommonOffset; + + // It is common for multiple macro expansions to be "included" from the same + // location (expansion location), in which case use the order of the FileIDs + // to determine which came first. This will also take care the case where + // one of the locations points at the inclusion/expansion point of the other + // in which case its FileID will come before the other. + if (LOffset == ROffset && + (LQueryFID != CommonFID || RQueryFID != CommonFID)) + return IsLQFIDBeforeRQFID; + return LOffset < ROffset; } - + // Set up a new query. - void setQueryFIDs(FileID LHS, FileID RHS) { + void setQueryFIDs(FileID LHS, FileID RHS, bool isLFIDBeforeRFID) { + assert(LHS != RHS); LQueryFID = LHS; RQueryFID = RHS; + IsLQFIDBeforeRQFID = isLFIDBeforeRFID; + } + + void clear() { + LQueryFID = RQueryFID = FileID(); + IsLQFIDBeforeRQFID = false; } - + void setCommonLoc(FileID commonFID, unsigned lCommonOffset, unsigned rCommonOffset) { CommonFID = commonFID; LCommonOffset = lCommonOffset; RCommonOffset = rCommonOffset; } - + }; -/// SourceManager - This file handles loading and caching of source files into -/// memory. This object owns the MemoryBuffer objects for all of the loaded +/// \brief This class handles loading and caching of source files into memory. +/// +/// This object owns the MemoryBuffer objects for all of the loaded /// files and assigns unique FileID's for each unique #include chain. /// /// The SourceManager can be queried for information about SourceLocation -/// objects, turning them into either spelling or instantiation locations. -/// Spelling locations represent where the bytes corresponding to a token came -/// from and instantiation locations represent where the location is in the -/// user's view. In the case of a macro expansion, for example, the spelling -/// location indicates where the expanded token came from and the instantiation -/// location specifies where it was expanded. +/// objects, turning them into either spelling or expansion locations. Spelling +/// locations represent where the bytes corresponding to a token came from and +/// expansion locations represent where the location is in the user's view. In +/// the case of a macro expansion, for example, the spelling location indicates +/// where the expanded token came from and the expansion location specifies +/// where it was expanded. class SourceManager : public llvm::RefCountedBase<SourceManager> { - /// \brief Diagnostic object. - Diagnostic &Diag; + /// \brief DiagnosticsEngine object. + DiagnosticsEngine &Diag; FileManager &FileMgr; @@ -451,16 +498,37 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> { /// 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; - /// NextOffset - This is the next available offset that a new SLocEntry can - /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry. - unsigned NextOffset; + /// \brief The table of SLocEntries that are local to this module. + /// + /// Positive FileIDs are indexes into this table. Entry 0 indicates an invalid + /// expansion. + std::vector<SrcMgr::SLocEntry> LocalSLocEntryTable; + + /// \brief The table of SLocEntries that are loaded from other modules. + /// + /// Negative FileIDs are indexes into this table. To get from ID to an index, + /// use (-ID - 2). + std::vector<SrcMgr::SLocEntry> LoadedSLocEntryTable; + + /// \brief The starting offset of the next local SLocEntry. + /// + /// This is LocalSLocEntryTable.back().Offset + the size of that entry. + unsigned NextLocalOffset; + + /// \brief The starting offset of the latest batch of loaded SLocEntries. + /// + /// This is LoadedSLocEntryTable.back().Offset, except that that entry might + /// not have been loaded, so that value would be unknown. + unsigned CurrentLoadedOffset; + + /// \brief The highest possible offset is 2^31-1, so CurrentLoadedOffset + /// starts at 2^31. + static const unsigned MaxLoadedOffset = 1U << 31U; - /// \brief If source location entries are being lazily loaded from - /// an external source, this vector indicates whether the Ith source - /// location entry has already been loaded from the external storage. + /// \brief A bitmap that indicates whether the entries of LoadedSLocEntryTable + /// have already been loaded from the external source. + /// + /// Same indexing as LoadedSLocEntryTable. std::vector<bool> SLocEntryLoaded; /// \brief An external source for source location entries. @@ -485,6 +553,9 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> { /// MainFileID - The file ID for the main source file of the translation unit. FileID MainFileID; + /// \brief The file ID for the precompiled preamble there is one. + FileID PreambleFileID; + // Statistics for -print-stats. mutable unsigned NumLinearScans, NumBinaryProbes; @@ -493,17 +564,23 @@ class SourceManager : public llvm::RefCountedBase<SourceManager> { // Cache for the "fake" buffer used for error-recovery purposes. mutable llvm::MemoryBuffer *FakeBufferForRecovery; - + + /// \brief Lazily computed map of macro argument chunks to their expanded + /// source location. + typedef std::map<unsigned, SourceLocation> MacroArgsMap; + + mutable llvm::DenseMap<FileID, MacroArgsMap *> MacroArgsCacheMap; + // SourceManager doesn't support copy construction. explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); public: - SourceManager(Diagnostic &Diag, FileManager &FileMgr); + SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr); ~SourceManager(); void clearIDTables(); - Diagnostic &getDiagnostics() const { return Diag; } + DiagnosticsEngine &getDiagnostics() const { return Diag; } FileManager &getFileManager() const { return FileMgr; } @@ -513,6 +590,15 @@ public: OverridenFilesKeepOriginalName = value; } + /// 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. + FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { + assert(MainFileID.isInvalid() && "MainFileID already set!"); + MainFileID = createFileIDForMemBuffer(Buffer); + return MainFileID; + } + //===--------------------------------------------------------------------===// // MainFileID creation and querying methods. //===--------------------------------------------------------------------===// @@ -527,67 +613,56 @@ public: return MainFileID; } - /// \brief Set the file ID for the precompiled preamble, which is also the - /// main file. - void SetPreambleFileID(FileID Preamble) { - assert(MainFileID.isInvalid() && "MainFileID already set!"); - MainFileID = Preamble; + /// \brief Set the file ID for the precompiled preamble. + void setPreambleFileID(FileID Preamble) { + assert(PreambleFileID.isInvalid() && "PreambleFileID already set!"); + PreambleFileID = Preamble; } - + + /// \brief Get the file ID for the precompiled preamble if there is one. + FileID getPreambleFileID() const { return PreambleFileID; } + //===--------------------------------------------------------------------===// - // Methods to create new FileID's and instantiations. + // Methods to create new FileID's and macro expansions. //===--------------------------------------------------------------------===// /// createFileID - Create a new FileID that represents the specified file /// being #included from the specified IncludePosition. This translates NULL /// into standard input. - /// PreallocateID should be non-zero to specify which pre-allocated, - /// lazily computed source location is being filled in by this operation. FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - unsigned PreallocatedID = 0, - unsigned Offset = 0) { + int LoadedID = 0, unsigned LoadedOffset = 0) { const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); assert(IR && "getOrCreateContentCache() cannot return NULL"); - return createFileID(IR, IncludePos, FileCharacter, PreallocatedID, Offset); + return createFileID(IR, IncludePos, FileCharacter, LoadedID, LoadedOffset); } /// 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. FileID createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer, - unsigned PreallocatedID = 0, - unsigned Offset = 0) { + int LoadedID = 0, unsigned LoadedOffset = 0) { return createFileID(createMemBufferContentCache(Buffer), SourceLocation(), - SrcMgr::C_User, PreallocatedID, Offset); + SrcMgr::C_User, LoadedID, LoadedOffset); } - /// 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. - FileID createMainFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) { - assert(MainFileID.isInvalid() && "MainFileID already set!"); - MainFileID = createFileIDForMemBuffer(Buffer); - return MainFileID; - } - - /// createMacroArgInstantiationLoc - Return a new SourceLocation that encodes - /// the fact that a token from SpellingLoc should actually be referenced from - /// InstantiationLoc, and that it represents the instantiation of a macro - /// argument into the function-like macro body. - SourceLocation createMacroArgInstantiationLoc(SourceLocation Loc, - SourceLocation InstantiationLoc, - unsigned TokLength); + /// createMacroArgExpansionLoc - Return a new SourceLocation that encodes the + /// fact that a token from SpellingLoc should actually be referenced from + /// ExpansionLoc, and that it represents the expansion of a macro argument + /// into the function-like macro body. + SourceLocation createMacroArgExpansionLoc(SourceLocation Loc, + SourceLocation ExpansionLoc, + unsigned TokLength); - /// createInstantiationLoc - Return a new SourceLocation that encodes the fact + /// createExpansionLoc - Return a new SourceLocation that encodes the fact /// that a token from SpellingLoc should actually be referenced from - /// InstantiationLoc. - SourceLocation createInstantiationLoc(SourceLocation Loc, - SourceLocation InstantiationLocStart, - SourceLocation InstantiationLocEnd, - unsigned TokLength, - unsigned PreallocatedID = 0, - unsigned Offset = 0); + /// ExpansionLoc. + SourceLocation createExpansionLoc(SourceLocation Loc, + SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd, + unsigned TokLength, + int LoadedID = 0, + unsigned LoadedOffset = 0); /// \brief Retrieve the memory buffer associated with the given file. /// @@ -633,11 +708,11 @@ public: if (MyInvalid || !Entry.isFile()) { if (Invalid) *Invalid = true; - + return getFakeBufferForRecovery(); } - - return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc, + + return Entry.getFile().getContentCache()->getBuffer(Diag, *this, Loc, Invalid); } @@ -647,22 +722,22 @@ public: if (MyInvalid || !Entry.isFile()) { if (Invalid) *Invalid = true; - + return getFakeBufferForRecovery(); } - return Entry.getFile().getContentCache()->getBuffer(Diag, *this, - SourceLocation(), + return Entry.getFile().getContentCache()->getBuffer(Diag, *this, + SourceLocation(), Invalid); } - + /// getFileEntryForID - Returns the FileEntry record for the provided FileID. const FileEntry *getFileEntryForID(FileID FID) const { bool MyInvalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &MyInvalid); if (MyInvalid || !Entry.isFile()) return 0; - + return Entry.getFile().getContentCache()->OrigEntry; } @@ -677,8 +752,30 @@ public: /// /// \param FID The file ID whose contents will be returned. /// \param Invalid If non-NULL, will be set true if an error occurred. - llvm::StringRef getBufferData(FileID FID, bool *Invalid = 0) const; + StringRef getBufferData(FileID FID, bool *Invalid = 0) const; + /// \brief Get the number of FileIDs (files and macros) that were created + /// during preprocessing of \arg FID, including it. + unsigned getNumCreatedFIDsForFileID(FileID FID) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return 0; + + return Entry.getFile().NumCreatedFIDs; + } + + /// \brief Set the number of FileIDs (files and macros) that were created + /// during preprocessing of \arg FID, including it. + void setNumCreatedFIDsForFileID(FileID FID, unsigned NumFIDs) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return; + + assert(Entry.getFile().NumCreatedFIDs == 0 && "Already set!"); + const_cast<SrcMgr::FileInfo &>(Entry.getFile()).NumCreatedFIDs = NumFIDs; + } //===--------------------------------------------------------------------===// // SourceLocation manipulation methods. @@ -702,34 +799,52 @@ public: /// getLocForStartOfFile - Return the source location corresponding to the /// first byte of the specified file. SourceLocation getLocForStartOfFile(FileID FID) const { - assert(FID.ID < SLocEntryTable.size() && "FileID out of range"); bool Invalid = false; const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); if (Invalid || !Entry.isFile()) return SourceLocation(); - + unsigned FileOffset = Entry.getOffset(); return SourceLocation::getFileLoc(FileOffset); } - /// getInstantiationLoc - Given a SourceLocation object, return the - /// instantiation location referenced by the ID. - SourceLocation getInstantiationLoc(SourceLocation Loc) const { + /// \brief Returns the include location if \arg FID is a #include'd file + /// otherwise it returns an invalid location. + SourceLocation getIncludeLoc(FileID FID) const { + bool Invalid = false; + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); + if (Invalid || !Entry.isFile()) + return SourceLocation(); + + return Entry.getFile().getIncludeLoc(); + } + + /// getExpansionLoc - Given a SourceLocation object, return the expansion + /// location referenced by the ID. + SourceLocation getExpansionLoc(SourceLocation Loc) const { // Handle the non-mapped case inline, defer to out of line code to handle - // instantiations. + // expansions. if (Loc.isFileID()) return Loc; - return getInstantiationLocSlowCase(Loc); + return getExpansionLocSlowCase(Loc); } - /// getImmediateInstantiationRange - Loc is required to be an instantiation - /// location. Return the start/end of the instantiation information. + /// \brief Given \arg Loc, if it is a macro location return the expansion + /// location or the spelling location, depending on if it comes from a + /// macro argument or not. + SourceLocation getFileLoc(SourceLocation Loc) const { + if (Loc.isFileID()) return Loc; + return getFileLocSlowCase(Loc); + } + + /// getImmediateExpansionRange - Loc is required to be an expansion location. + /// Return the start/end of the expansion information. std::pair<SourceLocation,SourceLocation> - getImmediateInstantiationRange(SourceLocation Loc) const; + getImmediateExpansionRange(SourceLocation Loc) const; - /// getInstantiationRange - Given a SourceLocation object, return the - /// range of tokens covered by the instantiation in the ultimate file. + /// getExpansionRange - Given a SourceLocation object, return the range of + /// tokens covered by the expansion the ultimate file. std::pair<SourceLocation,SourceLocation> - getInstantiationRange(SourceLocation Loc) const; + getExpansionRange(SourceLocation Loc) const; /// getSpellingLoc - Given a SourceLocation object, return the spelling @@ -737,7 +852,7 @@ public: /// that make up the lexed token can be found. SourceLocation getSpellingLoc(SourceLocation Loc) const { // Handle the non-mapped case inline, defer to out of line code to handle - // instantiations. + // expansions. if (Loc.isFileID()) return Loc; return getSpellingLocSlowCase(Loc); } @@ -756,11 +871,11 @@ public: 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. + /// getDecomposedExpansionLoc - Decompose the specified location into a raw + /// FileID + Offset pair. If the location is an expansion record, walk + /// through it until we find the final location expanded. std::pair<FileID, unsigned> - getDecomposedInstantiationLoc(SourceLocation Loc) const { + getDecomposedExpansionLoc(SourceLocation Loc) const { FileID FID = getFileID(Loc); const SrcMgr::SLocEntry *E = &getSLocEntry(FID); @@ -768,11 +883,11 @@ public: if (Loc.isFileID()) return std::make_pair(FID, Offset); - return getDecomposedInstantiationLocSlowCase(E); + return getDecomposedExpansionLocSlowCase(E); } /// getDecomposedSpellingLoc - Decompose the specified location into a raw - /// FileID + Offset pair. If the location is an instantiation record, walk + /// FileID + Offset pair. If the location is an expansion record, walk /// through it until we find its spelling record. std::pair<FileID, unsigned> getDecomposedSpellingLoc(SourceLocation Loc) const { @@ -792,12 +907,55 @@ public: return getDecomposedLoc(SpellingLoc).second; } - /// isMacroArgInstantiation - This method tests whether the given source - /// location represents a macro argument's instantiation into the - /// function-like macro definition. Such source locations only appear inside - /// of the instantiation locations representing where a particular - /// function-like macro was expanded. - bool isMacroArgInstantiation(SourceLocation Loc) const; + /// isMacroArgExpansion - This method tests whether the given source location + /// represents a macro argument's expansion into the function-like macro + /// definition. Such source locations only appear inside of the expansion + /// locations representing where a particular function-like macro was + /// expanded. + bool isMacroArgExpansion(SourceLocation Loc) const; + + /// \brief Returns true if \arg Loc is inside the [\arg Start, +\arg Length) + /// chunk of the source location address space. + /// If it's true and \arg RelativeOffset is non-null, it will be set to the + /// relative offset of \arg Loc inside the chunk. + bool isInSLocAddrSpace(SourceLocation Loc, + SourceLocation Start, unsigned Length, + unsigned *RelativeOffset = 0) const { + assert(((Start.getOffset() < NextLocalOffset && + Start.getOffset()+Length <= NextLocalOffset) || + (Start.getOffset() >= CurrentLoadedOffset && + Start.getOffset()+Length < MaxLoadedOffset)) && + "Chunk is not valid SLoc address space"); + unsigned LocOffs = Loc.getOffset(); + unsigned BeginOffs = Start.getOffset(); + unsigned EndOffs = BeginOffs + Length; + if (LocOffs >= BeginOffs && LocOffs < EndOffs) { + if (RelativeOffset) + *RelativeOffset = LocOffs - BeginOffs; + return true; + } + + return false; + } + + /// \brief Return true if both \arg LHS and \arg RHS are in the local source + /// location address space or the loaded one. If it's true and + /// \arg RelativeOffset is non-null, it will be set to the offset of \arg RHS + /// relative to \arg LHS. + bool isInSameSLocAddrSpace(SourceLocation LHS, SourceLocation RHS, + int *RelativeOffset) const { + unsigned LHSOffs = LHS.getOffset(), RHSOffs = RHS.getOffset(); + bool LHSLoaded = LHSOffs >= CurrentLoadedOffset; + bool RHSLoaded = RHSOffs >= CurrentLoadedOffset; + + if (LHSLoaded == RHSLoaded) { + if (RelativeOffset) + *RelativeOffset = RHSOffs - LHSOffs; + return true; + } + + return false; + } //===--------------------------------------------------------------------===// // Queries about the code at a SourceLocation. @@ -811,14 +969,14 @@ public: /// 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 - /// a file sloc, so you must choose a spelling or instantiation location + /// returns zero if the column number isn't known. This may only be called + /// on a file sloc, so you must choose a spelling or expansion location /// before calling this method. - unsigned getColumnNumber(FileID FID, unsigned FilePos, + unsigned getColumnNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid = 0) const; - unsigned getInstantiationColumnNumber(SourceLocation Loc, - bool *Invalid = 0) const; + unsigned getExpansionColumnNumber(SourceLocation Loc, + bool *Invalid = 0) const; unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid = 0) const; @@ -828,8 +986,7 @@ public: /// about to emit a diagnostic. unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid = 0) const; unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid = 0) const; - unsigned getInstantiationLineNumber(SourceLocation Loc, - bool *Invalid = 0) const; + unsigned getExpansionLineNumber(SourceLocation Loc, bool *Invalid = 0) const; unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid = 0) const; /// Return the filename or buffer identifier of the buffer the location is in. @@ -852,8 +1009,8 @@ public: /// or GNU line marker directives. This provides a view on the data that a /// user should see in diagnostics, for example. /// - /// Note that a presumed location is always given as the instantiation point - /// of an instantiation location, not at the spelling location. + /// Note that a presumed location is always given as the expansion point of + /// an expansion location, not at the spelling location. /// /// \returns The presumed location of the specified SourceLocation. If the /// presumed location cannot be calculate (e.g., because \p Loc is invalid @@ -884,33 +1041,18 @@ public: return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; } - /// \brief Given a specific chunk of a FileID (FileID with offset+length), - /// returns true if \arg Loc is inside that chunk and sets relative offset - /// (offset of \arg Loc from beginning of chunk) to \arg relativeOffset. - bool isInFileID(SourceLocation Loc, - FileID FID, unsigned offset, unsigned length, - unsigned *relativeOffset = 0) const { - assert(!FID.isInvalid()); - if (Loc.isInvalid()) - return false; - - unsigned start = getSLocEntry(FID).getOffset() + offset; - unsigned end = start + length; - -#ifndef NDEBUG - // Make sure offset/length describe a chunk inside the given FileID. - unsigned NextOffset; - if (FID.ID+1 == SLocEntryTable.size()) - NextOffset = getNextOffset(); - else - NextOffset = getSLocEntry(FID.ID+1).getOffset(); - assert(start < NextOffset); - assert(end < NextOffset); -#endif - - if (Loc.getOffset() >= start && Loc.getOffset() < end) { - if (relativeOffset) - *relativeOffset = Loc.getOffset() - start; + /// \brief The size of the SLocEnty that \arg FID represents. + unsigned getFileIDSize(FileID FID) const; + + /// \brief Given a specific FileID, returns true if \arg Loc is inside that + /// FileID chunk and sets relative offset (offset of \arg Loc from beginning + /// of FileID) to \arg relativeOffset. + bool isInFileID(SourceLocation Loc, FileID FID, + unsigned *RelativeOffset = 0) const { + unsigned Offs = Loc.getOffset(); + if (isOffsetInFileID(FID, Offs)) { + if (RelativeOffset) + *RelativeOffset = Offs - getSLocEntry(FID).getOffset(); return true; } @@ -923,7 +1065,7 @@ public: /// getLineTableFilenameID - Return the uniqued ID for the specified filename. /// - unsigned getLineTableFilenameID(llvm::StringRef Str); + unsigned getLineTableFilenameID(StringRef Str); /// 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 @@ -948,11 +1090,11 @@ public: size_t getContentCacheSize() const { return ContentCacheAlloc.getTotalMemory(); } - + struct MemoryBufferSizes { const size_t malloc_bytes; const size_t mmap_bytes; - + MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} }; @@ -961,6 +1103,10 @@ public: /// by heap-backed versus mmap'ed memory. MemoryBufferSizes getMemoryBufferSizes() const; + // Return the amount of memory used for various side tables and + // data structures in the SourceManager. + size_t getDataStructureSizes() const; + //===--------------------------------------------------------------------===// // Other miscellaneous methods. //===--------------------------------------------------------------------===// @@ -969,25 +1115,67 @@ public: /// /// If the source file is included multiple times, the source location will /// be based upon the first inclusion. - SourceLocation getLocation(const FileEntry *SourceFile, - unsigned Line, unsigned Col); + SourceLocation translateFileLineCol(const FileEntry *SourceFile, + unsigned Line, unsigned Col) const; + + /// \brief Get the FileID for the given file. + /// + /// If the source file is included multiple times, the FileID will be the + /// first inclusion. + FileID translateFile(const FileEntry *SourceFile) const; + + /// \brief Get the source location in \arg FID for the given line:col. + /// Returns null location if \arg FID is not a file SLocEntry. + SourceLocation translateLineCol(FileID FID, + unsigned Line, unsigned Col) const; + + /// \brief If \arg Loc points inside a function macro argument, the returned + /// location will be the macro location in which the argument was expanded. + /// If a macro argument is used multiple times, the expanded location will + /// be at the first expansion of the argument. + /// e.g. + /// MY_MACRO(foo); + /// ^ + /// Passing a file location pointing at 'foo', will yield a macro location + /// where 'foo' was expanded into. + SourceLocation getMacroArgExpandedLocation(SourceLocation Loc) 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 Comparison function class. + class LocBeforeThanCompare : public std::binary_function<SourceLocation, + SourceLocation, bool> { + SourceManager &SM; + + public: + explicit LocBeforeThanCompare(SourceManager &SM) : SM(SM) { } + + bool operator()(SourceLocation LHS, SourceLocation RHS) const { + return SM.isBeforeInTranslationUnit(LHS, RHS); + } + }; + /// \brief Determines the order of 2 source locations in the "source location /// address space". - static bool isBeforeInSourceLocationOffset(SourceLocation LHS, - SourceLocation RHS) { - return isBeforeInSourceLocationOffset(LHS, RHS.getOffset()); + bool isBeforeInSLocAddrSpace(SourceLocation LHS, SourceLocation RHS) const { + return isBeforeInSLocAddrSpace(LHS, RHS.getOffset()); } /// \brief Determines the order of a source location and a source location /// offset in the "source location address space". - static bool isBeforeInSourceLocationOffset(SourceLocation LHS, unsigned RHS) { - return LHS.getOffset() < RHS; + /// + /// Note that we always consider source locations loaded from + bool isBeforeInSLocAddrSpace(SourceLocation LHS, unsigned RHS) const { + unsigned LHSOffset = LHS.getOffset(); + bool LHSLoaded = LHSOffset >= CurrentLoadedOffset; + bool RHSLoaded = RHS >= CurrentLoadedOffset; + if (LHSLoaded == RHSLoaded) + return LHSOffset < RHS; + + return LHSLoaded; } // Iterators over FileInfos. @@ -1003,53 +1191,80 @@ public: /// void PrintStats() const; - unsigned sloc_entry_size() const { return SLocEntryTable.size(); } - - // FIXME: Exposing this is a little gross; what we want is a good way - // to iterate the entries that were not defined in an AST file (or - // any other external source). - unsigned sloc_loaded_entry_size() const { return SLocEntryLoaded.size(); } - - const SrcMgr::SLocEntry &getSLocEntry(unsigned ID, bool *Invalid = 0) const { - assert(ID < SLocEntryTable.size() && "Invalid id"); - // If we haven't loaded this source-location entry from the external source - // yet, do so now. - if (ExternalSLocEntries && - ID < SLocEntryLoaded.size() && - !SLocEntryLoaded[ID] && - ExternalSLocEntries->ReadSLocEntry(ID) && - Invalid) - *Invalid = true; - - return SLocEntryTable[ID]; + /// \brief Get the number of local SLocEntries we have. + unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); } + + /// \brief Get a local SLocEntry. This is exposed for indexing. + const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index, + bool *Invalid = 0) const { + assert(Index < LocalSLocEntryTable.size() && "Invalid index"); + return LocalSLocEntryTable[Index]; + } + + /// \brief Get the number of loaded SLocEntries we have. + unsigned loaded_sloc_entry_size() const { return LoadedSLocEntryTable.size();} + + /// \brief Get a loaded SLocEntry. This is exposed for indexing. + const SrcMgr::SLocEntry &getLoadedSLocEntry(unsigned Index, bool *Invalid=0) const { + assert(Index < LoadedSLocEntryTable.size() && "Invalid index"); + if (!SLocEntryLoaded[Index]) + ExternalSLocEntries->ReadSLocEntry(-(static_cast<int>(Index) + 2)); + return LoadedSLocEntryTable[Index]; } const SrcMgr::SLocEntry &getSLocEntry(FileID FID, bool *Invalid = 0) const { - return getSLocEntry(FID.ID, Invalid); + return getSLocEntryByID(FID.ID); } - unsigned getNextOffset() const { return NextOffset; } + unsigned getNextLocalOffset() const { return NextLocalOffset; } + + void setExternalSLocEntrySource(ExternalSLocEntrySource *Source) { + assert(LoadedSLocEntryTable.empty() && + "Invalidating existing loaded entries"); + ExternalSLocEntries = Source; + } - /// \brief Preallocate some number of source location entries, which - /// will be loaded as needed from the given external source. - void PreallocateSLocEntries(ExternalSLocEntrySource *Source, - unsigned NumSLocEntries, - unsigned NextOffset); + /// \brief Allocate a number of loaded SLocEntries, which will be actually + /// loaded on demand from the external source. + /// + /// NumSLocEntries will be allocated, which occupy a total of TotalSize space + /// in the global source view. The lowest ID and the base offset of the + /// entries will be returned. + std::pair<int, unsigned> + AllocateLoadedSLocEntries(unsigned NumSLocEntries, unsigned TotalSize); + + /// \brief Returns true if \arg Loc came from a PCH/Module. + bool isLoadedSourceLocation(SourceLocation Loc) const { + return Loc.getOffset() >= CurrentLoadedOffset; + } - /// \brief Clear out any preallocated source location entries that - /// haven't already been loaded. - void ClearPreallocatedSLocEntries(); + /// \brief Returns true if \arg Loc did not come from a PCH/Module. + bool isLocalSourceLocation(SourceLocation Loc) const { + return Loc.getOffset() < NextLocalOffset; + } private: const llvm::MemoryBuffer *getFakeBufferForRecovery() const; - /// createInstantiationLoc - Implements the common elements of storing an - /// instantiation info struct into the SLocEntry table and producing a source + /// \brief Get the entry with the given unwrapped FileID. + const SrcMgr::SLocEntry &getSLocEntryByID(int ID) const { + assert(ID != -1 && "Using FileID sentinel value"); + if (ID < 0) + return getLoadedSLocEntryByID(ID); + return getLocalSLocEntry(static_cast<unsigned>(ID)); + } + + const SrcMgr::SLocEntry &getLoadedSLocEntryByID(int ID) const { + return getLoadedSLocEntry(static_cast<unsigned>(-ID - 2)); + } + + /// createExpansionLoc - Implements the common elements of storing an + /// expansion info struct into the SLocEntry table and producing a source /// location that refers to it. - SourceLocation createInstantiationLocImpl(const SrcMgr::InstantiationInfo &II, - unsigned TokLength, - unsigned PreallocatedID = 0, - unsigned Offset = 0); + SourceLocation createExpansionLocImpl(const SrcMgr::ExpansionInfo &Expansion, + unsigned TokLength, + int LoadedID = 0, + unsigned LoadedOffset = 0); /// isOffsetInFileID - Return true if the specified FileID contains the /// specified SourceLocation offset. This is a very hot method. @@ -1058,10 +1273,17 @@ private: // 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; + // If this is the very last entry then it does. + if (FID.ID == -2) + return true; + + // If it is the last local entry, then it does if the location is local. + if (static_cast<unsigned>(FID.ID+1) == LocalSLocEntryTable.size()) { + return SLocOffset < NextLocalOffset; + } + // Otherwise, the entry after it has to not include it. This works for both + // local and loaded entries. return SLocOffset < getSLocEntry(FileID::get(FID.ID+1)).getOffset(); } @@ -1071,8 +1293,7 @@ private: FileID createFileID(const SrcMgr::ContentCache* File, SourceLocation IncludePos, SrcMgr::CharacteristicKind DirCharacter, - unsigned PreallocatedID = 0, - unsigned Offset = 0); + int LoadedID, unsigned LoadedOffset); const SrcMgr::ContentCache * getOrCreateContentCache(const FileEntry *SourceFile); @@ -1083,15 +1304,22 @@ private: createMemBufferContentCache(const llvm::MemoryBuffer *Buf); FileID getFileIDSlow(unsigned SLocOffset) const; + FileID getFileIDLocal(unsigned SLocOffset) const; + FileID getFileIDLoaded(unsigned SLocOffset) const; - SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const; + SourceLocation getExpansionLocSlowCase(SourceLocation Loc) const; SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; + SourceLocation getFileLocSlowCase(SourceLocation Loc) const; std::pair<FileID, unsigned> - getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E) const; + getDecomposedExpansionLocSlowCase(const SrcMgr::SLocEntry *E) const; std::pair<FileID, unsigned> getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const; + void computeMacroArgsCache(MacroArgsMap *&MacroArgsCache, FileID FID) const; + + friend class ASTReader; + friend class ASTWriter; }; diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h index 3f5d1a35e5951..1cb16b458f41c 100644 --- a/include/clang/Basic/SourceManagerInternals.h +++ b/include/clang/Basic/SourceManagerInternals.h @@ -84,7 +84,7 @@ class LineTableInfo { /// 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; + std::map<int, std::vector<LineEntry> > LineEntries; public: LineTableInfo() { } @@ -97,32 +97,32 @@ public: ~LineTableInfo() {} - unsigned getLineTableFilenameID(llvm::StringRef Str); + unsigned getLineTableFilenameID(StringRef Str); const char *getFilename(unsigned ID) const { assert(ID < FilenamesByID.size() && "Invalid FilenameID"); return FilenamesByID[ID]->getKeyData(); } unsigned getNumFilenames() const { return FilenamesByID.size(); } - void AddLineNote(unsigned FID, unsigned Offset, + void AddLineNote(int FID, unsigned Offset, unsigned LineNo, int FilenameID); - void AddLineNote(unsigned FID, unsigned Offset, + void AddLineNote(int FID, unsigned Offset, 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); + const LineEntry *FindNearestLineEntry(int FID, unsigned Offset); // Low-level access - typedef std::map<unsigned, std::vector<LineEntry> >::iterator iterator; + typedef std::map<int, std::vector<LineEntry> >::iterator iterator; iterator begin() { return LineEntries.begin(); } iterator end() { return LineEntries.end(); } /// \brief Add a new line entry that has already been encoded into /// the internal representation of the line table. - void AddEntry(unsigned FID, const std::vector<LineEntry> &Entries); + void AddEntry(int FID, const std::vector<LineEntry> &Entries); }; } // end namespace clang diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index cfce0ccbc9dd3..2a95d6165c0d1 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -40,6 +40,7 @@ namespace clang { TST_char16, // C++0x char16_t TST_char32, // C++0x char32_t TST_int, + TST_half, // OpenCL half, ARM NEON __fp16 TST_float, TST_double, TST_bool, // _Bool @@ -57,6 +58,7 @@ namespace clang { TST_underlyingType, // __underlying_type for C++0x TST_auto, // C++0x auto TST_unknown_anytype, // __unknown_anytype extension + TST_atomic, // C1X _Atomic TST_error // erroneous type }; @@ -146,6 +148,7 @@ namespace clang { SC_PrivateExtern, // These are only legal on variables. + SC_OpenCLWorkGroupLocal, SC_Auto, SC_Register }; diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 73996e43d5dab..7b3d7762c24aa 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -78,6 +78,9 @@ def ParenListExpr : DStmt<Expr>; def VAArgExpr : DStmt<Expr>; def GenericSelectionExpr : DStmt<Expr>; +// Atomic expressions +def AtomicExpr : DStmt<Expr>; + // GNU Extensions. def AddrLabelExpr : DStmt<Expr>; def StmtExpr : DStmt<Expr>; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 4559cf2f64bed..a87af2fbbc7a1 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_TARGETINFO_H #define LLVM_CLANG_BASIC_TARGETINFO_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -31,7 +32,7 @@ struct fltSemantics; } namespace clang { -class Diagnostic; +class DiagnosticsEngine; class LangOptions; class MacroBuilder; class SourceLocation; @@ -68,21 +69,24 @@ protected: unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; + unsigned char HalfWidth, HalfAlign; unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; unsigned char LongDoubleWidth, LongDoubleAlign; unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; + unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; const char *DescriptionString; const char *UserLabelPrefix; const char *MCountName; - const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat; + const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, + *LongDoubleFormat; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI CXXABI; const LangAS::Map *AddrSpaceMap; - mutable llvm::StringRef PlatformName; + mutable StringRef PlatformName; mutable VersionTuple PlatformMinVersion; unsigned HasAlignMac68kSupport : 1; @@ -97,7 +101,8 @@ public: /// \param Opts - The options to use to initialize the target. The target may /// modify the options to canonicalize the target feature information to match /// what the backend expects. - static TargetInfo* CreateTargetInfo(Diagnostic &Diags, TargetOptions &Opts); + static TargetInfo* CreateTargetInfo(DiagnosticsEngine &Diags, + TargetOptions &Opts); virtual ~TargetInfo(); @@ -131,6 +136,16 @@ protected: /// boundary. unsigned UseBitFieldTypeAlignment : 1; + /// Control whether zero length bitfields (e.g., int : 0;) force alignment of + /// the next bitfield. If the alignment of the zero length bitfield is + /// greater than the member that follows it, `bar', `bar' will be aligned as + /// the type of the zero-length bitfield. + unsigned UseZeroLengthBitfieldAlignment : 1; + + /// If non-zero, specifies a fixed alignment value for bitfields that follow + /// zero length bitfield, regardless of the zero length bitfield type. + unsigned ZeroLengthBitfieldBoundary; + public: IntType getSizeType() const { return SizeType; } IntType getIntMaxType() const { return IntMaxType; } @@ -211,6 +226,11 @@ public: unsigned getChar32Width() const { return getTypeWidth(Char32Type); } unsigned getChar32Align() const { return getTypeAlign(Char32Type); } + /// getHalfWidth/Align/Format - Return the size/align/format of 'half'. + unsigned getHalfWidth() const { return HalfWidth; } + unsigned getHalfAlign() const { return HalfAlign; } + const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; } + /// getFloatWidth/Align/Format - Return the size/align/format of 'float'. unsigned getFloatWidth() const { return FloatWidth; } unsigned getFloatAlign() const { return FloatAlign; } @@ -234,6 +254,14 @@ public: unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; } unsigned getLargeArrayAlign() const { return LargeArrayAlign; } + /// getMaxAtomicPromoteWidth - Return the maximum width lock-free atomic + /// operation which will ever be supported for the given target + unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; } + /// getMaxAtomicInlineWidth - Return the maximum width lock-free atomic + /// operation which can be inlined given the supported features of the + /// given target. + unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; } + /// getIntMaxTWidth - Return the size of intmax_t and uintmax_t for this /// target, in bits. unsigned getIntMaxTWidth() const { @@ -261,10 +289,24 @@ public: return MCountName; } + /// useBitFieldTypeAlignment() - Check whether the alignment of bit-field + /// types is respected when laying out structures. bool useBitFieldTypeAlignment() const { return UseBitFieldTypeAlignment; } + /// useZeroLengthBitfieldAlignment() - Check whether zero length bitfields + /// should force alignment of the next member. + bool useZeroLengthBitfieldAlignment() const { + return UseZeroLengthBitfieldAlignment; + } + + /// getZeroLengthBitfieldBoundary() - Get the fixed alignment value in bits + /// for a member that follows a zero length bitfield. + unsigned getZeroLengthBitfieldBoundary() const { + return ZeroLengthBitfieldBoundary; + } + /// hasAlignMac68kSupport - Check whether this target support '#pragma options /// align=mac68k'. bool hasAlignMac68kSupport() const { @@ -306,16 +348,16 @@ public: /// isValidClobber - Returns whether the passed in string is /// a valid clobber in an inline asm statement. This is used by /// Sema. - bool isValidClobber(llvm::StringRef Name) const; + bool isValidClobber(StringRef Name) const; /// isValidGCCRegisterName - Returns whether the passed in string /// is a valid register name according to GCC. This is used by Sema for /// inline asm statements. - bool isValidGCCRegisterName(llvm::StringRef Name) const; + bool isValidGCCRegisterName(StringRef Name) const; // getNormalizedGCCRegisterName - Returns the "normalized" GCC register name. // For example, on x86 it will return "ax" when "eax" is passed in. - llvm::StringRef getNormalizedGCCRegisterName(llvm::StringRef Name) const; + StringRef getNormalizedGCCRegisterName(StringRef Name) const; struct ConstraintInfo { enum { @@ -331,7 +373,7 @@ public: std::string ConstraintStr; // constraint: "=rm" std::string Name; // Operand name: [foo] with no []'s. public: - ConstraintInfo(llvm::StringRef ConstraintStr, llvm::StringRef Name) + ConstraintInfo(StringRef ConstraintStr, StringRef Name) : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()), Name(Name.str()) {} @@ -444,7 +486,7 @@ public: /// and give good diagnostics in cases when the assembler or code generator /// would otherwise reject the section specifier. /// - virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const { + virtual std::string isValidSectionSpecifier(StringRef SR) const { return ""; } @@ -453,11 +495,9 @@ public: /// language options which change the target configuration. virtual void setForcedLangOptions(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, - llvm::StringMap<bool> &Features) const { + /// getDefaultFeatures - Get the default set of target features for the CPU; + /// this should include all legal feature strings on the target. + virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const { } /// getABI - Get the ABI in use. @@ -473,10 +513,8 @@ public: /// setCPU - Target the specific CPU. /// /// \return - False on error (invalid CPU name). - // - // FIXME: Remove this. virtual bool setCPU(const std::string &Name) { - return true; + return false; } /// setABI - Use the specific ABI. @@ -565,7 +603,7 @@ public: /// \brief Retrieve the name of the platform as it is used in the /// availability attribute. - llvm::StringRef getPlatformName() const { return PlatformName; } + StringRef getPlatformName() const { return PlatformName; } /// \brief Retrieve the minimum desired version of the platform, to /// which the program should be compiled. diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 86172b83ff422..35a881c660a29 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -89,6 +89,9 @@ PPKEYWORD(sccs) PPKEYWORD(assert) PPKEYWORD(unassert) +// Clang extensions +PPKEYWORD(__export_macro__) + //===----------------------------------------------------------------------===// // Language keywords. //===----------------------------------------------------------------------===// @@ -114,13 +117,23 @@ TOK(raw_identifier) // Used only in raw lexing mode. TOK(numeric_constant) // 0x123 // C99 6.4.4: Character Constants -TOK(char_constant) // 'a' L'b' +TOK(char_constant) // 'a' +TOK(wide_char_constant) // L'b' + +// C++0x Character Constants +TOK(utf16_char_constant) // u'a' +TOK(utf32_char_constant) // U'a' // C99 6.4.5: String Literals. TOK(string_literal) // "foo" TOK(wide_string_literal) // L"foo" TOK(angle_string_literal)// <foo> +// C++0x String Literals. +TOK(utf8_string_literal) // u8"foo" +TOK(utf16_string_literal)// u"foo" +TOK(utf32_string_literal)// U"foo" + // C99 6.4.6: Punctuators. PUNCTUATOR(l_square, "[") PUNCTUATOR(r_square, "]") @@ -236,6 +249,8 @@ KEYWORD(unsigned , KEYALL) KEYWORD(void , KEYALL) KEYWORD(volatile , KEYALL) KEYWORD(while , KEYALL) +KEYWORD(_Alignas , KEYALL) +KEYWORD(_Atomic , KEYALL) KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) @@ -289,6 +304,7 @@ CXX_KEYWORD_OPERATOR(xor , caret) CXX_KEYWORD_OPERATOR(xor_eq , caretequal) // C++0x keywords +KEYWORD(alignas , KEYCXX0X) KEYWORD(alignof , KEYCXX0X) KEYWORD(char16_t , KEYCXX0X) KEYWORD(char32_t , KEYCXX0X) @@ -387,6 +403,8 @@ KEYWORD(__array_extent , KEYCXX) // Apple Extension. KEYWORD(__private_extern__ , KEYALL) +KEYWORD(__import_module__ , KEYALL) +KEYWORD(__module_private__ , KEYALL) // Microsoft Extension. KEYWORD(__declspec , KEYALL) @@ -395,6 +413,7 @@ KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) KEYWORD(__thiscall , KEYALL) KEYWORD(__forceinline , KEYALL) +KEYWORD(__unaligned , KEYMS) // OpenCL-specific keywords KEYWORD(__kernel , KEYOPENCL) @@ -422,6 +441,12 @@ KEYWORD(__pascal , KEYALL) KEYWORD(__vector , KEYALTIVEC) KEYWORD(__pixel , KEYALTIVEC) +// ARM NEON extensions. +ALIAS("__fp16", half , KEYALL) + +// OpenCL Extension. +KEYWORD(half , KEYOPENCL) + // Objective-C ARC keywords. KEYWORD(__bridge , KEYARC) KEYWORD(__bridge_transfer , KEYARC) @@ -455,6 +480,7 @@ ALIAS("__volatile__" , volatile , KEYALL) // Microsoft extensions which should be disabled in strict conformance mode KEYWORD(__ptr64 , KEYMS) +KEYWORD(__ptr32 , KEYMS) KEYWORD(__w64 , KEYMS) KEYWORD(__uuidof , KEYMS | KEYBORLAND) KEYWORD(__try , KEYMS | KEYBORLAND) diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h index 91eb68eaad9f5..30ef6641efc13 100644 --- a/include/clang/Basic/VersionTuple.h +++ b/include/clang/Basic/VersionTuple.h @@ -14,13 +14,10 @@ #ifndef LLVM_CLANG_BASIC_VERSIONTUPLE_H #define LLVM_CLANG_BASIC_VERSIONTUPLE_H +#include "clang/Basic/LLVM.h" #include "llvm/ADT/Optional.h" #include <string> -namespace llvm { - class raw_ostream; -} - namespace clang { /// \brief Represents a version number in the form major[.minor[.subminor]]. @@ -120,7 +117,7 @@ public: }; /// \brief Print a version number. -llvm::raw_ostream& operator<<(llvm::raw_ostream &Out, const VersionTuple &V); +raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V); } // end namespace clang #endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H |