summaryrefslogtreecommitdiff
path: root/include/clang/Basic
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Basic')
-rw-r--r--include/clang/Basic/Attr.td149
-rw-r--r--include/clang/Basic/Builtins.def62
-rw-r--r--include/clang/Basic/Builtins.h17
-rw-r--r--include/clang/Basic/DeclNodes.td1
-rw-r--r--include/clang/Basic/DelayedCleanupPool.h5
-rw-r--r--include/clang/Basic/Diagnostic.h296
-rw-r--r--include/clang/Basic/Diagnostic.td10
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td15
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td157
-rw-r--r--include/clang/Basic/DiagnosticGroups.td54
-rw-r--r--include/clang/Basic/DiagnosticIDs.h137
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td69
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td90
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td783
-rw-r--r--include/clang/Basic/FileManager.h33
-rw-r--r--include/clang/Basic/IdentifierTable.h46
-rw-r--r--include/clang/Basic/LLVM.h53
-rw-r--r--include/clang/Basic/LangOptions.def158
-rw-r--r--include/clang/Basic/LangOptions.h277
-rw-r--r--include/clang/Basic/MacroBuilder.h10
-rw-r--r--include/clang/Basic/Makefile20
-rw-r--r--include/clang/Basic/OnDiskHashTable.h18
-rw-r--r--include/clang/Basic/OpenCLExtensions.def4
-rw-r--r--include/clang/Basic/PartialDiagnostic.h31
-rw-r--r--include/clang/Basic/PrettyStackTrace.h2
-rw-r--r--include/clang/Basic/SourceLocation.h70
-rw-r--r--include/clang/Basic/SourceManager.h780
-rw-r--r--include/clang/Basic/SourceManagerInternals.h14
-rw-r--r--include/clang/Basic/Specifiers.h3
-rw-r--r--include/clang/Basic/StmtNodes.td3
-rw-r--r--include/clang/Basic/TargetInfo.h74
-rw-r--r--include/clang/Basic/TokenKinds.def28
-rw-r--r--include/clang/Basic/VersionTuple.h7
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