aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-05-04 16:12:48 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-05-04 16:12:48 +0000
commit0883ccd9eac3b974df00e6548ee319a7dd3646f4 (patch)
treed6a70c3518b8dea8be7062438d7e8676820ed17f /include/clang
parent60bfabcd8ce617297c0d231f77d14ab507e98796 (diff)
downloadsrc-0883ccd9eac3b974df00e6548ee319a7dd3646f4.tar.gz
src-0883ccd9eac3b974df00e6548ee319a7dd3646f4.zip
Update clang to r103004.
Notes
Notes: svn path=/vendor/clang/dist/; revision=207619
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/APValue.h8
-rw-r--r--include/clang/AST/ASTContext.h48
-rw-r--r--include/clang/AST/ASTVector.h397
-rw-r--r--include/clang/AST/CanonicalType.h1
-rw-r--r--include/clang/AST/Decl.h96
-rw-r--r--include/clang/AST/DeclAccessPair.h72
-rw-r--r--include/clang/AST/DeclBase.h99
-rw-r--r--include/clang/AST/DeclCXX.h40
-rw-r--r--include/clang/AST/DeclContextInternals.h4
-rw-r--r--include/clang/AST/DeclFriend.h10
-rw-r--r--include/clang/AST/DeclNodes.def8
-rw-r--r--include/clang/AST/DeclObjC.h75
-rw-r--r--include/clang/AST/DeclTemplate.h109
-rw-r--r--include/clang/AST/DeclarationName.h11
-rw-r--r--include/clang/AST/DependentDiagnostic.h9
-rw-r--r--include/clang/AST/Expr.h331
-rw-r--r--include/clang/AST/ExprCXX.h104
-rw-r--r--include/clang/AST/ExprObjC.h485
-rw-r--r--include/clang/AST/ExternalASTSource.h7
-rw-r--r--include/clang/AST/Stmt.h8
-rw-r--r--include/clang/AST/StmtNodes.def3
-rw-r--r--include/clang/AST/StmtObjC.h137
-rw-r--r--include/clang/AST/TemplateName.h6
-rw-r--r--include/clang/AST/Type.h84
-rw-r--r--include/clang/AST/TypeNodes.def4
-rw-r--r--include/clang/AST/UnresolvedSet.h51
-rw-r--r--include/clang/AST/UsuallyTinyPtrVector.h105
-rw-r--r--include/clang/Analysis/Support/Optional.h66
-rw-r--r--include/clang/Basic/Builtins.def12
-rw-r--r--include/clang/Basic/BuiltinsPPC.def92
-rw-r--r--include/clang/Basic/BuiltinsX86.def2
-rw-r--r--include/clang/Basic/Diagnostic.h49
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td10
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td19
-rw-r--r--include/clang/Basic/DiagnosticGroups.td13
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td319
-rw-r--r--include/clang/Basic/LangOptions.h19
-rw-r--r--include/clang/Basic/SourceLocation.h11
-rw-r--r--include/clang/Basic/SourceManager.h19
-rw-r--r--include/clang/Basic/TargetInfo.h34
-rw-r--r--include/clang/Basic/Version.h4
-rw-r--r--include/clang/Checker/BugReporter/BugReporter.h1
-rw-r--r--include/clang/Checker/PathSensitive/AnalysisManager.h8
-rw-r--r--include/clang/Checker/PathSensitive/GRCoreEngine.h27
-rw-r--r--include/clang/Checker/PathSensitive/GRExprEngine.h24
-rw-r--r--include/clang/Checker/PathSensitive/MemRegion.h6
-rw-r--r--include/clang/Checker/PathSensitive/Store.h3
-rw-r--r--include/clang/Checker/PathSensitive/ValueManager.h6
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h19
-rw-r--r--include/clang/Driver/CC1Options.td40
-rw-r--r--include/clang/Driver/Options.td14
-rw-r--r--include/clang/Driver/Tool.h4
-rw-r--r--include/clang/Driver/ToolChain.h7
-rw-r--r--include/clang/Frontend/ASTConsumers.h4
-rw-r--r--include/clang/Frontend/Analyses.def25
-rw-r--r--include/clang/Frontend/AnalysisConsumer.h1
-rw-r--r--include/clang/Frontend/DiagnosticOptions.h5
-rw-r--r--include/clang/Frontend/FixItRewriter.h59
-rw-r--r--include/clang/Frontend/FrontendActions.h8
-rw-r--r--include/clang/Frontend/FrontendOptions.h9
-rw-r--r--include/clang/Frontend/PCHBitCodes.h6
-rw-r--r--include/clang/Frontend/PCHReader.h5
-rw-r--r--include/clang/Frontend/StmtXML.def9
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h2
-rw-r--r--include/clang/Frontend/VerifyDiagnosticsClient.h19
-rw-r--r--include/clang/Lex/PPCallbacks.h15
-rw-r--r--include/clang/Lex/Preprocessor.h10
-rw-r--r--include/clang/Lex/TokenConcatenation.h4
-rw-r--r--include/clang/Makefile27
-rw-r--r--include/clang/Parse/Action.h284
-rw-r--r--include/clang/Parse/AttributeList.h4
-rw-r--r--include/clang/Parse/DeclSpec.h35
-rw-r--r--include/clang/Parse/Parser.h62
-rw-r--r--include/clang/Parse/Scope.h41
-rw-r--r--include/clang/Rewrite/Rewriter.h30
77 files changed, 2954 insertions, 856 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index 9d4bff893f02..5effa9057a4e 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -122,13 +122,17 @@ public:
return const_cast<APValue*>(this)->getFloat();
}
- APValue &getVectorElt(unsigned i) const {
+ APValue &getVectorElt(unsigned i) {
assert(isVector() && "Invalid accessor");
return ((Vec*)(char*)Data)->Elts[i];
}
+ const APValue &getVectorElt(unsigned i) const {
+ assert(isVector() && "Invalid accessor");
+ return ((const Vec*)(const char*)Data)->Elts[i];
+ }
unsigned getVectorLength() const {
assert(isVector() && "Invalid accessor");
- return ((Vec*)(void *)Data)->NumElts;
+ return ((const Vec*)(const void *)Data)->NumElts;
}
APSInt &getComplexIntReal() {
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index c41857ec0200..f8a8f179ae58 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -25,6 +25,7 @@
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/CanonicalType.h"
+#include "clang/AST/UsuallyTinyPtrVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/OwningPtr.h"
@@ -34,6 +35,7 @@
namespace llvm {
struct fltSemantics;
+ class raw_ostream;
}
namespace clang {
@@ -70,28 +72,6 @@ namespace clang {
namespace Builtin { class Context; }
-/// \brief A vector of C++ member functions that is optimized for
-/// storing a single method.
-class CXXMethodVector {
- /// \brief Storage for the vector.
- ///
- /// When the low bit is zero, this is a const CXXMethodDecl *. When the
- /// low bit is one, this is a std::vector<const CXXMethodDecl *> *.
- mutable uintptr_t Storage;
-
- typedef std::vector<const CXXMethodDecl *> vector_type;
-
-public:
- CXXMethodVector() : Storage(0) { }
-
- typedef const CXXMethodDecl **iterator;
- iterator begin() const;
- iterator end() const;
-
- void push_back(const CXXMethodDecl *Method);
- void Destroy();
-};
-
/// ASTContext - This class holds long-lived AST nodes (such as types and
/// decls) that can be referred to throughout the semantic analysis of a file.
class ASTContext {
@@ -164,6 +144,8 @@ class ASTContext {
QualType ObjCConstantStringType;
RecordDecl *CFConstantStringTypeDecl;
+ RecordDecl *NSConstantStringTypeDecl;
+
RecordDecl *ObjCFastEnumerationStateTypeDecl;
/// \brief The type for the C FILE type.
@@ -250,6 +232,7 @@ class ASTContext {
/// Since most C++ member functions aren't virtual and therefore
/// don't override anything, we store the overridden functions in
/// this map on the side rather than within the CXXMethodDecl structure.
+ typedef UsuallyTinyPtrVector<const CXXMethodDecl> CXXMethodVector;
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
TranslationUnitDecl *TUDecl;
@@ -617,11 +600,13 @@ public:
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
unsigned NumArgs,
- QualType Canon = QualType());
+ QualType Canon = QualType(),
+ bool IsCurrentInstantiation = false);
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgumentListInfo &Args,
- QualType Canon = QualType());
+ QualType Canon = QualType(),
+ bool IsCurrentInstantiation = false);
TypeSourceInfo *
getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc,
@@ -688,6 +673,19 @@ public:
// constant CFStrings.
QualType getCFConstantStringType();
+ // getNSConstantStringType - Return the C structure type used to represent
+ // constant NSStrings.
+ QualType getNSConstantStringType();
+ /// Get the structure type used to representation NSStrings, or NULL
+ /// if it hasn't yet been built.
+ QualType getRawNSConstantStringType() {
+ if (NSConstantStringTypeDecl)
+ return getTagDeclType(NSConstantStringTypeDecl);
+ return QualType();
+ }
+ void setNSConstantStringType(QualType T);
+
+
/// Get the structure type used to representation CFStrings, or NULL
/// if it hasn't yet been built.
QualType getRawCFConstantStringType() {
@@ -937,6 +935,8 @@ public:
/// layout of the specified Objective-C interface.
const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
+ void DumpRecordLayout(const RecordDecl *RD, llvm::raw_ostream &OS);
+
/// getASTObjCImplementationLayout - Get or compute information about
/// the layout of the specified Objective-C implementation. This may
/// differ from the interface if synthesized ivars are present.
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
new file mode 100644
index 000000000000..217dfade525f
--- /dev/null
+++ b/include/clang/AST/ASTVector.h
@@ -0,0 +1,397 @@
+//===- ASTVector.h - Vector that uses ASTContext for allocation --*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides ASTVector, a vector ADT whose contents are
+// allocated using the allocator associated with an ASTContext..
+//
+//===----------------------------------------------------------------------===//
+
+// FIXME: Most of this is copy-and-paste from BumpVector.h and SmallVector.h.
+// We can refactor this core logic into something common.
+
+#ifndef LLVM_CLANG_AST_VECTOR
+#define LLVM_CLANG_AST_VECTOR
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include <algorithm>
+#include <memory>
+#include <cstring>
+
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+ // Work around flawed VC++ implementation of std::uninitialized_copy. Define
+ // additional overloads so that elements with pointer types are recognized as
+ // scalars and not objects, causing bizarre type conversion errors.
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+#else
+ // FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
+ // is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
+namespace clang {
+
+template<typename T>
+class ASTVector {
+ T *Begin, *End, *Capacity;
+
+ void setEnd(T *P) { this->End = P; }
+
+public:
+ // Default ctor - Initialize to empty.
+ explicit ASTVector(ASTContext &C, unsigned N = 0)
+ : Begin(NULL), End(NULL), Capacity(NULL) {
+ reserve(C, N);
+ }
+
+ ~ASTVector() {
+ if (llvm::is_class<T>::value) {
+ // Destroy the constructed elements in the vector.
+ destroy_range(Begin, End);
+ }
+ }
+
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef T value_type;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+
+ // forward iterator creation methods.
+ iterator begin() { return Begin; }
+ const_iterator begin() const { return Begin; }
+ iterator end() { return End; }
+ const_iterator end() const { return End; }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+
+ bool empty() const { return Begin == End; }
+ size_type size() const { return End-Begin; }
+
+ reference operator[](unsigned idx) {
+ assert(Begin + idx < End);
+ return Begin[idx];
+ }
+ const_reference operator[](unsigned idx) const {
+ assert(Begin + idx < End);
+ return Begin[idx];
+ }
+
+ reference front() {
+ return begin()[0];
+ }
+ const_reference front() const {
+ return begin()[0];
+ }
+
+ reference back() {
+ return end()[-1];
+ }
+ const_reference back() const {
+ return end()[-1];
+ }
+
+ void pop_back() {
+ --End;
+ End->~T();
+ }
+
+ T pop_back_val() {
+ T Result = back();
+ pop_back();
+ return Result;
+ }
+
+ void clear() {
+ if (llvm::is_class<T>::value) {
+ destroy_range(Begin, End);
+ }
+ End = Begin;
+ }
+
+ /// data - Return a pointer to the vector's buffer, even if empty().
+ pointer data() {
+ return pointer(Begin);
+ }
+
+ /// data - Return a pointer to the vector's buffer, even if empty().
+ const_pointer data() const {
+ return const_pointer(Begin);
+ }
+
+ void push_back(const_reference Elt, ASTContext &C) {
+ if (End < Capacity) {
+ Retry:
+ new (End) T(Elt);
+ ++End;
+ return;
+ }
+ grow(C);
+ goto Retry;
+ }
+
+ void reserve(ASTContext &C, unsigned N) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(C, N);
+ }
+
+ /// capacity - Return the total number of elements in the currently allocated
+ /// buffer.
+ size_t capacity() const { return Capacity - Begin; }
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ template<typename in_iter>
+ void append(ASTContext &C, in_iter in_start, in_iter in_end) {
+ size_type NumInputs = std::distance(in_start, in_end);
+
+ if (NumInputs == 0)
+ return;
+
+ // Grow allocated space if needed.
+ if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+ this->grow(C, this->size()+NumInputs);
+
+ // Copy the new elements over.
+ // TODO: NEED To compile time dispatch on whether in_iter is a random access
+ // iterator to use the fast uninitialized_copy.
+ std::uninitialized_copy(in_start, in_end, this->end());
+ this->setEnd(this->end() + NumInputs);
+ }
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ void append(ASTContext &C, size_type NumInputs, const T &Elt) {
+ // Grow allocated space if needed.
+ if (NumInputs > size_type(this->capacity_ptr()-this->end()))
+ this->grow(C, this->size()+NumInputs);
+
+ // Copy the new elements over.
+ std::uninitialized_fill_n(this->end(), NumInputs, Elt);
+ this->setEnd(this->end() + NumInputs);
+ }
+
+ /// uninitialized_copy - Copy the range [I, E) onto the uninitialized memory
+ /// starting with "Dest", constructing elements into it as needed.
+ template<typename It1, typename It2>
+ static void uninitialized_copy(It1 I, It1 E, It2 Dest) {
+ std::uninitialized_copy(I, E, Dest);
+ }
+
+ iterator insert(ASTContext &C, iterator I, const T &Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ push_back(Elt);
+ return this->end()-1;
+ }
+
+ if (this->EndX < this->CapacityX) {
+ Retry:
+ new (this->end()) T(this->back());
+ this->setEnd(this->end()+1);
+ // Push everything else over.
+ std::copy_backward(I, this->end()-1, this->end());
+ *I = Elt;
+ return I;
+ }
+ size_t EltNo = I-this->begin();
+ this->grow(C);
+ I = this->begin()+EltNo;
+ goto Retry;
+ }
+
+ iterator insert(ASTContext &C, iterator I, size_type NumToInsert,
+ const T &Elt) {
+ if (I == this->end()) { // Important special case for empty vector.
+ append(C, NumToInsert, Elt);
+ return this->end()-1;
+ }
+
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ // Ensure there is enough space.
+ reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
+
+ // Uninvalidate the iterator.
+ I = this->begin()+InsertElt;
+
+ // If there are more elements between the insertion point and the end of the
+ // range than there are being inserted, we can use a simple approach to
+ // insertion. Since we already reserved space, we know that this won't
+ // reallocate the vector.
+ if (size_t(this->end()-I) >= NumToInsert) {
+ T *OldEnd = this->end();
+ append(C, this->end()-NumToInsert, this->end());
+
+ // Copy the existing elements that get replaced.
+ std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+ std::fill_n(I, NumToInsert, Elt);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = this->end();
+ this->setEnd(this->end() + NumToInsert);
+ size_t NumOverwritten = OldEnd-I;
+ this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+ // Replace the overwritten part.
+ std::fill_n(I, NumOverwritten, Elt);
+
+ // Insert the non-overwritten middle part.
+ std::uninitialized_fill_n(OldEnd, NumToInsert-NumOverwritten, Elt);
+ return I;
+ }
+
+ template<typename ItTy>
+ iterator insert(ASTContext &C, iterator I, ItTy From, ItTy To) {
+ if (I == this->end()) { // Important special case for empty vector.
+ append(C, From, To);
+ return this->end()-1;
+ }
+
+ size_t NumToInsert = std::distance(From, To);
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ size_t InsertElt = I - this->begin();
+
+ // Ensure there is enough space.
+ reserve(C, static_cast<unsigned>(this->size() + NumToInsert));
+
+ // Uninvalidate the iterator.
+ I = this->begin()+InsertElt;
+
+ // If there are more elements between the insertion point and the end of the
+ // range than there are being inserted, we can use a simple approach to
+ // insertion. Since we already reserved space, we know that this won't
+ // reallocate the vector.
+ if (size_t(this->end()-I) >= NumToInsert) {
+ T *OldEnd = this->end();
+ append(C, this->end()-NumToInsert, this->end());
+
+ // Copy the existing elements that get replaced.
+ std::copy_backward(I, OldEnd-NumToInsert, OldEnd);
+
+ std::copy(From, To, I);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = this->end();
+ this->setEnd(this->end() + NumToInsert);
+ size_t NumOverwritten = OldEnd-I;
+ this->uninitialized_copy(I, OldEnd, this->end()-NumOverwritten);
+
+ // Replace the overwritten part.
+ for (; NumOverwritten > 0; --NumOverwritten) {
+ *I = *From;
+ ++I; ++From;
+ }
+
+ // Insert the non-overwritten middle part.
+ this->uninitialized_copy(From, To, OldEnd);
+ return I;
+ }
+
+ void resize(ASTContext &C, unsigned N, const T &NV) {
+ if (N < this->size()) {
+ this->destroy_range(this->begin()+N, this->end());
+ this->setEnd(this->begin()+N);
+ } else if (N > this->size()) {
+ if (this->capacity() < N)
+ this->grow(C, N);
+ construct_range(this->end(), this->begin()+N, NV);
+ this->setEnd(this->begin()+N);
+ }
+ }
+
+private:
+ /// grow - double the size of the allocated memory, guaranteeing space for at
+ /// least one more element or MinSize if specified.
+ void grow(ASTContext &C, size_type MinSize = 1);
+
+ void construct_range(T *S, T *E, const T &Elt) {
+ for (; S != E; ++S)
+ new (S) T(Elt);
+ }
+
+ void destroy_range(T *S, T *E) {
+ while (S != E) {
+ --E;
+ E->~T();
+ }
+ }
+
+protected:
+ iterator capacity_ptr() { return (iterator)this->Capacity; }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void ASTVector<T>::grow(ASTContext &C, size_t MinSize) {
+ size_t CurCapacity = Capacity-Begin;
+ size_t CurSize = size();
+ size_t NewCapacity = 2*CurCapacity;
+ if (NewCapacity < MinSize)
+ NewCapacity = MinSize;
+
+ // Allocate the memory from the ASTContext.
+ T *NewElts = new (C) T[NewCapacity];
+
+ // Copy the elements over.
+ if (llvm::is_class<T>::value) {
+ std::uninitialized_copy(Begin, End, NewElts);
+ // Destroy the original elements.
+ destroy_range(Begin, End);
+ }
+ else {
+ // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove).
+ memcpy(NewElts, Begin, CurSize * sizeof(T));
+ }
+
+ C.Deallocate(Begin);
+ Begin = NewElts;
+ End = NewElts+CurSize;
+ Capacity = Begin+NewCapacity;
+}
+
+} // end: clang namespace
+#endif
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index b2a87f617063..93dcad751221 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -263,6 +263,7 @@ public:
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isMemberFunctionPointerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isClassType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureType)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isStructureOrClassType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 2cdb98351394..834c9a0c563f 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -31,7 +31,9 @@ class StringLiteral;
class TemplateArgumentList;
class MemberSpecializationInfo;
class FunctionTemplateSpecializationInfo;
+class DependentFunctionTemplateSpecializationInfo;
class TypeLoc;
+class UnresolvedSetImpl;
/// \brief A container of type source information.
///
@@ -196,6 +198,10 @@ public:
return DC->isRecord();
}
+ /// \brief Given that this declaration is a C++ class member,
+ /// determine whether it's an instance member of its class.
+ bool isCXXInstanceMember() const;
+
/// \brief Determine what kind of linkage this entity has.
Linkage getLinkage() const;
@@ -211,6 +217,12 @@ public:
static bool classofKind(Kind K) { return K >= NamedFirst && K <= NamedLast; }
};
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const NamedDecl *ND) {
+ ND->getDeclName().printName(OS);
+ return OS;
+}
+
/// NamespaceDecl - Represent a C++ namespace.
class NamespaceDecl : public NamedDecl, public DeclContext {
SourceLocation LBracLoc, RBracLoc;
@@ -478,6 +490,7 @@ protected:
private:
// FIXME: This can be packed into the bitfields in Decl.
unsigned SClass : 3;
+ unsigned SClassAsWritten : 3;
bool ThreadSpecified : 1;
bool HasCXXDirectInit : 1;
@@ -485,14 +498,20 @@ private:
/// condition, e.g., if (int x = foo()) { ... }.
bool DeclaredInCondition : 1;
+ /// \brief Whether this variable is the exception variable in a C++ catch
+ /// or an Objective-C @catch statement.
+ bool ExceptionVar : 1;
+
friend class StmtIteratorBase;
protected:
VarDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass SC)
+ QualType T, TypeSourceInfo *TInfo, StorageClass SC,
+ StorageClass SCAsWritten)
: DeclaratorDecl(DK, DC, L, Id, T, TInfo), Init(),
ThreadSpecified(false), HasCXXDirectInit(false),
- DeclaredInCondition(false) {
+ DeclaredInCondition(false), ExceptionVar(false) {
SClass = SC;
+ SClassAsWritten = SCAsWritten;
}
typedef Redeclarable<VarDecl> redeclarable_base;
@@ -509,7 +528,8 @@ public:
static VarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo, StorageClass S);
+ QualType T, TypeSourceInfo *TInfo, StorageClass S,
+ StorageClass SCAsWritten);
virtual void Destroy(ASTContext& C);
virtual ~VarDecl();
@@ -517,7 +537,11 @@ public:
virtual SourceRange getSourceRange() const;
StorageClass getStorageClass() const { return (StorageClass)SClass; }
+ StorageClass getStorageClassAsWritten() const {
+ return (StorageClass) SClassAsWritten;
+ }
void setStorageClass(StorageClass SC) { SClass = SC; }
+ void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
void setThreadSpecified(bool T) { ThreadSpecified = T; }
bool isThreadSpecified() const {
@@ -536,6 +560,12 @@ public:
return getStorageClass() <= Register;
}
+ /// isStaticLocal - Returns true if a variable with function scope is a
+ /// static local variable.
+ bool isStaticLocal() const {
+ return getStorageClass() == Static && !isFileVarDecl();
+ }
+
/// hasExternStorage - Returns true if a variable has extern or
/// __private_extern__ storage.
bool hasExternalStorage() const {
@@ -815,6 +845,13 @@ public:
DeclaredInCondition = InCondition;
}
+ /// \brief Determine whether this variable is the exception variable in a
+ /// C++ catch statememt or an Objective-C @catch statement.
+ bool isExceptionVariable() const {
+ return ExceptionVar;
+ }
+ void setExceptionVariable(bool EV) { ExceptionVar = EV; }
+
/// \brief If this variable is an instantiated static data member of a
/// class template specialization, returns the templated static data member
/// from which it was instantiated.
@@ -844,7 +881,7 @@ class ImplicitParamDecl : public VarDecl {
protected:
ImplicitParamDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType Tw)
- : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None) {}
+ : VarDecl(DK, DC, L, Id, Tw, /*TInfo=*/0, VarDecl::None, VarDecl::None) {}
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
@@ -866,9 +903,9 @@ class ParmVarDecl : public VarDecl {
protected:
ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg)
- : VarDecl(DK, DC, L, Id, T, TInfo, S),
- objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
+ StorageClass S, StorageClass SCAsWritten, Expr *DefArg)
+ : VarDecl(DK, DC, L, Id, T, TInfo, S, SCAsWritten),
+ objcDeclQualifier(OBJC_TQ_None), HasInheritedDefaultArg(false) {
setDefaultArg(DefArg);
}
@@ -876,7 +913,8 @@ public:
static ParmVarDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg);
+ StorageClass S, StorageClass SCAsWritten,
+ Expr *DefArg);
ObjCDeclQualifier getObjCDeclQualifier() const {
return ObjCDeclQualifier(objcDeclQualifier);
@@ -1002,6 +1040,7 @@ private:
// FIXME: This can be packed into the bitfields in Decl.
// NOTE: VC++ treats enums as signed, avoid using the StorageClass enum
unsigned SClass : 2;
+ unsigned SClassAsWritten : 2;
bool IsInline : 1;
bool IsVirtualAsWritten : 1;
bool IsPure : 1;
@@ -1033,19 +1072,20 @@ private:
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
- llvm::PointerUnion3<FunctionTemplateDecl *,
+ llvm::PointerUnion4<FunctionTemplateDecl *,
MemberSpecializationInfo *,
- FunctionTemplateSpecializationInfo *>
+ FunctionTemplateSpecializationInfo *,
+ DependentFunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, bool isInline)
+ StorageClass S, StorageClass SCAsWritten, bool isInline)
: DeclaratorDecl(DK, DC, L, N, T, TInfo),
DeclContext(DK),
ParamInfo(0), Body(),
- SClass(S), IsInline(isInline),
+ SClass(S), SClassAsWritten(SCAsWritten), IsInline(isInline),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),
IsCopyAssignment(false),
@@ -1070,7 +1110,9 @@ public:
static FunctionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName N, QualType T,
TypeSourceInfo *TInfo,
- StorageClass S = None, bool isInline = false,
+ StorageClass S = None,
+ StorageClass SCAsWritten = None,
+ bool isInline = false,
bool hasWrittenPrototype = true);
virtual void getNameForDiagnostic(std::string &S,
@@ -1107,6 +1149,9 @@ public:
void setBody(Stmt *B);
void setLazyBody(uint64_t Offset) { Body = Offset; }
+ /// Whether this function is variadic.
+ bool isVariadic() const;
+
/// Whether this function is marked as virtual explicitly.
bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
@@ -1225,6 +1270,11 @@ public:
StorageClass getStorageClass() const { return StorageClass(SClass); }
void setStorageClass(StorageClass SC) { SClass = SC; }
+ StorageClass getStorageClassAsWritten() const {
+ return StorageClass(SClassAsWritten);
+ }
+ void setStorageClassAsWritten(StorageClass SC) { SClassAsWritten = SC; }
+
/// \brief Determine whether the "inline" keyword was specified for this
/// function.
bool isInlineSpecified() const { return IsInline; }
@@ -1361,6 +1411,18 @@ public:
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
+ /// \brief Specifies that this function declaration is actually a
+ /// dependent function template specialization.
+ void setDependentTemplateSpecialization(ASTContext &Context,
+ const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo &TemplateArgs);
+
+ DependentFunctionTemplateSpecializationInfo *
+ getDependentSpecializationInfo() const {
+ return TemplateOrSpecialization.
+ dyn_cast<DependentFunctionTemplateSpecializationInfo*>();
+ }
+
/// \brief Determine what kind of template instantiation this function
/// represents.
TemplateSpecializationKind getTemplateSpecializationKind() const;
@@ -1961,7 +2023,7 @@ public:
///
class BlockDecl : public Decl, public DeclContext {
// FIXME: This can be packed into the bitfields in Decl.
- bool isVariadic : 1;
+ bool IsVariadic : 1;
/// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal
/// parameters of this function. This is null if a prototype or if there are
/// no formals.
@@ -1973,7 +2035,7 @@ class BlockDecl : public Decl, public DeclContext {
protected:
BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
: Decl(Block, DC, CaretLoc), DeclContext(Block),
- isVariadic(false), ParamInfo(0), NumParams(0), Body(0) {}
+ IsVariadic(false), ParamInfo(0), NumParams(0), Body(0) {}
virtual ~BlockDecl();
virtual void Destroy(ASTContext& C);
@@ -1983,8 +2045,8 @@ public:
SourceLocation getCaretLocation() const { return getLocation(); }
- bool IsVariadic() const { return isVariadic; }
- void setIsVariadic(bool value) { isVariadic = value; }
+ bool isVariadic() const { return IsVariadic; }
+ void setIsVariadic(bool value) { IsVariadic = value; }
CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
Stmt *getBody() const { return (Stmt*) Body; }
diff --git a/include/clang/AST/DeclAccessPair.h b/include/clang/AST/DeclAccessPair.h
new file mode 100644
index 000000000000..7ecd8f8bcd78
--- /dev/null
+++ b/include/clang/AST/DeclAccessPair.h
@@ -0,0 +1,72 @@
+//===--- DeclAccessPair.h - A decl bundled with its path access -*- 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 DeclAccessPair class, which provides an
+// efficient representation of a pair of a NamedDecl* and an
+// AccessSpecifier. Generally the access specifier gives the
+// natural access of a declaration when named in a class, as
+// defined in C++ [class.access.base]p1.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DECLACCESSPAIR_H
+#define LLVM_CLANG_AST_DECLACCESSPAIR_H
+
+#include "clang/Basic/Specifiers.h"
+
+namespace clang {
+
+class NamedDecl;
+
+/// A POD class for pairing a NamedDecl* with an access specifier.
+/// Can be put into unions.
+class DeclAccessPair {
+ NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
+
+ enum { Mask = 0x3 };
+
+public:
+ static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
+ DeclAccessPair p;
+ p.set(D, AS);
+ return p;
+ }
+
+ NamedDecl *getDecl() const {
+ return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
+ }
+ AccessSpecifier getAccess() const {
+ return AccessSpecifier(Mask & (uintptr_t) Ptr);
+ }
+
+ void setDecl(NamedDecl *D) {
+ set(D, getAccess());
+ }
+ void setAccess(AccessSpecifier AS) {
+ set(getDecl(), AS);
+ }
+ void set(NamedDecl *D, AccessSpecifier AS) {
+ Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
+ reinterpret_cast<uintptr_t>(D));
+ }
+
+ operator NamedDecl*() const { return getDecl(); }
+ NamedDecl *operator->() const { return getDecl(); }
+};
+}
+
+// Take a moment to tell SmallVector that DeclAccessPair is POD.
+namespace llvm {
+template<typename> struct isPodLike;
+template<> struct isPodLike<clang::DeclAccessPair> {
+ static const bool value = true;
+};
+}
+
+#endif
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index d5913e236c2c..a9b948eee546 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -76,26 +76,68 @@ public:
#include "clang/AST/DeclNodes.def"
};
- /// IdentifierNamespace - According to C99 6.2.3, there are four
- /// namespaces, labels, tags, members and ordinary
- /// identifiers. These are meant as bitmasks, so that searches in
- /// C++ can look into the "tag" namespace during ordinary lookup. We
- /// use additional namespaces for Objective-C entities. We also put
- /// C++ friend declarations (of previously-undeclared entities) in
- /// shadow namespaces, and 'using' declarations (as opposed to their
- /// implicit shadow declarations) can be found in their own
- /// namespace.
+ /// IdentifierNamespace - The different namespaces in which
+ /// declarations may appear. According to C99 6.2.3, there are
+ /// four namespaces, labels, tags, members and ordinary
+ /// identifiers. C++ describes lookup completely differently:
+ /// certain lookups merely "ignore" certain kinds of declarations,
+ /// usually based on whether the declaration is of a type, etc.
+ ///
+ /// These are meant as bitmasks, so that searches in
+ /// C++ can look into the "tag" namespace during ordinary lookup.
+ ///
+ /// Decl currently provides 16 bits of IDNS bits.
enum IdentifierNamespace {
- IDNS_Label = 0x1,
- IDNS_Tag = 0x2,
- IDNS_Member = 0x4,
- IDNS_Ordinary = 0x8,
- IDNS_ObjCProtocol = 0x10,
- IDNS_ObjCImplementation = 0x20,
- IDNS_ObjCCategoryName = 0x40,
- IDNS_OrdinaryFriend = 0x80,
- IDNS_TagFriend = 0x100,
- IDNS_Using = 0x200
+ /// Labels, declared with 'x:' and referenced with 'goto x'.
+ IDNS_Label = 0x0001,
+
+ /// Tags, declared with 'struct foo;' and referenced with
+ /// 'struct foo'. All tags are also types. This is what
+ /// elaborated-type-specifiers look for in C.
+ IDNS_Tag = 0x0002,
+
+ /// Types, declared with 'struct foo', typedefs, etc.
+ /// This is what elaborated-type-specifiers look for in C++,
+ /// but note that it's ill-formed to find a non-tag.
+ IDNS_Type = 0x0004,
+
+ /// Members, declared with object declarations within tag
+ /// definitions. In C, these can only be found by "qualified"
+ /// lookup in member expressions. In C++, they're found by
+ /// normal lookup.
+ IDNS_Member = 0x0008,
+
+ /// Namespaces, declared with 'namespace foo {}'.
+ /// Lookup for nested-name-specifiers find these.
+ IDNS_Namespace = 0x0010,
+
+ /// Ordinary names. In C, everything that's not a label, tag,
+ /// or member ends up here.
+ IDNS_Ordinary = 0x0020,
+
+ /// Objective C @protocol.
+ IDNS_ObjCProtocol = 0x0040,
+
+ /// This declaration is a friend function. A friend function
+ /// declaration is always in this namespace but may also be in
+ /// IDNS_Ordinary if it was previously declared.
+ IDNS_OrdinaryFriend = 0x0080,
+
+ /// This declaration is a friend class. A friend class
+ /// declaration is always in this namespace but may also be in
+ /// IDNS_Tag|IDNS_Type if it was previously declared.
+ IDNS_TagFriend = 0x0100,
+
+ /// This declaration is a using declaration. A using declaration
+ /// *introduces* a number of other declarations into the current
+ /// scope, and those declarations use the IDNS of their targets,
+ /// but the actual using declarations go in this namespace.
+ IDNS_Using = 0x0200,
+
+ /// This declaration is a C++ operator declared in a non-class
+ /// context. All such operators are also in IDNS_Ordinary.
+ /// C++ lexical operator lookup looks for these.
+ IDNS_NonMemberOperator = 0x0400
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
@@ -313,6 +355,13 @@ public:
}
static unsigned getIdentifierNamespaceForKind(Kind DK);
+ bool hasTagIdentifierNamespace() const {
+ return isTagIdentifierNamespace(getIdentifierNamespace());
+ }
+ static bool isTagIdentifierNamespace(unsigned NS) {
+ // TagDecls have Tag and Type set and may also have TagFriend.
+ return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type);
+ }
/// getLexicalDeclContext - The declaration context where this Decl was
/// lexically declared (LexicalDC). May be different from
@@ -455,14 +504,14 @@ public:
assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
"namespace includes neither ordinary nor tag");
- assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary |
+ assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary | IDNS_Type |
IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
"namespace includes other than ordinary or tag");
IdentifierNamespace = 0;
if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
IdentifierNamespace |= IDNS_TagFriend;
- if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag;
+ if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag | IDNS_Type;
}
if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
@@ -489,6 +538,14 @@ public:
FOK_Declared : FOK_Undeclared);
}
+ /// Specifies that this declaration is a C++ overloaded non-member.
+ void setNonMemberOperator() {
+ assert(getKind() == Function || getKind() == FunctionTemplate);
+ assert((IdentifierNamespace & IDNS_Ordinary) &&
+ "visible non-member operators should be in ordinary namespace");
+ IdentifierNamespace |= IDNS_NonMemberOperator;
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *) { return true; }
static bool classofKind(Kind K) { return true; }
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 23769af46b36..aa649c811115 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -471,6 +471,11 @@ public:
friend_iterator friend_end() const;
void pushFriendDecl(FriendDecl *FD);
+ /// Determines whether this record has any friends.
+ bool hasFriends() const {
+ return data().FirstFriend != 0;
+ }
+
/// hasConstCopyConstructor - Determines whether this class has a
/// copy constructor that accepts a const-qualified argument.
bool hasConstCopyConstructor(ASTContext &Context) const;
@@ -931,15 +936,16 @@ class CXXMethodDecl : public FunctionDecl {
protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- bool isStatic, bool isInline)
+ bool isStatic, StorageClass SCAsWritten, bool isInline)
: FunctionDecl(DK, RD, L, N, T, TInfo, (isStatic ? Static : None),
- isInline) {}
+ SCAsWritten, isInline) {}
public:
static CXXMethodDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, DeclarationName N,
QualType T, TypeSourceInfo *TInfo,
bool isStatic = false,
+ StorageClass SCAsWritten = FunctionDecl::None,
bool isInline = false);
bool isStatic() const { return getStorageClass() == Static; }
@@ -960,6 +966,10 @@ public:
/// delete or delete[] operator with a particular signature.
bool isUsualDeallocationFunction() const;
+ /// \brief Determine whether this is a copy-assignment operator, regardless
+ /// of whether it was declared implicitly or explicitly.
+ bool isCopyAssignmentOperator() const;
+
const CXXMethodDecl *getCanonicalDecl() const {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
@@ -1052,6 +1062,10 @@ class CXXBaseOrMemberInitializer {
/// and AnonUnionMember holds field decl for au_i1.
FieldDecl *AnonUnionMember;
+ /// IsVirtual - If the initializer is a base initializer, this keeps track
+ /// of whether the base is virtual or not.
+ bool IsVirtual;
+
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@@ -1062,7 +1076,7 @@ public:
/// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
explicit
CXXBaseOrMemberInitializer(ASTContext &Context,
- TypeSourceInfo *TInfo,
+ TypeSourceInfo *TInfo, bool IsVirtual,
SourceLocation L,
Expr *Init,
SourceLocation R);
@@ -1095,7 +1109,14 @@ public:
/// Otherwise, returns NULL.
const Type *getBaseClass() const;
Type *getBaseClass();
-
+
+ /// Returns whether the base is virtual or not.
+ bool isBaseVirtual() const {
+ assert(isBaseInitializer() && "Must call this on base initializer!");
+
+ return IsVirtual;
+ }
+
/// \brief Returns the declarator information for a base class initializer.
TypeSourceInfo *getBaseClassInfo() const {
return BaseOrMember.dyn_cast<TypeSourceInfo *>();
@@ -1171,7 +1192,8 @@ class CXXConstructorDecl : public CXXMethodDecl {
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false, isInline),
+ : CXXMethodDecl(CXXConstructor, RD, L, N, T, TInfo, false,
+ FunctionDecl::None, isInline),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
setImplicit(isImplicitlyDeclared);
@@ -1199,7 +1221,7 @@ public:
/// defined. If false, then this constructor was defined by the
/// user. This operation can only be invoked if the constructor has
/// already been defined.
- bool isImplicitlyDefined(ASTContext &C) const {
+ bool isImplicitlyDefined() const {
assert(isThisDeclarationADefinition() &&
"Can only get the implicit-definition flag once the "
"constructor has been defined");
@@ -1314,7 +1336,8 @@ class CXXDestructorDecl : public CXXMethodDecl {
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false, isInline),
+ : CXXMethodDecl(CXXDestructor, RD, L, N, T, /*TInfo=*/0, false,
+ FunctionDecl::None, isInline),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1370,7 +1393,8 @@ class CXXConversionDecl : public CXXMethodDecl {
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
DeclarationName N, QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified)
- : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false, isInline),
+ : CXXMethodDecl(CXXConversion, RD, L, N, T, TInfo, false,
+ FunctionDecl::None, isInline),
IsExplicitSpecified(isExplicitSpecified) { }
public:
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 16cb491344bc..2a4b12ac2eaf 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -230,7 +230,7 @@ public:
// Tag declarations always go at the end of the list so that an
// iterator which points at the first tag will start a span of
// decls that only contains tags.
- if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
+ if (D->hasTagIdentifierNamespace())
Vec.push_back(reinterpret_cast<uintptr_t>(D));
// Resolved using declarations go at the front of the list so that
@@ -251,7 +251,7 @@ public:
// tag declarations. But we can be clever about tag declarations
// because there can only ever be one in a scope.
} else if (reinterpret_cast<NamedDecl *>(Vec.back())
- ->getIdentifierNamespace() == Decl::IDNS_Tag) {
+ ->hasTagIdentifierNamespace()) {
uintptr_t TagD = Vec.back();
Vec.back() = reinterpret_cast<uintptr_t>(D);
Vec.push_back(TagD);
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 99ef738980cc..a20625da56b7 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -48,10 +48,6 @@ private:
// Location of the 'friend' specifier.
SourceLocation FriendLoc;
- // FIXME: Hack to keep track of whether this was a friend function
- // template specialization.
- bool WasSpecialization;
-
friend class CXXRecordDecl::friend_iterator;
friend class CXXRecordDecl;
@@ -60,8 +56,7 @@ private:
: Decl(Decl::Friend, DC, L),
Friend(Friend),
NextFriend(0),
- FriendLoc(FriendL),
- WasSpecialization(false) {
+ FriendLoc(FriendL) {
}
public:
@@ -88,9 +83,6 @@ public:
return FriendLoc;
}
- bool wasSpecialization() const { return WasSpecialization; }
- void setSpecialization(bool WS) { WasSpecialization = WS; }
-
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FriendDecl *D) { return true; }
diff --git a/include/clang/AST/DeclNodes.def b/include/clang/AST/DeclNodes.def
index 082299c41f50..5b03ff8d9119 100644
--- a/include/clang/AST/DeclNodes.def
+++ b/include/clang/AST/DeclNodes.def
@@ -105,14 +105,14 @@ ABSTRACT_DECL(Named, Decl)
DECL(ImplicitParam, VarDecl)
DECL(ParmVar, VarDecl)
DECL(NonTypeTemplateParm, VarDecl)
- DECL(Template, NamedDecl)
+ ABSTRACT_DECL(Template, NamedDecl)
DECL(FunctionTemplate, TemplateDecl)
DECL(ClassTemplate, TemplateDecl)
DECL(TemplateTemplateParm, TemplateDecl)
DECL(Using, NamedDecl)
DECL(UsingShadow, NamedDecl)
DECL(ObjCMethod, NamedDecl)
- DECL(ObjCContainer, NamedDecl)
+ ABSTRACT_DECL(ObjCContainer, NamedDecl)
DECL(ObjCCategory, ObjCContainerDecl)
DECL(ObjCProtocol, ObjCContainerDecl)
DECL(ObjCInterface, ObjCContainerDecl)
@@ -143,7 +143,7 @@ LAST_DECL_CONTEXT(Block)
// Declaration ranges
DECL_RANGE(Named, Namespace, ObjCCompatibleAlias)
-DECL_RANGE(ObjCContainer, ObjCContainer, ObjCImplementation)
+DECL_RANGE(ObjCContainer, ObjCCategory, ObjCImplementation)
DECL_RANGE(Field, Field, ObjCAtDefsField)
DECL_RANGE(Type, Typedef, TemplateTypeParm)
DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization)
@@ -151,7 +151,7 @@ DECL_RANGE(Record, Record, ClassTemplatePartialSpecialization)
DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm)
DECL_RANGE(Declarator, Function, NonTypeTemplateParm)
DECL_RANGE(Function, Function, CXXConversion)
-DECL_RANGE(Template, Template, TemplateTemplateParm)
+DECL_RANGE(Template, FunctionTemplate, TemplateTemplateParm)
DECL_RANGE(ObjCImpl, ObjCCategoryImpl, ObjCImplementation)
LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm)
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 9b2b6096e81d..e34ec9ffcdf0 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -29,6 +29,7 @@ class ObjCProtocolDecl;
class ObjCCategoryDecl;
class ObjCPropertyDecl;
class ObjCPropertyImplDecl;
+class CXXBaseOrMemberInitializer;
class ObjCListBase {
void operator=(const ObjCListBase &); // DO NOT IMPLEMENT
@@ -136,6 +137,9 @@ private:
/// in, inout, etc.
unsigned objcDeclQualifier : 6;
+ // Number of args separated by ':' in a method declaration.
+ unsigned NumSelectorArgs;
+
// Result type of this method.
QualType MethodDeclType;
@@ -167,13 +171,15 @@ private:
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
- ImplementationControl impControl = None)
+ ImplementationControl impControl = None,
+ unsigned numSelectorArgs = 0)
: NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
DeclContext(ObjCMethod),
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
- MethodDeclType(T), ResultTInfo(ResultTInfo),
+ NumSelectorArgs(numSelectorArgs), MethodDeclType(T),
+ ResultTInfo(ResultTInfo),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
virtual ~ObjCMethodDecl() {}
@@ -197,7 +203,8 @@ public:
bool isInstance = true,
bool isVariadic = false,
bool isSynthesized = false,
- ImplementationControl impControl = None);
+ ImplementationControl impControl = None,
+ unsigned numSelectorArgs = 0);
virtual ObjCMethodDecl *getCanonicalDecl();
const ObjCMethodDecl *getCanonicalDecl() const {
@@ -209,6 +216,11 @@ public:
}
void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
+ unsigned getNumSelectorArgs() const { return NumSelectorArgs; }
+ void setNumSelectorArgs(unsigned numSelectorArgs) {
+ NumSelectorArgs = numSelectorArgs;
+ }
+
// Location information, modeled after the Stmt API.
SourceLocation getLocStart() const { return getLocation(); }
SourceLocation getLocEnd() const { return EndLoc; }
@@ -235,9 +247,16 @@ public:
typedef ObjCList<ParmVarDecl>::iterator param_iterator;
param_iterator param_begin() const { return ParamInfo.begin(); }
param_iterator param_end() const { return ParamInfo.end(); }
+ // This method returns and of the parameters which are part of the selector
+ // name mangling requirements.
+ param_iterator sel_param_end() const {
+ return ParamInfo.begin() + NumSelectorArgs;
+ }
- void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num) {
+ void setMethodParams(ASTContext &C, ParmVarDecl *const *List, unsigned Num,
+ unsigned numSelectorArgs) {
ParamInfo.set(List, Num, C);
+ NumSelectorArgs = numSelectorArgs;
}
// Iterator access to parameter types.
@@ -1114,6 +1133,9 @@ public:
static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const ObjCCategoryImplDecl *CID);
+
/// ObjCImplementationDecl - Represents a class definition - this is where
/// method definitions are specified. For example:
///
@@ -1131,18 +1153,54 @@ public:
class ObjCImplementationDecl : public ObjCImplDecl {
/// Implementation Class's super class.
ObjCInterfaceDecl *SuperClass;
-
+ /// Support for ivar initialization.
+ /// IvarInitializers - The arguments used to initialize the ivars
+ CXXBaseOrMemberInitializer **IvarInitializers;
+ unsigned NumIvarInitializers;
+
ObjCImplementationDecl(DeclContext *DC, SourceLocation L,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl)
: ObjCImplDecl(ObjCImplementation, DC, L, classInterface),
- SuperClass(superDecl){}
+ SuperClass(superDecl), IvarInitializers(0), NumIvarInitializers(0) {}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
ObjCInterfaceDecl *classInterface,
ObjCInterfaceDecl *superDecl);
-
+
+ /// init_iterator - Iterates through the ivar initializer list.
+ typedef CXXBaseOrMemberInitializer **init_iterator;
+
+ /// init_const_iterator - Iterates through the ivar initializer list.
+ typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+
+ /// init_begin() - Retrieve an iterator to the first initializer.
+ init_iterator init_begin() { return IvarInitializers; }
+ /// begin() - Retrieve an iterator to the first initializer.
+ init_const_iterator init_begin() const { return IvarInitializers; }
+
+ /// init_end() - Retrieve an iterator past the last initializer.
+ init_iterator init_end() {
+ return IvarInitializers + NumIvarInitializers;
+ }
+ /// end() - Retrieve an iterator past the last initializer.
+ init_const_iterator init_end() const {
+ return IvarInitializers + NumIvarInitializers;
+ }
+ /// getNumArgs - Number of ivars which must be initialized.
+ unsigned getNumIvarInitializers() const {
+ return NumIvarInitializers;
+ }
+
+ void setNumIvarInitializers(unsigned numNumIvarInitializers) {
+ NumIvarInitializers = numNumIvarInitializers;
+ }
+
+ void setIvarInitializers(ASTContext &C,
+ CXXBaseOrMemberInitializer ** initializers,
+ unsigned numInitializers);
+
/// getIdentifier - Get the identifier that names the class
/// interface associated with this implementation.
IdentifierInfo *getIdentifier() const {
@@ -1199,6 +1257,9 @@ public:
static bool classofKind(Kind K) { return K == ObjCImplementation; }
};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const ObjCImplementationDecl *ID);
+
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
/// declared as @compatibility_alias alias class.
class ObjCCompatibleAliasDecl : public NamedDecl {
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 8d1a4caccb23..1ec38bacb51f 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -376,6 +376,81 @@ public:
PointOfInstantiation = POI;
}
};
+
+/// \brief Provides information about a dependent function-template
+/// specialization declaration. Since explicit function template
+/// specialization and instantiation declarations can only appear in
+/// namespace scope, and you can only specialize a member of a
+/// fully-specialized class, the only way to get one of these is in
+/// a friend declaration like the following:
+///
+/// template <class T> void foo(T);
+/// template <class T> class A {
+/// friend void foo<>(T);
+/// };
+class DependentFunctionTemplateSpecializationInfo {
+ union {
+ // Force sizeof to be a multiple of sizeof(void*) so that the
+ // trailing data is aligned.
+ void *Aligner;
+
+ struct {
+ /// The number of potential template candidates.
+ unsigned NumTemplates;
+
+ /// The number of template arguments.
+ unsigned NumArgs;
+ } d;
+ };
+
+ /// The locations of the left and right angle brackets.
+ SourceRange AngleLocs;
+
+ FunctionTemplateDecl * const *getTemplates() const {
+ return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
+ }
+
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc*>(
+ &getTemplates()[getNumTemplates()]);
+ }
+
+public:
+ DependentFunctionTemplateSpecializationInfo(
+ const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo &TemplateArgs);
+
+ /// \brief Returns the number of function templates that this might
+ /// be a specialization of.
+ unsigned getNumTemplates() const {
+ return d.NumTemplates;
+ }
+
+ /// \brief Returns the i'th template candidate.
+ FunctionTemplateDecl *getTemplate(unsigned I) const {
+ assert(I < getNumTemplates() && "template index out of range");
+ return getTemplates()[I];
+ }
+
+ /// \brief Returns the number of explicit template arguments that were given.
+ unsigned getNumTemplateArgs() const {
+ return d.NumArgs;
+ }
+
+ /// \brief Returns the nth template argument.
+ const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
+ assert(I < getNumTemplateArgs() && "template arg index out of range");
+ return getTemplateArgs()[I];
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return AngleLocs.getBegin();
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return AngleLocs.getEnd();
+ }
+};
/// Declaration of a template function.
class FunctionTemplateDecl : public TemplateDecl {
@@ -652,7 +727,8 @@ class NonTypeTemplateParmDecl
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo)
- : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None),
+ : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
+ VarDecl::None),
TemplateParmPosition(D, P), DefaultArgument(0)
{ }
@@ -935,6 +1011,11 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentLoc *ArgsAsWritten;
unsigned NumArgsAsWritten;
+ /// \brief Sequence number indicating when this class template partial
+ /// specialization was added to the set of partial specializations for
+ /// its owning class template.
+ unsigned SequenceNumber;
+
/// \brief The class template partial specialization from which this
/// class template partial specialization was instantiated.
///
@@ -950,13 +1031,15 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentListBuilder &Builder,
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
- ClassTemplatePartialSpecializationDecl *PrevDecl)
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
DC, L, SpecializedTemplate, Builder,
PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
- NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
+ NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+ InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -966,7 +1049,8 @@ public:
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber);
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
@@ -983,6 +1067,10 @@ public:
return NumArgsAsWritten;
}
+ /// \brief Get the sequence number for this class template partial
+ /// specialization.
+ unsigned getSequenceNumber() const { return SequenceNumber; }
+
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
@@ -1046,6 +1134,15 @@ public:
"Only member templates can be member template specializations");
return First->InstantiatedFromMember.setInt(true);
}
+
+ /// Retrieves the injected specialization type for this partial
+ /// specialization. This is not the same as the type-decl-type for
+ /// this partial specialization, which is an InjectedClassNameType.
+ QualType getInjectedSpecializationType() const {
+ assert(getTypeForDecl() && "partial specialization has no type set!");
+ return cast<InjectedClassNameType>(getTypeForDecl())
+ ->getInjectedSpecializationType();
+ }
// FIXME: Add Profile support!
@@ -1141,6 +1238,10 @@ public:
return CommonPtr->PartialSpecializations;
}
+ /// \brief Retrieve the partial specializations as an ordered list.
+ void getPartialSpecializations(
+ llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+
/// \brief Find a class template partial specialization with the given
/// type T.
///
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 6225069c602f..94017865d4c6 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -198,9 +198,12 @@ public:
/// callee in a call expression with dependent arguments.
bool isDependentName() const;
- /// getName - Retrieve the human-readable string for this name.
+ /// getNameAsString - Retrieve the human-readable string for this name.
std::string getAsString() const;
+ /// printName - Print the human-readable name to a stream.
+ void printName(llvm::raw_ostream &OS) const;
+
/// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
/// this declaration name, or NULL if this declaration name isn't a
/// simple identifier.
@@ -331,13 +334,15 @@ public:
/// getCXXConstructorName - Returns the name of a C++ constructor
/// for the given Type.
DeclarationName getCXXConstructorName(CanQualType Ty) {
- return getCXXSpecialName(DeclarationName::CXXConstructorName, Ty);
+ return getCXXSpecialName(DeclarationName::CXXConstructorName,
+ Ty.getUnqualifiedType());
}
/// getCXXDestructorName - Returns the name of a C++ destructor
/// for the given Type.
DeclarationName getCXXDestructorName(CanQualType Ty) {
- return getCXXSpecialName(DeclarationName::CXXDestructorName, Ty);
+ return getCXXSpecialName(DeclarationName::CXXDestructorName,
+ Ty.getUnqualifiedType());
}
/// getCXXConversionFunctionName - Returns the name of a C++
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 1954a282e802..2bbe5020cb3a 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -22,6 +22,7 @@
#include "clang/Basic/SourceLocation.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclContextInternals.h"
+#include "clang/AST/Type.h"
namespace clang {
@@ -42,6 +43,7 @@ public:
AccessSpecifier AS,
NamedDecl *TargetDecl,
CXXRecordDecl *NamingClass,
+ QualType BaseObjectType,
const PartialDiagnostic &PDiag) {
DependentDiagnostic *DD = Create(Context, Parent, PDiag);
DD->AccessData.Loc = Loc.getRawEncoding();
@@ -49,6 +51,7 @@ public:
DD->AccessData.Access = AS;
DD->AccessData.TargetDecl = TargetDecl;
DD->AccessData.NamingClass = NamingClass;
+ DD->AccessData.BaseObjectType = BaseObjectType.getAsOpaquePtr();
return DD;
}
@@ -81,6 +84,11 @@ public:
return AccessData.NamingClass;
}
+ QualType getAccessBaseObjectType() const {
+ assert(getKind() == Access);
+ return QualType::getFromOpaquePtr(AccessData.BaseObjectType);
+ }
+
const PartialDiagnostic &getDiagnostic() const {
return Diag;
}
@@ -107,6 +115,7 @@ private:
unsigned IsMember : 1;
NamedDecl *TargetDecl;
CXXRecordDecl *NamingClass;
+ void *BaseObjectType;
} AccessData;
};
};
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index a687ee5f01c8..2946e464a7cf 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -17,6 +17,9 @@
#include "clang/AST/APValue.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/ASTVector.h"
+#include "clang/AST/UsuallyTinyPtrVector.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallVector.h"
@@ -32,11 +35,15 @@ namespace clang {
class NamedDecl;
class ValueDecl;
class BlockDecl;
+ class CXXBaseSpecifier;
class CXXOperatorCallExpr;
class CXXMemberCallExpr;
class TemplateArgumentLoc;
class TemplateArgumentListInfo;
+/// \brief A simple array of base specifiers.
+typedef UsuallyTinyPtrVector<const CXXBaseSpecifier> CXXBaseSpecifierArray;
+
/// Expr - This represents one expression. Note that Expr's are subclasses of
/// Stmt. This allows an expression to be transparently used any place a Stmt
/// is required.
@@ -197,6 +204,12 @@ public:
/// \brief Returns whether this expression refers to a vector element.
bool refersToVectorElement() const;
+ /// isKnownToHaveBooleanValue - Return true if this is an integer expression
+ /// that is known to return 0 or 1. This happens for _Bool/bool expressions
+ /// but also int expressions which are produced by things like comparisons in
+ /// C.
+ bool isKnownToHaveBooleanValue() const;
+
/// isIntegerConstantExpr - Return true if this expression is a valid integer
/// constant expression, and, if so, return its value in Result. If not a
/// valid i-c-e, return false and fill in Loc (if specified) with the location
@@ -210,7 +223,7 @@ public:
}
/// isConstantInitializer - Returns true if this expression is a constant
/// initializer, which can be emitted at compile-time.
- bool isConstantInitializer(ASTContext &Ctx) const;
+ bool isConstantInitializer(ASTContext &Ctx) const;
/// EvalResult is a struct with detailed info about an evaluated expression.
struct EvalResult {
@@ -302,7 +315,7 @@ public:
/// its subexpression. If that subexpression is also a ParenExpr,
/// then this method recursively returns its subexpression, and so forth.
/// Otherwise, the method returns the current Expr.
- Expr* IgnoreParens();
+ Expr *IgnoreParens();
/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
/// or CastExprs, returning their operand.
@@ -331,7 +344,7 @@ public:
/// temporary object.
const Expr *getTemporaryObject() const;
- const Expr* IgnoreParens() const {
+ const Expr *IgnoreParens() const {
return const_cast<Expr*>(this)->IgnoreParens();
}
const Expr *IgnoreParenCasts() const {
@@ -901,7 +914,7 @@ public:
///
/// __builtin_offsetof(type, a.b[10]) is represented as a unary operator whose
/// subexpression is a compound literal with the various MemberExpr and
-/// ArraySubscriptExpr's applied to it.
+/// ArraySubscriptExpr's applied to it. (This is only used in C)
///
class UnaryOperator : public Expr {
public:
@@ -990,6 +1003,205 @@ public:
virtual child_iterator child_end();
};
+/// OffsetOfExpr - [C99 7.17] - This represents an expression of the form
+/// offsetof(record-type, member-designator). For example, given:
+/// @code
+/// struct S {
+/// float f;
+/// double d;
+/// };
+/// struct T {
+/// int i;
+/// struct S s[10];
+/// };
+/// @endcode
+/// we can represent and evaluate the expression @c offsetof(struct T, s[2].d).
+
+class OffsetOfExpr : public Expr {
+public:
+ // __builtin_offsetof(type, identifier(.identifier|[expr])*)
+ class OffsetOfNode {
+ public:
+ /// \brief The kind of offsetof node we have.
+ enum Kind {
+ /// \brief An index into an array.
+ Array = 0x00,
+ /// \brief A field.
+ Field = 0x01,
+ /// \brief A field in a dependent type, known only by its name.
+ Identifier = 0x02,
+ /// \brief An implicit indirection through a C++ base class, when the
+ /// field found is in a base class.
+ Base = 0x03
+ };
+
+ private:
+ enum { MaskBits = 2, Mask = 0x03 };
+
+ /// \brief The source range that covers this part of the designator.
+ SourceRange Range;
+
+ /// \brief The data describing the designator, which comes in three
+ /// different forms, depending on the lower two bits.
+ /// - An unsigned index into the array of Expr*'s stored after this node
+ /// in memory, for [constant-expression] designators.
+ /// - A FieldDecl*, for references to a known field.
+ /// - An IdentifierInfo*, for references to a field with a given name
+ /// when the class type is dependent.
+ /// - A CXXBaseSpecifier*, for references that look at a field in a
+ /// base class.
+ uintptr_t Data;
+
+ public:
+ /// \brief Create an offsetof node that refers to an array element.
+ OffsetOfNode(SourceLocation LBracketLoc, unsigned Index,
+ SourceLocation RBracketLoc)
+ : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) { }
+
+ /// \brief Create an offsetof node that refers to a field.
+ OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field,
+ SourceLocation NameLoc)
+ : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
+ Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) { }
+
+ /// \brief Create an offsetof node that refers to an identifier.
+ OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name,
+ SourceLocation NameLoc)
+ : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc),
+ Data(reinterpret_cast<uintptr_t>(Name) | Identifier) { }
+
+ /// \brief Create an offsetof node that refers into a C++ base class.
+ explicit OffsetOfNode(const CXXBaseSpecifier *Base)
+ : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {}
+
+ /// \brief Determine what kind of offsetof node this is.
+ Kind getKind() const {
+ return static_cast<Kind>(Data & Mask);
+ }
+
+ /// \brief For an array element node, returns the index into the array
+ /// of expressions.
+ unsigned getArrayExprIndex() const {
+ assert(getKind() == Array);
+ return Data >> 2;
+ }
+
+ /// \brief For a field offsetof node, returns the field.
+ FieldDecl *getField() const {
+ assert(getKind() == Field);
+ return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask);
+ }
+
+ /// \brief For a field or identifier offsetof node, returns the name of
+ /// the field.
+ IdentifierInfo *getFieldName() const;
+
+ /// \brief For a base class node, returns the base specifier.
+ CXXBaseSpecifier *getBase() const {
+ assert(getKind() == Base);
+ return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask);
+ }
+
+ /// \brief Retrieve the source range that covers this offsetof node.
+ ///
+ /// For an array element node, the source range contains the locations of
+ /// the square brackets. For a field or identifier node, the source range
+ /// contains the location of the period (if there is one) and the
+ /// identifier.
+ SourceRange getRange() const { return Range; }
+ };
+
+private:
+
+ SourceLocation OperatorLoc, RParenLoc;
+ // Base type;
+ TypeSourceInfo *TSInfo;
+ // Number of sub-components (i.e. instances of OffsetOfNode).
+ unsigned NumComps;
+ // Number of sub-expressions (i.e. array subscript expressions).
+ unsigned NumExprs;
+
+ OffsetOfExpr(ASTContext &C, QualType type,
+ SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+ OffsetOfNode* compsPtr, unsigned numComps,
+ Expr** exprsPtr, unsigned numExprs,
+ SourceLocation RParenLoc);
+
+ explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
+ : Expr(OffsetOfExprClass, EmptyShell()),
+ TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}
+
+public:
+
+ static OffsetOfExpr *Create(ASTContext &C, QualType type,
+ SourceLocation OperatorLoc, TypeSourceInfo *tsi,
+ OffsetOfNode* compsPtr, unsigned numComps,
+ Expr** exprsPtr, unsigned numExprs,
+ SourceLocation RParenLoc);
+
+ static OffsetOfExpr *CreateEmpty(ASTContext &C,
+ unsigned NumComps, unsigned NumExprs);
+
+ /// getOperatorLoc - Return the location of the operator.
+ SourceLocation getOperatorLoc() const { return OperatorLoc; }
+ void setOperatorLoc(SourceLocation L) { OperatorLoc = L; }
+
+ /// \brief Return the location of the right parentheses.
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation R) { RParenLoc = R; }
+
+ TypeSourceInfo *getTypeSourceInfo() const {
+ return TSInfo;
+ }
+ void setTypeSourceInfo(TypeSourceInfo *tsi) {
+ TSInfo = tsi;
+ }
+
+ const OffsetOfNode &getComponent(unsigned Idx) {
+ assert(Idx < NumComps && "Subscript out of range");
+ return reinterpret_cast<OffsetOfNode *> (this + 1)[Idx];
+ }
+
+ void setComponent(unsigned Idx, OffsetOfNode ON) {
+ assert(Idx < NumComps && "Subscript out of range");
+ reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON;
+ }
+
+ unsigned getNumComponents() const {
+ return NumComps;
+ }
+
+ Expr* getIndexExpr(unsigned Idx) {
+ assert(Idx < NumExprs && "Subscript out of range");
+ return reinterpret_cast<Expr **>(
+ reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx];
+ }
+
+ void setIndexExpr(unsigned Idx, Expr* E) {
+ assert(Idx < NumComps && "Subscript out of range");
+ reinterpret_cast<Expr **>(
+ reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E;
+ }
+
+ unsigned getNumExpressions() const {
+ return NumExprs;
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(OperatorLoc, RParenLoc);
+ }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == OffsetOfExprClass;
+ }
+
+ static bool classof(const OffsetOfExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+};
+
/// SizeOfAlignOfExpr - [C99 6.5.3.4] - This is for sizeof/alignof, both of
/// types and expressions.
class SizeOfAlignOfExpr : public Expr {
@@ -1274,7 +1486,7 @@ public:
class MemberExpr : public Expr {
/// Extra data stored in some member expressions.
struct MemberNameQualifier : public NameQualifier {
- NamedDecl *FoundDecl;
+ DeclAccessPair FoundDecl;
};
/// Base - the expression for the base pointer or structure references. In
@@ -1349,7 +1561,7 @@ public:
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
- ValueDecl *memberdecl, NamedDecl *founddecl,
+ ValueDecl *memberdecl, DeclAccessPair founddecl,
SourceLocation l,
const TemplateArgumentListInfo *targs,
QualType ty);
@@ -1365,9 +1577,10 @@ public:
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
/// \brief Retrieves the declaration found by lookup.
- NamedDecl *getFoundDecl() const {
+ DeclAccessPair getFoundDecl() const {
if (!HasQualifierOrFoundDecl)
- return getMemberDecl();
+ return DeclAccessPair::make(getMemberDecl(),
+ getMemberDecl()->getAccess());
return getMemberQualifier()->FoundDecl;
}
@@ -1636,8 +1849,53 @@ public:
private:
CastKind Kind;
Stmt *Op;
+
+ /// BasePath - For derived-to-base and base-to-derived casts, the base array
+ /// contains the inheritance path.
+ CXXBaseSpecifierArray BasePath;
+
+ void CheckBasePath() const {
+#ifndef NDEBUG
+ switch (getCastKind()) {
+ case CK_DerivedToBase:
+ case CK_UncheckedDerivedToBase:
+ case CK_DerivedToBaseMemberPointer:
+ case CK_BaseToDerived:
+ case CK_BaseToDerivedMemberPointer:
+ assert(!BasePath.empty() && "Cast kind should have a base path!");
+ break;
+
+ // These should not have an inheritance path.
+ case CK_Unknown:
+ case CK_BitCast:
+ case CK_NoOp:
+ case CK_Dynamic:
+ case CK_ToUnion:
+ case CK_ArrayToPointerDecay:
+ case CK_FunctionToPointerDecay:
+ case CK_NullToMemberPointer:
+ case CK_UserDefinedConversion:
+ case CK_ConstructorConversion:
+ case CK_IntegralToPointer:
+ case CK_PointerToIntegral:
+ case CK_ToVoid:
+ case CK_VectorSplat:
+ case CK_IntegralCast:
+ case CK_IntegralToFloating:
+ case CK_FloatingToIntegral:
+ case CK_FloatingCast:
+ case CK_MemberPointerToBoolean:
+ case CK_AnyPointerToObjCPointerCast:
+ case CK_AnyPointerToBlockPointerCast:
+ assert(BasePath.empty() && "Cast kind should not have a base path!");
+ break;
+ }
+#endif
+ }
+
protected:
- CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op) :
+ CastExpr(StmtClass SC, QualType ty, const CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath) :
Expr(SC, ty,
// Cast expressions are type-dependent if the type is
// dependent (C++ [temp.dep.expr]p3).
@@ -1645,12 +1903,16 @@ protected:
// Cast expressions are value-dependent if the type is
// dependent or if the subexpression is value-dependent.
ty->isDependentType() || (op && op->isValueDependent())),
- Kind(kind), Op(op) {}
+ Kind(kind), Op(op), BasePath(BasePath) {
+ CheckBasePath();
+ }
/// \brief Construct an empty cast.
CastExpr(StmtClass SC, EmptyShell Empty)
: Expr(SC, Empty) { }
+ virtual void DoDestroy(ASTContext &C);
+
public:
CastKind getCastKind() const { return Kind; }
void setCastKind(CastKind K) { Kind = K; }
@@ -1667,10 +1929,12 @@ public:
const Expr *getSubExprAsWritten() const {
return const_cast<CastExpr *>(this)->getSubExprAsWritten();
}
-
+
+ const CXXBaseSpecifierArray& getBasePath() const { return BasePath; }
+
static bool classof(const Stmt *T) {
StmtClass SC = T->getStmtClass();
- if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass)
+ if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;
if (SC >= ImplicitCastExprClass && SC <= CStyleCastExprClass)
@@ -1706,14 +1970,15 @@ class ImplicitCastExpr : public CastExpr {
bool LvalueCast;
public:
- ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, bool Lvalue) :
- CastExpr(ImplicitCastExprClass, ty, kind, op), LvalueCast(Lvalue) { }
+ ImplicitCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, bool Lvalue)
+ : CastExpr(ImplicitCastExprClass, ty, kind, op, BasePath),
+ LvalueCast(Lvalue) { }
/// \brief Construct an empty implicit cast.
explicit ImplicitCastExpr(EmptyShell Shell)
: CastExpr(ImplicitCastExprClass, Shell) { }
-
virtual SourceRange getSourceRange() const {
return getSubExpr()->getSourceRange();
}
@@ -1753,8 +2018,9 @@ class ExplicitCastExpr : public CastExpr {
protected:
ExplicitCastExpr(StmtClass SC, QualType exprTy, CastKind kind,
- Expr *op, TypeSourceInfo *writtenTy)
- : CastExpr(SC, exprTy, kind, op), TInfo(writtenTy) {}
+ Expr *op, CXXBaseSpecifierArray BasePath,
+ TypeSourceInfo *writtenTy)
+ : CastExpr(SC, exprTy, kind, op, BasePath), TInfo(writtenTy) {}
/// \brief Construct an empty explicit cast.
ExplicitCastExpr(StmtClass SC, EmptyShell Shell)
@@ -1774,7 +2040,7 @@ public:
StmtClass SC = T->getStmtClass();
if (SC >= CStyleCastExprClass && SC <= CStyleCastExprClass)
return true;
- if (SC >= CXXNamedCastExprClass && SC <= CXXFunctionalCastExprClass)
+ if (SC >= CXXStaticCastExprClass && SC <= CXXFunctionalCastExprClass)
return true;
return false;
@@ -1790,10 +2056,10 @@ class CStyleCastExpr : public ExplicitCastExpr {
SourceLocation RPLoc; // the location of the right paren
public:
CStyleCastExpr(QualType exprTy, CastKind kind, Expr *op,
- TypeSourceInfo *writtenTy,
- SourceLocation l, SourceLocation r) :
- ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, writtenTy),
- LPLoc(l), RPLoc(r) {}
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l, SourceLocation r)
+ : ExplicitCastExpr(CStyleCastExprClass, exprTy, kind, op, BasePath,
+ writtenTy), LPLoc(l), RPLoc(r) {}
/// \brief Construct an empty C-style explicit cast.
explicit CStyleCastExpr(EmptyShell Shell)
@@ -2362,7 +2628,7 @@ public:
virtual child_iterator child_end();
};
-/// VAArgExpr, used for the builtin function __builtin_va_start.
+/// VAArgExpr, used for the builtin function __builtin_va_arg.
class VAArgExpr : public Expr {
Stmt *Val;
SourceLocation BuiltinLoc, RParenLoc;
@@ -2373,7 +2639,7 @@ public:
BuiltinLoc(BLoc),
RParenLoc(RPLoc) { }
- /// \brief Create an empty __builtin_va_start expression.
+ /// \brief Create an empty __builtin_va_arg expression.
explicit VAArgExpr(EmptyShell Empty) : Expr(VAArgExprClass, Empty) { }
const Expr *getSubExpr() const { return cast<Expr>(Val); }
@@ -2438,7 +2704,8 @@ public:
/// serves as its syntactic form.
class InitListExpr : public Expr {
// FIXME: Eliminate this vector in favor of ASTContext allocation
- std::vector<Stmt *> InitExprs;
+ typedef ASTVector<Stmt *> InitExprsTy;
+ InitExprsTy InitExprs;
SourceLocation LBraceLoc, RBraceLoc;
/// Contains the initializer list that describes the syntactic form
@@ -2454,11 +2721,13 @@ class InitListExpr : public Expr {
bool HadArrayRangeDesignator;
public:
- InitListExpr(SourceLocation lbraceloc, Expr **initexprs, unsigned numinits,
+ InitListExpr(ASTContext &C, SourceLocation lbraceloc,
+ Expr **initexprs, unsigned numinits,
SourceLocation rbraceloc);
/// \brief Build an empty initializer list.
- explicit InitListExpr(EmptyShell Empty) : Expr(InitListExprClass, Empty) { }
+ explicit InitListExpr(ASTContext &C, EmptyShell Empty)
+ : Expr(InitListExprClass, Empty), InitExprs(C) { }
unsigned getNumInits() const { return InitExprs.size(); }
@@ -2478,7 +2747,7 @@ public:
}
/// \brief Reserve space for some number of initializers.
- void reserveInits(unsigned NumInits);
+ void reserveInits(ASTContext &C, unsigned NumInits);
/// @brief Specify the number of initializers
///
@@ -2495,7 +2764,7 @@ public:
/// When @p Init is out of range for this initializer list, the
/// initializer list will be extended with NULL expressions to
/// accomodate the new entry.
- Expr *updateInit(unsigned Init, Expr *expr);
+ Expr *updateInit(ASTContext &C, unsigned Init, Expr *expr);
/// \brief If this initializes a union, specifies which field in the
/// union to initialize.
@@ -2541,8 +2810,8 @@ public:
virtual child_iterator child_begin();
virtual child_iterator child_end();
- typedef std::vector<Stmt *>::iterator iterator;
- typedef std::vector<Stmt *>::reverse_iterator reverse_iterator;
+ typedef InitExprsTy::iterator iterator;
+ typedef InitExprsTy::reverse_iterator reverse_iterator;
iterator begin() { return InitExprs.begin(); }
iterator end() { return InitExprs.end(); }
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6e2e832e3542..f9ca78ad292d 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -118,8 +118,9 @@ private:
protected:
CXXNamedCastExpr(StmtClass SC, QualType ty, CastKind kind, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l)
- : ExplicitCastExpr(SC, ty, kind, op, writtenTy), Loc(l) {}
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : ExplicitCastExpr(SC, ty, kind, op, BasePath, writtenTy), Loc(l) {}
explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell)
: ExplicitCastExpr(SC, Shell) { }
@@ -137,7 +138,6 @@ public:
}
static bool classof(const Stmt *T) {
switch (T->getStmtClass()) {
- case CXXNamedCastExprClass:
case CXXStaticCastExprClass:
case CXXDynamicCastExprClass:
case CXXReinterpretCastExprClass:
@@ -156,9 +156,10 @@ public:
/// @c static_cast<int>(1.0).
class CXXStaticCastExpr : public CXXNamedCastExpr {
public:
- CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l)
- : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, writtenTy, l) {}
+ CXXStaticCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : CXXNamedCastExpr(CXXStaticCastExprClass, ty, kind, op, BasePath, writtenTy, l) {}
explicit CXXStaticCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXStaticCastExprClass, Empty) { }
@@ -177,9 +178,11 @@ public:
/// @c dynamic_cast<Derived*>(BasePtr).
class CXXDynamicCastExpr : public CXXNamedCastExpr {
public:
- CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op,
- TypeSourceInfo *writtenTy, SourceLocation l)
- : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, writtenTy, l) {}
+ CXXDynamicCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath, TypeSourceInfo *writtenTy,
+ SourceLocation l)
+ : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, kind, op, BasePath,
+ writtenTy, l) {}
explicit CXXDynamicCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXDynamicCastExprClass, Empty) { }
@@ -199,8 +202,9 @@ public:
class CXXReinterpretCastExpr : public CXXNamedCastExpr {
public:
CXXReinterpretCastExpr(QualType ty, CastKind kind, Expr *op,
+ CXXBaseSpecifierArray BasePath,
TypeSourceInfo *writtenTy, SourceLocation l)
- : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op,
+ : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, kind, op, BasePath,
writtenTy, l) {}
explicit CXXReinterpretCastExpr(EmptyShell Empty)
@@ -221,7 +225,8 @@ class CXXConstCastExpr : public CXXNamedCastExpr {
public:
CXXConstCastExpr(QualType ty, Expr *op, TypeSourceInfo *writtenTy,
SourceLocation l)
- : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op, writtenTy, l) {}
+ : CXXNamedCastExpr(CXXConstCastExprClass, ty, CK_NoOp, op,
+ CXXBaseSpecifierArray(), writtenTy, l) {}
explicit CXXConstCastExpr(EmptyShell Empty)
: CXXNamedCastExpr(CXXConstCastExprClass, Empty) { }
@@ -293,37 +298,41 @@ public:
/// This represents code like @c typeid(int) or @c typeid(*objPtr)
class CXXTypeidExpr : public Expr {
private:
- bool isTypeOp : 1;
- union {
- void *Ty;
- Stmt *Ex;
- } Operand;
+ llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand;
SourceRange Range;
public:
- CXXTypeidExpr(bool isTypeOp, void *op, QualType Ty, const SourceRange r) :
- Expr(CXXTypeidExprClass, Ty,
+ CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R)
+ : Expr(CXXTypeidExprClass, Ty,
+ // typeid is never type-dependent (C++ [temp.dep.expr]p4)
+ false,
+ // typeid is value-dependent if the type or expression are dependent
+ Operand->getType()->isDependentType()),
+ Operand(Operand), Range(R) { }
+
+ CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R)
+ : Expr(CXXTypeidExprClass, Ty,
// typeid is never type-dependent (C++ [temp.dep.expr]p4)
false,
// typeid is value-dependent if the type or expression are dependent
- (isTypeOp ? QualType::getFromOpaquePtr(op)->isDependentType()
- : static_cast<Expr*>(op)->isValueDependent())),
- isTypeOp(isTypeOp), Range(r) {
- if (isTypeOp)
- Operand.Ty = op;
- else
- // op was an Expr*, so cast it back to that to be safe
- Operand.Ex = static_cast<Expr*>(op);
- }
+ Operand->isTypeDependent() || Operand->isValueDependent()),
+ Operand(Operand), Range(R) { }
+
+ bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
+
+ /// \brief Retrieves the type operand of this typeid() expression after
+ /// various required adjustments (removing reference types, cv-qualifiers).
+ QualType getTypeOperand() const;
- bool isTypeOperand() const { return isTypeOp; }
- QualType getTypeOperand() const {
+ /// \brief Retrieve source information for the type operand.
+ TypeSourceInfo *getTypeOperandSourceInfo() const {
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
- return QualType::getFromOpaquePtr(Operand.Ty);
+ return Operand.get<TypeSourceInfo *>();
}
+
Expr* getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
- return static_cast<Expr*>(Operand.Ex);
+ return static_cast<Expr*>(Operand.get<Stmt *>());
}
virtual SourceRange getSourceRange() const {
@@ -621,12 +630,20 @@ public:
/// CXXConstructExpr - Represents a call to a C++ constructor.
class CXXConstructExpr : public Expr {
+public:
+ enum ConstructionKind {
+ CK_Complete,
+ CK_NonVirtualBase,
+ CK_VirtualBase
+ };
+
+private:
CXXConstructorDecl *Constructor;
SourceLocation Loc;
bool Elidable : 1;
bool ZeroInitialization : 1;
- bool BaseInitialization : 1;
+ unsigned ConstructKind : 2;
Stmt **Args;
unsigned NumArgs;
@@ -636,7 +653,7 @@ protected:
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
bool ZeroInitialization = false,
- bool BaseInitialization = false);
+ ConstructionKind ConstructKind = CK_Complete);
~CXXConstructExpr() { }
virtual void DoDestroy(ASTContext &C);
@@ -651,7 +668,7 @@ public:
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool ZeroInitialization = false,
- bool BaseInitialization = false);
+ ConstructionKind ConstructKind = CK_Complete);
CXXConstructorDecl* getConstructor() const { return Constructor; }
@@ -673,8 +690,12 @@ public:
/// \brief Determines whether this constructor is actually constructing
/// a base class (rather than a complete object).
- bool isBaseInitialization() const { return BaseInitialization; }
- void setBaseInitialization(bool BI) { BaseInitialization = BI; }
+ ConstructionKind getConstructionKind() const {
+ return (ConstructionKind)ConstructKind;
+ }
+ void setConstructionKind(ConstructionKind CK) {
+ ConstructKind = CK;
+ }
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
@@ -725,9 +746,10 @@ class CXXFunctionalCastExpr : public ExplicitCastExpr {
public:
CXXFunctionalCastExpr(QualType ty, TypeSourceInfo *writtenTy,
SourceLocation tyBeginLoc, CastKind kind,
- Expr *castExpr, SourceLocation rParenLoc)
+ Expr *castExpr, CXXBaseSpecifierArray BasePath,
+ SourceLocation rParenLoc)
: ExplicitCastExpr(CXXFunctionalCastExprClass, ty, kind, castExpr,
- writtenTy),
+ BasePath, writtenTy),
TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
explicit CXXFunctionalCastExpr(EmptyShell Shell)
@@ -774,7 +796,8 @@ public:
CXXTemporaryObjectExpr(ASTContext &C, CXXConstructorDecl *Cons,
QualType writtenTy, SourceLocation tyBeginLoc,
Expr **Args,unsigned NumArgs,
- SourceLocation rParenLoc);
+ SourceLocation rParenLoc,
+ bool ZeroInitialization = false);
~CXXTemporaryObjectExpr() { }
@@ -1290,6 +1313,9 @@ public:
Results.append(Begin, End);
}
+ /// Gets the naming class of this lookup, if any.
+ CXXRecordDecl *getNamingClass() const;
+
typedef UnresolvedSetImpl::iterator decls_iterator;
decls_iterator decls_begin() const { return Results.begin(); }
decls_iterator decls_end() const { return Results.end(); }
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index 6f43973a3e1d..8a09f4e9a6a9 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -59,13 +59,14 @@ public:
/// and behavior as StringLiteral except that the string initializer is obtained
/// from ASTContext with the encoding type as an argument.
class ObjCEncodeExpr : public Expr {
- QualType EncType;
+ TypeSourceInfo *EncodedType;
SourceLocation AtLoc, RParenLoc;
public:
- ObjCEncodeExpr(QualType T, QualType ET,
+ ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType,
SourceLocation at, SourceLocation rp)
- : Expr(ObjCEncodeExprClass, T, ET->isDependentType(),
- ET->isDependentType()), EncType(ET), AtLoc(at), RParenLoc(rp) {}
+ : Expr(ObjCEncodeExprClass, T, EncodedType->getType()->isDependentType(),
+ EncodedType->getType()->isDependentType()),
+ EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {}
explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}
@@ -75,9 +76,12 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- QualType getEncodedType() const { return EncType; }
- void setEncodedType(QualType T) { EncType = T; }
+ QualType getEncodedType() const { return EncodedType->getType(); }
+ TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; }
+ void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) {
+ EncodedType = EncType;
+ }
virtual SourceRange getSourceRange() const {
return SourceRange(AtLoc, RParenLoc);
@@ -177,11 +181,12 @@ class ObjCIvarRefExpr : public Expr {
public:
ObjCIvarRefExpr(ObjCIvarDecl *d,
- QualType t, SourceLocation l, Expr *base=0,
+ QualType t, SourceLocation l, Expr *base,
bool arrow = false, bool freeIvar = false) :
- Expr(ObjCIvarRefExprClass, t, false, false), D(d),
- Loc(l), Base(base), IsArrow(arrow),
- IsFreeIvar(freeIvar) {}
+ Expr(ObjCIvarRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()), D(d),
+ Loc(l), Base(base), IsArrow(arrow),
+ IsFreeIvar(freeIvar) {}
explicit ObjCIvarRefExpr(EmptyShell Empty)
: Expr(ObjCIvarRefExprClass, Empty) {}
@@ -228,8 +233,9 @@ private:
public:
ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t,
SourceLocation l, Expr *base)
- : Expr(ObjCPropertyRefExprClass, t, false, false), AsProperty(PD),
- IdLoc(l), Base(base) {
+ : Expr(ObjCPropertyRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()),
+ AsProperty(PD), IdLoc(l), Base(base) {
}
explicit ObjCPropertyRefExpr(EmptyShell Empty)
@@ -293,7 +299,8 @@ public:
QualType t,
ObjCMethodDecl *setter,
SourceLocation l, Expr *base)
- : Expr(ObjCImplicitSetterGetterRefExprClass, t, false, false),
+ : Expr(ObjCImplicitSetterGetterRefExprClass, t, /*TypeDependent=*/false,
+ base->isValueDependent()),
Setter(setter), Getter(getter), MemberLoc(l), Base(base),
InterfaceDecl(0), ClassLoc(SourceLocation()) {
}
@@ -339,152 +346,376 @@ public:
virtual child_iterator child_end();
};
+/// \brief An expression that sends a message to the given Objective-C
+/// object or class.
+///
+/// The following contains two message send expressions:
+///
+/// \code
+/// [[NSString alloc] initWithString:@"Hello"]
+/// \endcode
+///
+/// The innermost message send invokes the "alloc" class method on the
+/// NSString class, while the outermost message send invokes the
+/// "initWithString" instance method on the object returned from
+/// NSString's "alloc". In all, an Objective-C message send can take
+/// on four different (although related) forms:
+///
+/// 1. Send to an object instance.
+/// 2. Send to a class.
+/// 3. Send to the superclass instance of the current class.
+/// 4. Send to the superclass of the current class.
+///
+/// All four kinds of message sends are modeled by the ObjCMessageExpr
+/// class, and can be distinguished via \c getReceiverKind(). Example:
+///
class ObjCMessageExpr : public Expr {
- // SubExprs - The receiver and arguments of the message expression.
- Stmt **SubExprs;
+ /// \brief The number of arguments in the message send, not
+ /// including the receiver.
+ unsigned NumArgs : 16;
+
+ /// \brief The kind of message send this is, which is one of the
+ /// ReceiverKind values.
+ ///
+ /// We pad this out to a byte to avoid excessive masking and shifting.
+ unsigned Kind : 8;
+
+ /// \brief Whether we have an actual method prototype in \c
+ /// SelectorOrMethod.
+ ///
+ /// When non-zero, we have a method declaration; otherwise, we just
+ /// have a selector.
+ unsigned HasMethod : 8;
+
+ /// \brief When the message expression is a send to 'super', this is
+ /// the location of the 'super' keyword.
+ SourceLocation SuperLoc;
+
+ /// \brief Stores either the selector that this message is sending
+ /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
+ /// referring to the method that we type-checked against.
+ uintptr_t SelectorOrMethod;
+
+ /// \brief The source locations of the open and close square
+ /// brackets ('[' and ']', respectively).
+ SourceLocation LBracLoc, RBracLoc;
+
+ ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
+ : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0),
+ HasMethod(0), SelectorOrMethod(0) { }
+
+ ObjCMessageExpr(QualType T,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc,
+ bool IsInstanceSuper,
+ QualType SuperType,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+ ObjCMessageExpr(QualType T,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+ ObjCMessageExpr(QualType T,
+ SourceLocation LBracLoc,
+ Expr *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \brief Retrieve the pointer value of the message receiver.
+ void *getReceiverPointer() const {
+ return *const_cast<void **>(
+ reinterpret_cast<const void * const*>(this + 1));
+ }
- // NumArgs - The number of arguments (not including the receiver) to the
- // message expression.
- unsigned NumArgs;
+ /// \brief Set the pointer value of the message receiver.
+ void setReceiverPointer(void *Value) {
+ *reinterpret_cast<void **>(this + 1) = Value;
+ }
- /// \brief The location of the class name in a class message.
- SourceLocation ClassNameLoc;
+public:
+ /// \brief The kind of receiver this message is sending to.
+ enum ReceiverKind {
+ /// \brief The receiver is a class.
+ Class = 0,
+ /// \brief The receiver is an object instance.
+ Instance,
+ /// \brief The receiver is a superclass.
+ SuperClass,
+ /// \brief The receiver is the instance of the superclass object.
+ SuperInstance
+ };
- // A unigue name for this message.
- Selector SelName;
+ /// \brief Create a message send to super.
+ ///
+ /// \param Context The ASTContext in which this expression will be created.
+ ///
+ /// \param T The result type of this message.
+ ///
+ /// \param LBrac The location of the open square bracket '['.
+ ///
+ /// \param SuperLoc The location of the "super" keyword.
+ ///
+ /// \param IsInstanceSuper Whether this is an instance "super"
+ /// message (otherwise, it's a class "super" message).
+ ///
+ /// \param Sel The selector used to determine which method gets called.
+ ///
+ /// \param Method The Objective-C method against which this message
+ /// send was type-checked. May be NULL.
+ ///
+ /// \param Args The message send arguments.
+ ///
+ /// \param NumArgs The number of arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ SourceLocation LBracLoc,
+ SourceLocation SuperLoc,
+ bool IsInstanceSuper,
+ QualType SuperType,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \brief Create a class message send.
+ ///
+ /// \param Context The ASTContext in which this expression will be created.
+ ///
+ /// \param T The result type of this message.
+ ///
+ /// \param LBrac The location of the open square bracket '['.
+ ///
+ /// \param Receiver The type of the receiver, including
+ /// source-location information.
+ ///
+ /// \param Sel The selector used to determine which method gets called.
+ ///
+ /// \param Method The Objective-C method against which this message
+ /// send was type-checked. May be NULL.
+ ///
+ /// \param Args The message send arguments.
+ ///
+ /// \param NumArgs The number of arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ SourceLocation LBracLoc,
+ TypeSourceInfo *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \brief Create an instance message send.
+ ///
+ /// \param Context The ASTContext in which this expression will be created.
+ ///
+ /// \param T The result type of this message.
+ ///
+ /// \param LBrac The location of the open square bracket '['.
+ ///
+ /// \param Receiver The expression used to produce the object that
+ /// will receive this message.
+ ///
+ /// \param Sel The selector used to determine which method gets called.
+ ///
+ /// \param Method The Objective-C method against which this message
+ /// send was type-checked. May be NULL.
+ ///
+ /// \param Args The message send arguments.
+ ///
+ /// \param NumArgs The number of arguments.
+ ///
+ /// \param RBracLoc The location of the closing square bracket ']'.
+ static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+ SourceLocation LBracLoc,
+ Expr *Receiver,
+ Selector Sel,
+ ObjCMethodDecl *Method,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation RBracLoc);
+
+ /// \brief Create an empty Objective-C message expression, to be
+ /// filled in by subsequent calls.
+ ///
+ /// \param Context The context in which the message send will be created.
+ ///
+ /// \param NumArgs The number of message arguments, not including
+ /// the receiver.
+ static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
+
+ /// \brief Determine the kind of receiver that this message is being
+ /// sent to.
+ ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+
+ /// \brief Determine whether this is an instance message to either a
+ /// computed object or to super.
+ bool isInstanceMessage() const {
+ return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
+ }
- // A method prototype for this message (optional).
- // FIXME: Since method decls contain the selector, and most messages have a
- // prototype, consider devising a scheme for unifying SelName/MethodProto.
- ObjCMethodDecl *MethodProto;
+ /// \brief Determine whether this is an class message to either a
+ /// specified class or to super.
+ bool isClassMessage() const {
+ return getReceiverKind() == Class || getReceiverKind() == SuperClass;
+ }
- SourceLocation LBracloc, RBracloc;
+ /// \brief Returns the receiver of an instance message.
+ ///
+ /// \brief Returns the object expression for an instance message, or
+ /// NULL for a message that is not an instance message.
+ Expr *getInstanceReceiver() {
+ if (getReceiverKind() == Instance)
+ return static_cast<Expr *>(getReceiverPointer());
- // Constants for indexing into SubExprs.
- enum { RECEIVER=0, ARGS_START=1 };
+ return 0;
+ }
+ const Expr *getInstanceReceiver() const {
+ return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
+ }
- // Bit-swizzling flags.
- enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
- unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
+ /// \brief Turn this message send into an instance message that
+ /// computes the receiver object with the given expression.
+ void setInstanceReceiver(Expr *rec) {
+ Kind = Instance;
+ setReceiverPointer(rec);
+ }
+
+ /// \brief Returns the type of a class message send, or NULL if the
+ /// message is not a class message.
+ QualType getClassReceiver() const {
+ if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
+ return TSInfo->getType();
+
+ return QualType();
+ }
-public:
- /// This constructor is used to represent class messages where the
- /// ObjCInterfaceDecl* of the receiver is not known.
- ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
- SourceLocation clsNameLoc, Selector selInfo,
- QualType retType, ObjCMethodDecl *methDecl,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned NumArgs);
-
- /// This constructor is used to represent class messages where the
- /// ObjCInterfaceDecl* of the receiver is known.
- // FIXME: clsName should be typed to ObjCInterfaceType
- ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
- SourceLocation clsNameLoc, Selector selInfo,
- QualType retType, ObjCMethodDecl *methDecl,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned NumArgs);
-
- // constructor for instance messages.
- ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo,
- QualType retType, ObjCMethodDecl *methDecl,
- SourceLocation LBrac, SourceLocation RBrac,
- Expr **ArgExprs, unsigned NumArgs);
-
- explicit ObjCMessageExpr(EmptyShell Empty)
- : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
-
- virtual void DoDestroy(ASTContext &C);
-
- /// getReceiver - Returns the receiver of the message expression.
- /// This can be NULL if the message is for class methods. For
- /// class methods, use getClassName.
- /// FIXME: need to handle/detect 'super' usage within a class method.
- Expr *getReceiver() {
- uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
- return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
- }
- const Expr *getReceiver() const {
- return const_cast<ObjCMessageExpr*>(this)->getReceiver();
- }
- // FIXME: need setters for different receiver types.
- void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; }
- Selector getSelector() const { return SelName; }
- void setSelector(Selector S) { SelName = S; }
+ /// \brief Returns a type-source information of a class message
+ /// send, or NULL if the message is not a class message.
+ TypeSourceInfo *getClassReceiverTypeInfo() const {
+ if (getReceiverKind() == Class)
+ return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
+ return 0;
+ }
+
+ void setClassReceiver(TypeSourceInfo *TSInfo) {
+ Kind = Class;
+ setReceiverPointer(TSInfo);
+ }
- const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
- ObjCMethodDecl *getMethodDecl() { return MethodProto; }
- void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
+ /// \brief Retrieve the location of the 'super' keyword for a class
+ /// or instance message to 'super', otherwise an invalid source location.
+ SourceLocation getSuperLoc() const {
+ if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+ return SuperLoc;
- /// \brief Describes the class receiver of a message send.
- struct ClassInfo {
- /// \brief The interface declaration for the class that is
- /// receiving the message. May be NULL.
- ObjCInterfaceDecl *Decl;
+ return SourceLocation();
+ }
- /// \brief The name of the class that is receiving the
- /// message. This will never be NULL.
- IdentifierInfo *Name;
+ /// \brief Retrieve the Objective-C interface to which this message
+ /// is being directed, if known.
+ ///
+ /// This routine cross-cuts all of the different kinds of message
+ /// sends to determine what the underlying (statically known) type
+ /// of the receiver will be; use \c getReceiverKind() to determine
+ /// whether the message is a class or an instance method, whether it
+ /// is a send to super or not, etc.
+ ///
+ /// \returns The Objective-C interface if known, otherwise NULL.
+ ObjCInterfaceDecl *getReceiverInterface() const;
+
+ /// \brief Retrieve the type referred to by 'super'.
+ ///
+ /// The returned type will either be an ObjCInterfaceType (for an
+ /// class message to super) or an ObjCObjectPointerType that refers
+ /// to a class (for an instance message to super);
+ QualType getSuperType() const {
+ if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+ return QualType::getFromOpaquePtr(getReceiverPointer());
+
+ return QualType();
+ }
- /// \brief The source location of the class name.
- SourceLocation Loc;
+ void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
+ Kind = IsInstanceSuper? SuperInstance : SuperClass;
+ SuperLoc = Loc;
+ setReceiverPointer(T.getAsOpaquePtr());
+ }
- ClassInfo() : Decl(0), Name(0), Loc() { }
+ Selector getSelector() const;
- ClassInfo(ObjCInterfaceDecl *Decl, IdentifierInfo *Name, SourceLocation Loc)
- : Decl(Decl), Name(Name), Loc(Loc) { }
- };
+ void setSelector(Selector S) {
+ HasMethod = false;
+ SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
+ }
- /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
- /// and IdentifierInfo* of the invoked class. Both can be NULL if this
- /// is an instance message, and the ObjCInterfaceDecl* can be NULL if none
- /// was available when this ObjCMessageExpr object was constructed.
- ClassInfo getClassInfo() const;
- void setClassInfo(const ClassInfo &C);
+ const ObjCMethodDecl *getMethodDecl() const {
+ if (HasMethod)
+ return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
- /// getClassName - For class methods, this returns the invoked class,
- /// and returns NULL otherwise. For instance methods, use getReceiver.
- IdentifierInfo *getClassName() const {
- return getClassInfo().Name;
+ return 0;
}
- /// getNumArgs - Return the number of actual arguments to this call.
+ ObjCMethodDecl *getMethodDecl() {
+ if (HasMethod)
+ return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
+
+ return 0;
+ }
+
+ void setMethodDecl(ObjCMethodDecl *MD) {
+ HasMethod = true;
+ SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
+ }
+
+ /// \brief Return the number of actual arguments in this message,
+ /// not counting the receiver.
unsigned getNumArgs() const { return NumArgs; }
- void setNumArgs(unsigned nArgs) {
- NumArgs = nArgs;
- // FIXME: should always allocate SubExprs via the ASTContext's
- // allocator.
- if (!SubExprs)
- SubExprs = new Stmt* [NumArgs + 1];
+
+ /// \brief Retrieve the arguments to this message, not including the
+ /// receiver.
+ Stmt **getArgs() {
+ return reinterpret_cast<Stmt **>(this + 1) + 1;
+ }
+ const Stmt * const *getArgs() const {
+ return reinterpret_cast<const Stmt * const *>(this + 1) + 1;
}
/// getArg - Return the specified argument.
Expr *getArg(unsigned Arg) {
assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+ARGS_START]);
+ return cast<Expr>(getArgs()[Arg]);
}
const Expr *getArg(unsigned Arg) const {
assert(Arg < NumArgs && "Arg access out of range!");
- return cast<Expr>(SubExprs[Arg+ARGS_START]);
+ return cast<Expr>(getArgs()[Arg]);
}
/// setArg - Set the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr) {
assert(Arg < NumArgs && "Arg access out of range!");
- SubExprs[Arg+ARGS_START] = ArgExpr;
+ getArgs()[Arg] = ArgExpr;
}
- SourceLocation getLeftLoc() const { return LBracloc; }
- SourceLocation getRightLoc() const { return RBracloc; }
+ SourceLocation getLeftLoc() const { return LBracLoc; }
+ SourceLocation getRightLoc() const { return RBracLoc; }
- void setLeftLoc(SourceLocation L) { LBracloc = L; }
- void setRightLoc(SourceLocation L) { RBracloc = L; }
+ void setLeftLoc(SourceLocation L) { LBracLoc = L; }
+ void setRightLoc(SourceLocation L) { RBracLoc = L; }
void setSourceRange(SourceRange R) {
- LBracloc = R.getBegin();
- RBracloc = R.getEnd();
+ LBracLoc = R.getBegin();
+ RBracLoc = R.getEnd();
}
virtual SourceRange getSourceRange() const {
- return SourceRange(LBracloc, RBracloc);
+ return SourceRange(LBracLoc, RBracLoc);
}
static bool classof(const Stmt *T) {
@@ -499,14 +730,17 @@ public:
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
- arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
- arg_iterator arg_end() { return &SubExprs[ARGS_START] + NumArgs; }
- const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
- const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
+ arg_iterator arg_begin() { return getArgs(); }
+ arg_iterator arg_end() { return getArgs() + NumArgs; }
+ const_arg_iterator arg_begin() const { return getArgs(); }
+ const_arg_iterator arg_end() const { return getArgs() + NumArgs; }
};
/// ObjCSuperExpr - Represents the "super" expression in Objective-C,
/// which refers to the object on which the current method is executing.
+///
+/// FIXME: This class is intended for removal, once its remaining
+/// clients have been altered to represent "super" internally.
class ObjCSuperExpr : public Expr {
SourceLocation Loc;
public:
@@ -542,7 +776,8 @@ class ObjCIsaExpr : public Expr {
bool IsArrow;
public:
ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, QualType ty)
- : Expr(ObjCIsaExprClass, ty, false, false),
+ : Expr(ObjCIsaExprClass, ty, /*TypeDependent=*/false,
+ base->isValueDependent()),
Base(base), IsaMemberLoc(l), IsArrow(isarrow) {}
/// \brief Build an empty expression.
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index b8d80bc8978d..79e44511d32d 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -66,6 +66,13 @@ public:
/// building a new declaration.
virtual Decl *GetDecl(uint32_t ID) = 0;
+ /// \brief Resolve a selector ID into a selector.
+ virtual Selector GetSelector(uint32_t ID) = 0;
+
+ /// \brief Returns the number of selectors known to the external AST
+ /// source.
+ virtual uint32_t GetNumKnownSelectors() = 0;
+
/// \brief Resolve the offset of a statement in the decl stream into a
/// statement.
///
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 466848976cb3..0b68a4007363 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -70,13 +70,13 @@ namespace clang {
};
class ConstExprIterator {
- Stmt* const * I;
+ const Stmt * const *I;
public:
- ConstExprIterator(Stmt* const* i) : I(i) {}
+ ConstExprIterator(const Stmt * const *i) : I(i) {}
ConstExprIterator() : I(0) {}
ConstExprIterator& operator++() { ++I; return *this; }
- ConstExprIterator operator+(size_t i) { return I+i; }
- ConstExprIterator operator-(size_t i) { return I-i; }
+ ConstExprIterator operator+(size_t i) const { return I+i; }
+ ConstExprIterator operator-(size_t i) const { return I-i; }
const Expr * operator[](size_t idx) const;
signed operator-(const ConstExprIterator& R) const { return I - R.I; }
const Expr * operator*() const;
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index ec6149e55f11..3a23e49148d5 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -78,6 +78,7 @@ EXPR(StringLiteral , Expr)
EXPR(CharacterLiteral , Expr)
EXPR(ParenExpr , Expr)
EXPR(UnaryOperator , Expr)
+EXPR(OffsetOfExpr , Expr)
EXPR(SizeOfAlignOfExpr , Expr)
EXPR(ArraySubscriptExpr , Expr)
EXPR(CallExpr , Expr)
@@ -107,7 +108,7 @@ EXPR(GNUNullExpr , Expr)
// C++ Expressions.
EXPR(CXXOperatorCallExpr , CallExpr)
EXPR(CXXMemberCallExpr , CallExpr)
-EXPR(CXXNamedCastExpr , ExplicitCastExpr)
+ABSTRACT_EXPR(CXXNamedCastExpr , ExplicitCastExpr)
EXPR(CXXStaticCastExpr , CXXNamedCastExpr)
EXPR(CXXDynamicCastExpr , CXXNamedCastExpr)
EXPR(CXXReinterpretCastExpr , CXXNamedCastExpr)
diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h
index 3fd8f1672deb..269aa4c6dab2 100644
--- a/include/clang/AST/StmtObjC.h
+++ b/include/clang/AST/StmtObjC.h
@@ -71,38 +71,31 @@ public:
/// ObjCAtCatchStmt - This represents objective-c's @catch statement.
class ObjCAtCatchStmt : public Stmt {
private:
- enum { BODY, NEXT_CATCH, END_EXPR };
- ParmVarDecl *ExceptionDecl;
- Stmt *SubExprs[END_EXPR];
+ VarDecl *ExceptionDecl;
+ Stmt *Body;
SourceLocation AtCatchLoc, RParenLoc;
public:
ObjCAtCatchStmt(SourceLocation atCatchLoc, SourceLocation rparenloc,
- ParmVarDecl *catchVarDecl,
- Stmt *atCatchStmt, Stmt *atCatchList);
+ VarDecl *catchVarDecl,
+ Stmt *atCatchStmt)
+ : Stmt(ObjCAtCatchStmtClass), ExceptionDecl(catchVarDecl),
+ Body(atCatchStmt), AtCatchLoc(atCatchLoc), RParenLoc(rparenloc) { }
explicit ObjCAtCatchStmt(EmptyShell Empty) :
Stmt(ObjCAtCatchStmtClass, Empty) { }
- const Stmt *getCatchBody() const { return SubExprs[BODY]; }
- Stmt *getCatchBody() { return SubExprs[BODY]; }
- void setCatchBody(Stmt *S) { SubExprs[BODY] = S; }
+ const Stmt *getCatchBody() const { return Body; }
+ Stmt *getCatchBody() { return Body; }
+ void setCatchBody(Stmt *S) { Body = S; }
- const ObjCAtCatchStmt *getNextCatchStmt() const {
- return static_cast<const ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
- }
- ObjCAtCatchStmt *getNextCatchStmt() {
- return static_cast<ObjCAtCatchStmt*>(SubExprs[NEXT_CATCH]);
- }
- void setNextCatchStmt(Stmt *S) { SubExprs[NEXT_CATCH] = S; }
-
- const ParmVarDecl *getCatchParamDecl() const {
+ const VarDecl *getCatchParamDecl() const {
return ExceptionDecl;
}
- ParmVarDecl *getCatchParamDecl() {
+ VarDecl *getCatchParamDecl() {
return ExceptionDecl;
}
- void setCatchParamDecl(ParmVarDecl *D) { ExceptionDecl = D; }
+ void setCatchParamDecl(VarDecl *D) { ExceptionDecl = D; }
SourceLocation getAtCatchLoc() const { return AtCatchLoc; }
void setAtCatchLoc(SourceLocation Loc) { AtCatchLoc = Loc; }
@@ -110,7 +103,7 @@ public:
void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; }
virtual SourceRange getSourceRange() const {
- return SourceRange(AtCatchLoc, SubExprs[BODY]->getLocEnd());
+ return SourceRange(AtCatchLoc, Body->getLocEnd());
}
bool hasEllipsis() const { return getCatchParamDecl() == 0; }
@@ -160,50 +153,94 @@ public:
/// @try ... @catch ... @finally statement.
class ObjCAtTryStmt : public Stmt {
private:
- enum { TRY, CATCH, FINALLY, END_EXPR };
- Stmt* SubStmts[END_EXPR];
-
+ // The location of the
SourceLocation AtTryLoc;
-public:
+
+ // The number of catch blocks in this statement.
+ unsigned NumCatchStmts : 16;
+
+ // Whether this statement has a @finally statement.
+ bool HasFinally : 1;
+
+ /// \brief Retrieve the statements that are stored after this @try statement.
+ ///
+ /// The order of the statements in memory follows the order in the source,
+ /// with the @try body first, followed by the @catch statements (if any) and,
+ /// finally, the @finally (if it exists).
+ Stmt **getStmts() { return reinterpret_cast<Stmt **> (this + 1); }
+ const Stmt* const *getStmts() const {
+ return reinterpret_cast<const Stmt * const*> (this + 1);
+ }
+
ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt,
- Stmt *atCatchStmt,
- Stmt *atFinallyStmt)
- : Stmt(ObjCAtTryStmtClass) {
- SubStmts[TRY] = atTryStmt;
- SubStmts[CATCH] = atCatchStmt;
- SubStmts[FINALLY] = atFinallyStmt;
- AtTryLoc = atTryLoc;
- }
- explicit ObjCAtTryStmt(EmptyShell Empty) :
- Stmt(ObjCAtTryStmtClass, Empty) { }
+ Stmt **CatchStmts, unsigned NumCatchStmts,
+ Stmt *atFinallyStmt);
+
+ explicit ObjCAtTryStmt(EmptyShell Empty, unsigned NumCatchStmts,
+ bool HasFinally)
+ : Stmt(ObjCAtTryStmtClass, Empty), NumCatchStmts(NumCatchStmts),
+ HasFinally(HasFinally) { }
+public:
+ static ObjCAtTryStmt *Create(ASTContext &Context, SourceLocation atTryLoc,
+ Stmt *atTryStmt,
+ Stmt **CatchStmts, unsigned NumCatchStmts,
+ Stmt *atFinallyStmt);
+ static ObjCAtTryStmt *CreateEmpty(ASTContext &Context,
+ unsigned NumCatchStmts,
+ bool HasFinally);
+
+ /// \brief Retrieve the location of the @ in the @try.
SourceLocation getAtTryLoc() const { return AtTryLoc; }
void setAtTryLoc(SourceLocation Loc) { AtTryLoc = Loc; }
- const Stmt *getTryBody() const { return SubStmts[TRY]; }
- Stmt *getTryBody() { return SubStmts[TRY]; }
- void setTryBody(Stmt *S) { SubStmts[TRY] = S; }
-
- const ObjCAtCatchStmt *getCatchStmts() const {
- return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
+ /// \brief Retrieve the @try body.
+ const Stmt *getTryBody() const { return getStmts()[0]; }
+ Stmt *getTryBody() { return getStmts()[0]; }
+ void setTryBody(Stmt *S) { getStmts()[0] = S; }
+
+ /// \brief Retrieve the number of @catch statements in this try-catch-finally
+ /// block.
+ unsigned getNumCatchStmts() const { return NumCatchStmts; }
+
+ /// \brief Retrieve a @catch statement.
+ const ObjCAtCatchStmt *getCatchStmt(unsigned I) const {
+ assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+ return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
}
- ObjCAtCatchStmt *getCatchStmts() {
- return dyn_cast_or_null<ObjCAtCatchStmt>(SubStmts[CATCH]);
+
+ /// \brief Retrieve a @catch statement.
+ ObjCAtCatchStmt *getCatchStmt(unsigned I) {
+ assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+ return cast_or_null<ObjCAtCatchStmt>(getStmts()[I + 1]);
}
- void setCatchStmts(Stmt *S) { SubStmts[CATCH] = S; }
-
+
+ /// \brief Set a particular catch statement.
+ void setCatchStmt(unsigned I, ObjCAtCatchStmt *S) {
+ assert(I < NumCatchStmts && "Out-of-bounds @catch index");
+ getStmts()[I + 1] = S;
+ }
+
+ /// Retrieve the @finally statement, if any.
const ObjCAtFinallyStmt *getFinallyStmt() const {
- return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
+ if (!HasFinally)
+ return 0;
+
+ return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
}
ObjCAtFinallyStmt *getFinallyStmt() {
- return dyn_cast_or_null<ObjCAtFinallyStmt>(SubStmts[FINALLY]);
+ if (!HasFinally)
+ return 0;
+
+ return cast_or_null<ObjCAtFinallyStmt>(getStmts()[1 + NumCatchStmts]);
}
- void setFinallyStmt(Stmt *S) { SubStmts[FINALLY] = S; }
-
- virtual SourceRange getSourceRange() const {
- return SourceRange(AtTryLoc, SubStmts[TRY]->getLocEnd());
+ void setFinallyStmt(Stmt *S) {
+ assert(HasFinally && "@try does not have a @finally slot!");
+ getStmts()[1 + NumCatchStmts] = S;
}
+ virtual SourceRange getSourceRange() const;
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == ObjCAtTryStmtClass;
}
diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h
index aafe96381192..f3de9fa011bc 100644
--- a/include/clang/AST/TemplateName.h
+++ b/include/clang/AST/TemplateName.h
@@ -25,6 +25,7 @@ namespace llvm {
namespace clang {
class DependentTemplateName;
+class DiagnosticBuilder;
class IdentifierInfo;
class NestedNameSpecifier;
struct PrintingPolicy;
@@ -173,6 +174,11 @@ public:
}
};
+/// Insertion operator for diagnostics. This allows sending TemplateName's
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ TemplateName N);
+
/// \brief Represents a template name that was expressed as a
/// qualified name.
///
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 72793651c4be..030c74c64089 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -871,6 +871,7 @@ public:
bool isRecordType() const;
bool isClassType() const;
bool isStructureType() const;
+ bool isStructureOrClassType() const;
bool isUnionType() const;
bool isComplexIntegerType() const; // GCC _Complex integer type.
bool isVectorType() const; // GCC vector type.
@@ -922,6 +923,11 @@ public:
const ObjCInterfaceType *getAsObjCQualifiedInterfaceType() const;
const CXXRecordDecl *getCXXRecordDeclForPointerType() const;
+ /// \brief Retrieves the CXXRecordDecl that this type refers to, either
+ /// because the type is a RecordType or because it is the injected-class-name
+ /// type of a class template or class template partial specialization.
+ CXXRecordDecl *getAsCXXRecordDecl() const;
+
// Member-template getAs<specific type>'. This scheme will eventually
// replace the specific getAsXXXX methods above.
//
@@ -2433,8 +2439,11 @@ public:
class TemplateSpecializationType
: public Type, public llvm::FoldingSetNode {
- // FIXME: Currently needed for profiling expressions; can we avoid this?
- ASTContext &Context;
+ // The ASTContext is currently needed in order to profile expressions.
+ // FIXME: avoid this.
+ //
+ // The bool is whether this is a current instantiation.
+ llvm::PointerIntPair<ASTContext*, 1, bool> ContextAndCurrentInstantiation;
/// \brief The name of the template being specialized.
TemplateName Template;
@@ -2445,6 +2454,7 @@ class TemplateSpecializationType
TemplateSpecializationType(ASTContext &Context,
TemplateName T,
+ bool IsCurrentInstantiation,
const TemplateArgument *Args,
unsigned NumArgs, QualType Canon);
@@ -2476,6 +2486,12 @@ public:
static std::string PrintTemplateArgumentList(const TemplateArgumentListInfo &,
const PrintingPolicy &Policy);
+ /// True if this template specialization type matches a current
+ /// instantiation in the context in which it is found.
+ bool isCurrentInstantiation() const {
+ return ContextAndCurrentInstantiation.getInt();
+ }
+
typedef const TemplateArgument * iterator;
iterator begin() const { return getArgs(); }
@@ -2496,15 +2512,20 @@ public:
/// \precondition @c isArgType(Arg)
const TemplateArgument &getArg(unsigned Idx) const;
- bool isSugared() const { return !isDependentType(); }
+ bool isSugared() const {
+ return !isDependentType() || isCurrentInstantiation();
+ }
QualType desugar() const { return getCanonicalTypeInternal(); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Template, getArgs(), NumArgs, Context);
+ Profile(ID, Template, isCurrentInstantiation(), getArgs(), NumArgs,
+ *ContextAndCurrentInstantiation.getPointer());
}
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
- const TemplateArgument *Args, unsigned NumArgs,
+ bool IsCurrentInstantiation,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ASTContext &Context);
static bool classof(const Type *T) {
@@ -2513,40 +2534,57 @@ public:
static bool classof(const TemplateSpecializationType *T) { return true; }
};
-/// \brief The injected class name of a C++ class template. Used to
-/// record that a type was spelled with a bare identifier rather than
-/// as a template-id; the equivalent for non-templated classes is just
-/// RecordType.
+/// \brief The injected class name of a C++ class template or class
+/// template partial specialization. Used to record that a type was
+/// spelled with a bare identifier rather than as a template-id; the
+/// equivalent for non-templated classes is just RecordType.
///
-/// For consistency, template instantiation turns these into RecordTypes.
+/// Injected class name types are always dependent. Template
+/// instantiation turns these into RecordTypes.
///
-/// The desugared form is always a unqualified TemplateSpecializationType.
-/// The canonical form is always either a TemplateSpecializationType
-/// (when dependent) or a RecordType (otherwise).
+/// Injected class name types are always canonical. This works
+/// because it is impossible to compare an injected class name type
+/// with the corresponding non-injected template type, for the same
+/// reason that it is impossible to directly compare template
+/// parameters from different dependent contexts: injected class name
+/// types can only occur within the scope of a particular templated
+/// declaration, and within that scope every template specialization
+/// will canonicalize to the injected class name (when appropriate
+/// according to the rules of the language).
class InjectedClassNameType : public Type {
CXXRecordDecl *Decl;
- QualType UnderlyingType;
+ /// The template specialization which this type represents.
+ /// For example, in
+ /// template <class T> class A { ... };
+ /// this is A<T>, whereas in
+ /// template <class X, class Y> class A<B<X,Y> > { ... };
+ /// this is A<B<X,Y> >.
+ ///
+ /// It is always unqualified, always a template specialization type,
+ /// and always dependent.
+ QualType InjectedType;
friend class ASTContext; // ASTContext creates these.
- InjectedClassNameType(CXXRecordDecl *D, QualType TST, QualType Canon)
- : Type(InjectedClassName, Canon, Canon->isDependentType()),
- Decl(D), UnderlyingType(TST) {
+ friend class TagDecl; // TagDecl mutilates the Decl
+ InjectedClassNameType(CXXRecordDecl *D, QualType TST)
+ : Type(InjectedClassName, QualType(), true),
+ Decl(D), InjectedType(TST) {
assert(isa<TemplateSpecializationType>(TST));
assert(!TST.hasQualifiers());
- assert(TST->getCanonicalTypeInternal() == Canon);
+ assert(TST->isDependentType());
}
public:
- QualType getUnderlyingType() const { return UnderlyingType; }
- const TemplateSpecializationType *getUnderlyingTST() const {
- return cast<TemplateSpecializationType>(UnderlyingType.getTypePtr());
+ QualType getInjectedSpecializationType() const { return InjectedType; }
+ const TemplateSpecializationType *getInjectedTST() const {
+ return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
}
CXXRecordDecl *getDecl() const { return Decl; }
- bool isSugared() const { return true; }
- QualType desugar() const { return UnderlyingType; }
+ bool isSugared() const { return false; }
+ QualType desugar() const { return QualType(this, 0); }
static bool classof(const Type *T) {
return T->getTypeClass() == InjectedClassName;
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index 7e8b73c7a5f9..c665073025f7 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -91,7 +91,7 @@ DEPENDENT_TYPE(TemplateTypeParm, Type)
NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
-NON_CANONICAL_TYPE(InjectedClassName, Type)
+DEPENDENT_TYPE(InjectedClassName, Type)
DEPENDENT_TYPE(DependentName, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
@@ -105,6 +105,8 @@ LAST_TYPE(ObjCObjectPointer)
#ifdef LEAF_TYPE
LEAF_TYPE(Enum)
LEAF_TYPE(Builtin)
+LEAF_TYPE(Record)
+LEAF_TYPE(InjectedClassName)
LEAF_TYPE(ObjCInterface)
LEAF_TYPE(TemplateTypeParm)
#undef LEAF_TYPE
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 553f04d76aec..cad7e61d553c 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -17,56 +17,7 @@
#include <iterator>
#include "llvm/ADT/SmallVector.h"
-#include "clang/Basic/Specifiers.h"
-
-namespace clang {
-
-class NamedDecl;
-
-/// A POD class for pairing a NamedDecl* with an access specifier.
-/// Can be put into unions.
-class DeclAccessPair {
- NamedDecl *Ptr; // we'd use llvm::PointerUnion, but it isn't trivial
-
- enum { Mask = 0x3 };
-
-public:
- static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS) {
- DeclAccessPair p;
- p.set(D, AS);
- return p;
- }
-
- NamedDecl *getDecl() const {
- return (NamedDecl*) (~Mask & (uintptr_t) Ptr);
- }
- AccessSpecifier getAccess() const {
- return AccessSpecifier(Mask & (uintptr_t) Ptr);
- }
-
- void setDecl(NamedDecl *D) {
- set(D, getAccess());
- }
- void setAccess(AccessSpecifier AS) {
- set(getDecl(), AS);
- }
- void set(NamedDecl *D, AccessSpecifier AS) {
- Ptr = reinterpret_cast<NamedDecl*>(uintptr_t(AS) |
- reinterpret_cast<uintptr_t>(D));
- }
-
- operator NamedDecl*() const { return getDecl(); }
- NamedDecl *operator->() const { return getDecl(); }
-};
-}
-
-// Take a moment to tell SmallVector that this is POD.
-namespace llvm {
-template<typename> struct isPodLike;
-template<> struct isPodLike<clang::DeclAccessPair> {
- static const bool value = true;
-};
-}
+#include "clang/AST/DeclAccessPair.h"
namespace clang {
diff --git a/include/clang/AST/UsuallyTinyPtrVector.h b/include/clang/AST/UsuallyTinyPtrVector.h
new file mode 100644
index 000000000000..5ee40e05c956
--- /dev/null
+++ b/include/clang/AST/UsuallyTinyPtrVector.h
@@ -0,0 +1,105 @@
+//===-- UsuallyTinyPtrVector.h - Pointer vector class -----------*- 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 UsuallyTinyPtrVector class, which is a vector that
+// optimizes the case where there is only one element.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_USUALLY_TINY_PTR_VECTOR_H
+#define LLVM_CLANG_AST_USUALLY_TINY_PTR_VECTOR_H
+
+#include <vector>
+
+namespace clang {
+
+/// \brief A vector class template that is optimized for storing a single
+/// pointer element.
+template<typename T>
+class UsuallyTinyPtrVector {
+ /// \brief Storage for the vector.
+ ///
+ /// When the low bit is zero, this is a T *. When the
+ /// low bit is one, this is a std::vector<T *> *.
+ mutable uintptr_t Storage;
+
+ typedef std::vector<T*> vector_type;
+
+public:
+ UsuallyTinyPtrVector() : Storage(0) { }
+ explicit UsuallyTinyPtrVector(T *Element)
+ : Storage(reinterpret_cast<uintptr_t>(Element)) { }
+
+ bool empty() const { return !Storage; }
+
+ typedef const T **iterator;
+ iterator begin() const;
+ iterator end() const;
+
+ void push_back(T *Method);
+ void Destroy();
+};
+
+template<typename T>
+typename UsuallyTinyPtrVector<T>::iterator
+UsuallyTinyPtrVector<T>::begin() const {
+ if ((Storage & 0x01) == 0)
+ return reinterpret_cast<iterator>(&Storage);
+
+ vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+ return &Vec->front();
+}
+
+
+template<typename T>
+typename UsuallyTinyPtrVector<T>::iterator
+UsuallyTinyPtrVector<T>::end() const {
+ if ((Storage & 0x01) == 0) {
+ if (Storage == 0)
+ return reinterpret_cast<iterator>(&Storage);
+
+ return reinterpret_cast<iterator>(&Storage) + 1;
+ }
+
+ vector_type *Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+ return &Vec->front() + Vec->size();
+}
+
+template<typename T>
+void UsuallyTinyPtrVector<T>::push_back(T *Element) {
+ if (Storage == 0) {
+ // 0 -> 1 element.
+ Storage = reinterpret_cast<uintptr_t>(Element);
+ return;
+ }
+
+ vector_type *Vec;
+ if ((Storage & 0x01) == 0) {
+ // 1 -> 2 elements. Allocate a new vector and push the element into that
+ // vector.
+ Vec = new vector_type;
+ Vec->push_back(reinterpret_cast<T *>(Storage));
+ Storage = reinterpret_cast<uintptr_t>(Vec) | 0x01;
+ } else
+ Vec = reinterpret_cast<vector_type *>(Storage & ~0x01);
+
+ // Add the new element to the vector.
+ Vec->push_back(Element);
+}
+
+template<typename T>
+void UsuallyTinyPtrVector<T>::Destroy() {
+ if (Storage & 0x01)
+ delete reinterpret_cast<vector_type *>(Storage & ~0x01);
+
+ Storage = 0;
+}
+
+}
+#endif
diff --git a/include/clang/Analysis/Support/Optional.h b/include/clang/Analysis/Support/Optional.h
deleted file mode 100644
index a4e6d519a04f..000000000000
--- a/include/clang/Analysis/Support/Optional.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file provides Optional, a template class modeled in the spirit of
-// OCaml's 'opt' variant. The idea is to strongly type whether or not
-// a value can be optional.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_OPTIONAL
-#define LLVM_CLANG_ANALYSIS_OPTIONAL
-
-namespace clang {
-
-template<typename T>
-class Optional {
- T x;
- unsigned hasVal : 1;
-public:
- explicit Optional() : x(), hasVal(false) {}
- Optional(const T &y) : x(y), hasVal(true) {}
-
- static inline Optional create(const T* y) {
- return y ? Optional(*y) : Optional();
- }
-
- Optional &operator=(const T &y) {
- x = y;
- hasVal = true;
- return *this;
- }
-
- const T* getPointer() const { assert(hasVal); return &x; }
- const T& getValue() const { assert(hasVal); return x; }
-
- operator bool() const { return hasVal; }
- bool hasValue() const { return hasVal; }
- const T* operator->() const { return getPointer(); }
- const T& operator*() const { assert(hasVal); return x; }
-};
-} //end clang namespace
-
-namespace llvm {
-
-template<typename T> struct simplify_type;
-
-template <typename T>
-struct simplify_type<const ::clang::Optional<T> > {
- typedef const T* SimpleType;
- static SimpleType getSimplifiedValue(const ::clang::Optional<T> &Val) {
- return Val.getPointer();
- }
-};
-
-template <typename T>
-struct simplify_type< ::clang::Optional<T> >
- : public simplify_type<const ::clang::Optional<T> > {};
-} // end llvm namespace
-
-#endif
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 453f660c360a..b306954975f4 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -314,6 +314,7 @@ BUILTIN(__builtin_setjmp, "iv**", "")
BUILTIN(__builtin_longjmp, "vv**i", "r")
BUILTIN(__builtin_unwind_init, "v", "")
BUILTIN(__builtin_eh_return_data_regno, "ii", "nc")
+BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:")
BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:")
// GCC exception builtins
@@ -335,6 +336,7 @@ BUILTIN(__builtin___strcat_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strcpy_chk, "c*c*cC*z", "nF")
BUILTIN(__builtin___strncat_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___strncpy_chk, "c*c*cC*zz", "nF")
+BUILTIN(__builtin___stpncpy_chk, "c*c*cC*zz", "nF")
BUILTIN(__builtin___snprintf_chk, "ic*zizcC*.", "Fp:4:")
BUILTIN(__builtin___sprintf_chk, "ic*izcC*.", "Fp:3:")
BUILTIN(__builtin___vsnprintf_chk, "ic*zizcC*a", "FP:4:")
@@ -346,12 +348,9 @@ BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:")
BUILTIN(__builtin_expect, "LiLiLi" , "nc")
BUILTIN(__builtin_prefetch, "vvC*.", "nc")
-BUILTIN(__builtin_abort, "v", "Fnr")
BUILTIN(__builtin_trap, "v", "nr")
BUILTIN(__builtin_unreachable, "v", "nr")
-
BUILTIN(__builtin_shufflevector, "v." , "nc")
-
BUILTIN(__builtin_alloca, "v*z" , "n")
// "Overloaded" Atomic operator builtins. These are overloaded to support data
@@ -473,6 +472,13 @@ BUILTIN(__sync_fetch_and_max, "ii*i", "n")
BUILTIN(__sync_fetch_and_umin, "UiUi*Ui", "n")
BUILTIN(__sync_fetch_and_umax, "UiUi*Ui", "n")
+// Random libc builtins.
+BUILTIN(__builtin_abort, "v", "Fnr")
+BUILTIN(__builtin_index, "c*cC*i", "Fn")
+BUILTIN(__builtin_rindex, "c*cC*i", "Fn")
+
+
+
// C99 library functions
// C99 stdlib.h
LIBBUILTIN(abort, "v", "fr", "stdlib.h")
diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
index 817a032d9237..287bba96df25 100644
--- a/include/clang/Basic/BuiltinsPPC.def
+++ b/include/clang/Basic/BuiltinsPPC.def
@@ -18,7 +18,97 @@
// The format of this database matches clang/Basic/Builtins.def.
// This is just a placeholder, the types and attributes are wrong.
-BUILTIN(__builtin_altivec_abs_v4sf , "ii" , "nc")
+BUILTIN(__builtin_altivec_abs_v16qi, "V16UcV16Sc", "")
+BUILTIN(__builtin_altivec_abs_v8hi, "V8UsV8Ss", "")
+BUILTIN(__builtin_altivec_abs_v4si, "V4UiV4Si", "")
+
+BUILTIN(__builtin_altivec_abss_v16qi, "V16UcV16Sc", "")
+BUILTIN(__builtin_altivec_abss_v8hi, "V8UsV8Ss", "")
+BUILTIN(__builtin_altivec_abss_v4si, "V4UiV4Si", "")
+
+BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vaddsbs, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vaddubs, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vavgsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vavguh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vavgsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vavguw, "V4UiV4UiV4Ui", "")
+
+BUILTIN(__builtin_altivec_stvx, "vV4iiv*", "")
+BUILTIN(__builtin_altivec_stvxl, "vV4iiv*", "")
+BUILTIN(__builtin_altivec_stvebx, "vV16civ*", "")
+BUILTIN(__builtin_altivec_stvehx, "vV8siv*", "")
+BUILTIN(__builtin_altivec_stvewx, "vV4iiv*", "")
+
+BUILTIN(__builtin_altivec_vcmpbfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vcmpgtub, "V16cV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vmaxub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mfvscr, "V8Us", "")
+
+BUILTIN(__builtin_altivec_vminsb, "V16ScV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vminub, "V16UcV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "")
+
+BUILTIN(__builtin_altivec_mtvscr, "vV4i", "")
+
+BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "")
+BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "")
+BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "")
+BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "")
+
+BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "")
+BUILTIN(__builtin_altivec_vcmpgtub_p, "iiV16UcV16Uc", "")
+BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "")
+BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "")
+BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "")
+BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "")
+BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "")
+
// FIXME: Obviously incomplete.
#undef BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 5c75d3799bcb..a878dd1bd1a3 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -245,7 +245,7 @@ BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "")
BUILTIN(__builtin_ia32_mwait, "vUiUi", "")
BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "")
BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cc", "")
-BUILTIN(__builtin_ia32_palignr, "V1LLiV1LLiV1LLic", "")
+BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cc", "")
BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "")
BUILTIN(__builtin_ia32_storelv4si, "vV2i*V2LLi", "")
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index 57dd6967fc51..bf94af6cb60d 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -188,6 +188,9 @@ private:
bool ErrorsAsFatal; // Treat errors like fatal errors.
bool SuppressSystemWarnings; // Suppress warnings in system headers.
bool SuppressAllDiagnostics; // Suppress all diagnostics.
+ unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit.
+ unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
+ // 0 -> no limit.
ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
DiagnosticClient *Client;
@@ -211,9 +214,10 @@ private:
/// diagnostic that they follow.
Diagnostic::Level LastDiagLevel;
- unsigned NumDiagnostics; // Number of diagnostics reported
- unsigned NumErrors; // Number of diagnostics that are errors
-
+ unsigned NumWarnings; // Number of warnings reported
+ unsigned NumErrors; // Number of errors reported
+ unsigned NumErrorsSuppressed; // Number of errors suppressed
+
/// CustomDiagInfo - Information for uniquing and looking up custom diags.
diag::CustomDiagInfo *CustomDiagInfo;
@@ -270,6 +274,22 @@ public:
void setClient(DiagnosticClient* client) { Client = client; }
+ /// setErrorLimit - Specify a limit for the number of errors we should
+ /// emit before giving up. Zero disables the limit.
+ void setErrorLimit(unsigned Limit) { ErrorLimit = Limit; }
+
+ /// \brief Specify the maximum number of template instantiation
+ /// notes to emit along with a given diagnostic.
+ void setTemplateBacktraceLimit(unsigned Limit) {
+ TemplateBacktraceLimit = Limit;
+ }
+
+ /// \brief Retrieve the maximum number of template instantiation
+ /// nodes to emit along with a given diagnostic.
+ unsigned getTemplateBacktraceLimit() const {
+ return TemplateBacktraceLimit;
+ }
+
/// setIgnoreAllWarnings - When set to true, any unmapped warnings are
/// ignored. If this and WarningsAsErrors are both set, then this one wins.
void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }
@@ -324,8 +344,9 @@ public:
void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
assert(Diag < diag::DIAG_UPPER_LIMIT &&
"Can only map builtin diagnostics");
- assert((isBuiltinWarningOrExtension(Diag) || Map == diag::MAP_FATAL) &&
- "Cannot map errors!");
+ assert((isBuiltinWarningOrExtension(Diag) ||
+ (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
+ "Cannot map errors into warnings!");
setDiagnosticMappingInternal(Diag, Map, true);
}
@@ -338,7 +359,8 @@ public:
bool hasFatalErrorOccurred() const { return FatalErrorOccurred; }
unsigned getNumErrors() const { return NumErrors; }
- unsigned getNumDiagnostics() const { return NumDiagnostics; }
+ unsigned getNumErrorsSuppressed() const { return NumErrorsSuppressed; }
+ unsigned getNumWarnings() const { return NumWarnings; }
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
/// and level. If this is the first request for this diagnosic, it is
@@ -383,7 +405,18 @@ public:
/// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
/// ID is for an extension of some sort.
///
- static bool isBuiltinExtensionDiag(unsigned DiagID);
+ static bool isBuiltinExtensionDiag(unsigned DiagID) {
+ bool ignored;
+ return isBuiltinExtensionDiag(DiagID, ignored);
+ }
+
+ /// isBuiltinExtensionDiag - Determine whether the given built-in diagnostic
+ /// ID is for an extension of some sort. This also returns EnabledByDefault,
+ /// which is set to indicate whether the diagnostic is ignored by default (in
+ /// which case -pedantic enables it) or treated as a warning/error by default.
+ ///
+ static bool isBuiltinExtensionDiag(unsigned DiagID, bool &EnabledByDefault);
+
/// getWarningOptionForDiag - Return the lowest-level warning option that
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
@@ -473,7 +506,7 @@ private:
/// getDiagnosticMappingInfo - Return the mapping info currently set for the
/// specified builtin diagnostic. This returns the high bit encoding, or zero
/// if the field is completely uninitialized.
- unsigned getDiagnosticMappingInfo(diag::kind Diag) const {
+ diag::Mapping getDiagnosticMappingInfo(diag::kind Diag) const {
const DiagMappings &currentMappings = DiagMappingsStack.back();
return (diag::Mapping)((currentMappings[Diag/2] >> (Diag & 1)*4) & 15);
}
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 8e791c3422fc..88e7dc19aec5 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -13,6 +13,11 @@
let Component = "Common" in {
+// Basic.
+
+def fatal_too_many_errors
+ : Error<"too many errors emitted, stopping now">, DefaultFatal;
+
def note_previous_definition : Note<"previous definition is here">;
def note_previous_declaration : Note<"previous declaration is here">;
def note_previous_implicit_declaration : Note<
@@ -36,7 +41,7 @@ def err_expected_colon_after_setter_name : Error<
"must end with ':'">;
// Parse && Sema
-def err_no_declarators : Error<"declaration does not declare anything">;
+def ext_no_declarators : ExtWarn<"declaration does not declare anything">;
def err_param_redefinition : Error<"redefinition of parameter %0">;
def err_invalid_storage_class_in_func_decl : Error<
"invalid storage class specifier in function declarator">;
@@ -67,5 +72,6 @@ def err_target_invalid_feature : Error<"invalid target feature '%0'">;
def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal;
def err_file_modified : Error<
"file '%0' modified since it was first processed">, DefaultFatal;
-
+def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but "
+ "encoding is not supported">, DefaultFatal;
}
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 3dbe47f4cf54..3b7272e5acc5 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -94,5 +94,7 @@ def warn_drv_conflicting_deployment_targets : Warning<
def warn_drv_treating_input_as_cxx : Warning<
"treating '%0' input as '%1' when in C++ mode, this behavior is deprecated">,
InGroup<Deprecated>;
+def warn_drv_objc_gc_unsupported : Warning<
+ "Objective-C garbage collection is not supported on this platform, ignoring '%0'">;
}
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 2e0b4bad6b5b..b73103067017 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -14,7 +14,10 @@ def err_fe_error_reading : Error<"error reading '%0'">;
def err_fe_error_reading_stdin : Error<"error reading stdin">;
def err_fe_error_backend : Error<"error in backend: %0">, DefaultFatal;
def err_fe_invalid_ast_file : Error<"invalid AST file: '%0'">, DefaultFatal;
-def err_fe_invalid_ast_action : Error<"invalid action for AST input">, DefaultFatal;
+def err_fe_invalid_ast_action : Error<"invalid action for AST input">,
+ DefaultFatal;
+def err_fe_inline_asm : Error<"%0">; // Error generated by the backend.
+def note_fe_inline_asm_here : Note<"generated from here">;
def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
@@ -69,12 +72,12 @@ def err_fe_pth_file_has_no_source_header : Error<
def warn_fe_macro_contains_embedded_newline : Warning<
"macro '%0' contains embedded newline, text after the newline is ignored.">;
-def err_verify_bogus_characters : Error<
- "bogus characters before '{{' in expected string">;
def err_verify_missing_start : Error<
- "cannot find start ('{{') of expected string">;
+ "cannot find start ('{{') of expected %0">;
def err_verify_missing_end : Error<
- "cannot find end ('}}') of expected string">;
+ "cannot find end ('}}') of expected %0">;
+def err_verify_invalid_content : Error<
+ "invalid expected %0: %1">;
def err_verify_inconsistent_diags : Error<
"'%0' diagnostics %select{expected|seen}1 but not %select{seen|expected}1: %2">;
@@ -120,12 +123,18 @@ 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_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">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index b0c016bbfd28..c74a48c445fe 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -108,6 +108,7 @@ def : DiagGroup<"type-limits">;
def Uninitialized : DiagGroup<"uninitialized">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def UnusedArgument : DiagGroup<"unused-argument">;
+def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">;
def UnusedFunction : DiagGroup<"unused-function">;
def UnusedLabel : DiagGroup<"unused-label">;
def UnusedParameter : DiagGroup<"unused-parameter">;
@@ -138,7 +139,8 @@ def Conversion : DiagGroup<"conversion",
def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
- UnusedParameter, UnusedValue, UnusedVariable]>;
+ // UnusedParameter, (matches GCC's behavior)
+ UnusedValue, UnusedVariable]>;
// Format settings.
def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull]>;
@@ -156,23 +158,22 @@ def Extra : DiagGroup<"extra", [
]>;
def Most : DiagGroup<"most", [
+ CharSubscript,
Comment,
Format,
Implicit,
MismatchedTags,
MissingBraces,
MultiChar,
+ Reorder,
ReturnType,
Switch,
Trigraphs,
Uninitialized,
UnknownPragmas,
- UnusedValue,
- UnusedVariable,
+ Unused,
VectorConversions,
- VolatileRegisterVar,
- Reorder,
- CharSubscript
+ VolatileRegisterVar
]>;
// -Wall is -Wmost -Wparentheses
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 3e0956fb9460..27958515462a 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -190,7 +190,9 @@ def err_objc_missing_end : Error<"missing @end">;
def warn_objc_protocol_qualifier_missing_id : Warning<
"protocol qualifiers without 'id' is archaic">;
def err_objc_unknown_at : Error<"expected an Objective-C directive after '@'">;
-
+def err_illegal_super_cast : Error<
+ "cannot cast 'super' (it isn't an expression)">;
+
def err_objc_illegal_visibility_spec : Error<
"illegal visibility specification">;
def err_objc_illegal_interface_qual : Error<"illegal interface qualifier">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index b66d6cc6e5a3..93ab85806540 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -85,6 +85,8 @@ def warn_unused_parameter : Warning<"unused parameter %0">,
InGroup<UnusedParameter>, DefaultIgnore;
def warn_unused_variable : Warning<"unused variable %0">,
InGroup<UnusedVariable>, DefaultIgnore;
+def warn_unused_exception_param : Warning<"unused exception parameter %0">,
+ InGroup<UnusedExceptionParameter>, DefaultIgnore;
def warn_decl_in_param_list : Warning<
"declaration of %0 will not be visible outside of this function">;
def err_array_star_in_function_definition : Error<
@@ -215,7 +217,8 @@ def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">;
def err_statically_allocated_object : Error<
"interface type cannot be statically allocated">;
def err_object_cannot_be_passed_returned_by_value : Error<
- "interface type %1 cannot be %select{returned|passed}0 by value">;
+ "interface type %1 cannot be %select{returned|passed}0 by value"
+ "; did you forget * in %1">;
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
def warn_pragma_pack_invalid_alignment : Warning<
"expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">;
@@ -237,6 +240,8 @@ def err_duplicate_class_def : Error<
"duplicate interface definition for class %0">;
def err_undef_superclass : Error<
"cannot find interface declaration for %0, superclass of %1">;
+def err_no_nsconstant_string_class : Error<
+ "cannot find interface declaration for %0">;
def err_recursive_superclass : Error<
"trying to recursively use %0 as superclass of %1">;
def warn_previous_alias_decl : Warning<"previously declared alias is ignored">;
@@ -296,7 +301,7 @@ def warn_implements_nscopying : Warning<
def warn_multiple_method_decl : Warning<"multiple methods named %0 found">;
def warn_accessor_property_type_mismatch : Warning<
"type of property %0 does not match type of accessor %1">;
-def note_declared_at : Note<"declared at">;
+def note_declared_at : Note<"declared here">;
def err_setter_type_void : Error<"type of setter must be void">;
def err_duplicate_method_decl : Error<"duplicate declaration of method %0">;
def warn_missing_atend : Warning<"'@end' is missing in implementation context">;
@@ -322,8 +327,8 @@ def warn_atomic_property_rule : Warning<
"writable atomic property %0 cannot pair a synthesized setter/getter "
"with a user defined setter/getter">;
def err_use_continuation_class : Error<
- "property declaration in continuation class of %0 is to change a 'readonly' "
- "property to 'readwrite'">;
+ "illegal declaration of property in continuation class %0"
+ ": attribute must be readwrite, while its primary must be readonly">;
def err_continuation_class : Error<"continuation class has no primary class">;
def err_property_type : Error<"property cannot have array or function type %0">;
def error_missing_property_context : Error<
@@ -381,11 +386,13 @@ def err_static_assert_failed : Error<"static_assert failed \"%0\"">;
def err_unexpected_friend : Error<
"friends can only be classes or functions">;
-def err_enum_friend : Error<
- "enum types cannot be friends">;
+def ext_enum_friend : ExtWarn<
+ "enumeration type %0 cannot be a friend">;
+def ext_nonclass_type_friend : ExtWarn<
+ "non-class type %0 cannot be a friend">;
def err_friend_is_member : Error<
"friends cannot be members of the declaring class">;
-def err_unelaborated_friend_type : Error<
+def ext_unelaborated_friend_type : ExtWarn<
"must specify '%select{struct|union|class|enum}0' to befriend %1">;
def err_qualified_friend_not_found : Error<
"no function named %0 with type %1 was found in the specified scope">;
@@ -399,6 +406,9 @@ 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<
"allocation of an object of abstract type %0">;
+def err_throw_abstract_type : Error<
+ "cannot throw an object of abstract type %0">;
+def err_array_of_abstract_type : Error<"array of abstract class type %0">;
def err_multiple_final_overriders : Error<
"virtual function %q0 has more than one final overrider in %1">;
@@ -448,11 +458,20 @@ def warn_missing_exception_specification : Warning<
// C++ access checking
def err_class_redeclared_with_different_access : Error<
"%0 redeclared with '%1' access">;
-def err_access :
- Error<"%1 is a %select{private|protected}0 member of %3">,
- NoSFINAE;
-def err_access_ctor :
- Error<"calling a %select{private|protected}0 constructor of class %2">,
+def err_access : Error<
+ "%1 is a %select{private|protected}0 member of %3">, NoSFINAE;
+def err_access_ctor : Error<
+ "calling a %select{private|protected}0 constructor of class %2">, NoSFINAE;
+def err_access_base : Error<
+ "%select{base class|inherited virtual base class}0 %1 has %select{private|"
+ "protected}3 %select{constructor|copy constructor|copy assignment operator|"
+ "destructor}2">, NoSFINAE;
+def err_access_field: Error<
+ "field of type %0 has %select{private|protected}2 %select{constructor|copy "
+ "constructor|copy assignment operator|destructor}1">, NoSFINAE;
+
+def err_access_ctor_field :
+ Error<"field of type %1 has %select{private|protected}2 constructor">,
NoSFINAE;
def err_access_dtor_base :
Error<"base class %0 has %select{private|protected}1 destructor">,
@@ -461,6 +480,9 @@ def err_access_dtor_vbase :
Error<"inherited virtual base class %0 has "
"%select{private|protected}1 destructor">,
NoSFINAE;
+def err_access_dtor_temp :
+ Error<"temporary of type %0 has %select{private|protected}1 destructor">,
+ NoSFINAE;
def err_access_dtor_field :
Error<"field of type %1 has %select{private|protected}2 destructor">,
NoSFINAE;
@@ -494,6 +516,9 @@ def note_access_constrained_by_path : Note<
// C++ name lookup
def err_incomplete_nested_name_spec : Error<
"incomplete type %0 named in nested name specifier">;
+def err_dependent_nested_name_spec : Error<
+ "nested name specifier for a declaration cannot depend on a template "
+ "parameter">;
def err_nested_name_member_ref_lookup_ambiguous : Error<
"lookup of %0 in member access expression is ambiguous">;
def note_ambig_member_ref_object_type : Note<
@@ -542,6 +567,8 @@ def err_non_virtual_pure : Error<
def err_implicit_object_parameter_init : Error<
"cannot initialize object parameter of type %0 with an expression "
"of type %1">;
+def err_qualified_member_of_unrelated : Error<
+ "%q0 is not a member of class %1">;
def note_field_decl : Note<"member is declared here">;
def note_ivar_decl : Note<"ivar is declared here">;
@@ -592,6 +619,7 @@ def err_covariant_return_type_class_type_more_qualified : Error<
"return type of virtual function %0 is not covariant with the return type of "
"the function it overrides (class type %1 is more qualified than class "
"type %2">;
+
// C++ constructors
def err_constructor_cannot_be : Error<"constructor cannot be declared '%0'">;
def err_invalid_qualified_constructor : Error<
@@ -601,6 +629,11 @@ def err_constructor_return_type : Error<
def err_constructor_redeclared : Error<"constructor cannot be redeclared">;
def err_constructor_byvalue_arg : Error<
"copy constructor must pass its first argument by reference">;
+def warn_no_constructor_for_refconst : Warning<
+ "%select{struct|union|class|enum}0 %1 does not declare any constructor to "
+ "initialize its non-modifiable members">;
+def note_refconst_member_not_initialized : Note<
+ "%select{const|reference}0 member %1 will never be initialized">;
// C++ destructors
def err_destructor_not_member : Error<
@@ -678,18 +711,23 @@ def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
InGroup<DiagGroup<"uninitialized">>;
def err_temp_copy_no_viable : Error<
- "no viable copy constructor %select{copying variable|copying parameter|"
+ "no viable constructor %select{copying variable|copying parameter|"
"returning object|throwing object|copying member subobject|copying array "
- "element}0 of type %1">;
+ "element|allocating object|copying temporary|initializing base subobject|"
+ "initializing vector element}0 of type %1">;
def err_temp_copy_ambiguous : Error<
- "ambiguous copy constructor call when %select{copying variable|copying "
+ "ambiguous constructor call when %select{copying variable|copying "
"parameter|returning object|throwing object|copying member subobject|copying "
- "array element}0 of type %1">;
+ "array element|allocating object|copying temporary|initializing base subobject|"
+ "initializing vector element}0 of type %1">;
def err_temp_copy_deleted : Error<
"%select{copying variable|copying parameter|returning object|throwing "
- "object|copying member subobject|copying array element}0 of type %1 invokes "
- "deleted copy constructor">;
-
+ "object|copying member subobject|copying array element|allocating object|"
+ "copying temporary|initializing base subobject|initializing vector element}0 "
+ "of type %1 invokes deleted constructor">;
+def err_temp_copy_incomplete : Error<
+ "copying a temporary object of incomplete type %0">;
+
// C++0x decltype
def err_cannot_determine_declared_type_of_overloaded_function : Error<
"cannot determine the %select{type|declared type}0 of an overloaded "
@@ -1116,9 +1154,13 @@ def err_member_call_without_object : Error<
"call to non-static member function without an object argument">;
// C++ Address of Overloaded Function
+def err_addr_ovl_no_viable : Error<
+ "address of overloaded function %0 does not match required type %1">;
def err_addr_ovl_ambiguous : Error<
"address of overloaded function %0 is ambiguous">;
-
+def err_addr_ovl_not_func_ptrref : Error<
+ "address of overloaded function %0 cannot be converted to type %1">;
+
// C++ Template Declarations
def err_template_param_shadow : Error<
"declaration of %0 shadows template parameter">;
@@ -1178,6 +1220,8 @@ def err_template_decl_ref : Error<
"cannot refer to class template %0 without a template argument list">;
// C++ Template Argument Lists
+def err_template_missing_args : Error<
+ "use of class template %0 requires template arguments">;
def err_template_arg_list_different_arity : Error<
"%select{too few|too many}0 template arguments for "
"%select{class template|function template|template template parameter"
@@ -1231,9 +1275,6 @@ def err_template_arg_no_ref_bind : Error<
def err_template_arg_ref_bind_ignores_quals : Error<
"reference binding of non-type template parameter of type %0 to template "
"argument of type %1 ignores qualifiers">;
-def err_template_arg_unresolved_overloaded_function : Error<
- "overloaded function cannot be resolved to a non-type template parameter of "
- "type %0">;
def err_template_arg_not_decl_ref : Error<
"non-type template argument does not refer to any declaration">;
def err_template_arg_not_object_or_func_form : Error<
@@ -1414,7 +1455,10 @@ def note_prior_template_arg_substitution : Note<
" template parameter%1 %2">;
def note_template_default_arg_checking : Note<
"while checking a default template argument used here">;
-
+def note_instantiation_contexts_suppressed : Note<
+ "(skipping %0 context%s0 in backtrace; use -ftemplate-backtrace-limit=0 to "
+ "see all)">;
+
def err_field_instantiates_to_function : Error<
"data member instantiated with function type %0">;
def err_nested_name_spec_non_tag : Error<
@@ -1551,6 +1595,14 @@ def err_redefinition_different_kind : Error<
"redefinition of %0 as different kind of symbol">;
def err_redefinition_different_typedef : Error<
"typedef redefinition with different types (%0 vs %1)">;
+def err_tag_reference_non_tag : Error<
+ "elaborated type refers to %select{a non-tag type|a typedef|a template}0">;
+def err_tag_reference_conflict : Error<
+ "implicit declaration introduced by elaborated type conflicts with "
+ "%select{a declaration|a typedef|a template}0 of the same name">;
+def err_dependent_tag_decl : Error<
+ "%select{declaration|definition}0 of %select{struct|union|class|enum}1 "
+ "in a dependent scope">;
def err_tag_definition_of_typedef : Error<
"definition of type %0 conflicts with typedef of the same name">;
def err_conflicting_types : Error<"conflicting types for %0">;
@@ -1641,6 +1693,8 @@ 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_objc_class : Error<
+ "cannot initialize Objective-C class type %0">;
def err_implicit_empty_initializer : Error<
"initializer for aggregate with no elements requires explicit braces">;
def err_bitfield_has_negative_width : Error<
@@ -1649,9 +1703,18 @@ def err_anon_bitfield_has_negative_width : Error<
"anonymous bit-field has negative width (%0)">;
def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">;
def err_bitfield_width_exceeds_type_size : Error<
- "size of bit-field %0 exceeds size of its type (%1 bits)">;
+ "size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)">;
def err_anon_bitfield_width_exceeds_type_size : Error<
- "size of anonymous bit-field exceeds size of its type (%0 bits)">;
+ "size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">;
+
+// Used by C++ which allows bit-fields that are wider than the type.
+def warn_bitfield_width_exceeds_type_size: Warning<
+ "size of bit-field %0 (%1 bits) exceeds the size of its type; value will be "
+ "truncated to %2 bits">;
+def warn_anon_bitfield_width_exceeds_type_size : Warning<
+ "size of anonymous bit-field (%0 bits) exceeds size of its type; value will "
+ "be truncated to %1 bits">;
+
def warn_missing_braces : Warning<
"suggest braces around initialization of subobject">,
InGroup<DiagGroup<"missing-braces">>, DefaultIgnore;
@@ -1758,6 +1821,7 @@ def ext_offsetof_extended_field_designator : Extension<
"using extended field designator is an extension">;
def warn_offsetof_non_pod_type : ExtWarn<"offset of on non-POD type %0">,
InGroup<InvalidOffsetof>;
+def err_offsetof_bitfield : Error<"cannot compute offset of bit-field %0">;
def warn_floatingpoint_eq : Warning<
"comparing floating point with == or != is unsafe">,
@@ -1773,6 +1837,8 @@ def warn_precedence_bitwise_rel : Warning<
InGroup<Parentheses>;
def note_precedence_bitwise_first : Note<
"place parentheses around the %0 expression to evaluate it first">;
+def note_precedence_bitwise_silence : Note<
+ "place parentheses around the %0 expression to silence this warning">;
def err_sizeof_nonfragile_interface : Error<
"invalid application of '%select{alignof|sizeof}1' to interface %0 in "
@@ -1807,9 +1873,9 @@ def err_typecheck_member_reference_arrow : Error<
def err_typecheck_member_reference_suggestion : Error<
"member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?">;
def err_typecheck_member_reference_type : Error<
- "cannot refer to type member %0 with '%select{.|->}1'">;
+ "cannot refer to type member %0 in %1 with '%select{.|->}2'">;
def err_typecheck_member_reference_unknown : Error<
- "cannot refer to member %0 with '%select{.|->}1'">;
+ "cannot refer to member %0 in %1 with '%select{.|->}2'">;
def err_member_reference_needs_call : Error<
"base of member reference has function type %0; perhaps you meant to call "
"this function with '()'?">;
@@ -1835,6 +1901,8 @@ def err_out_of_line_declaration : Error<
def note_member_def_close_match : Note<"member declaration nearly matches">;
def err_typecheck_ivar_variable_size : Error<
"instance variables must have a constant size">;
+def err_ivar_reference_type : Error<
+ "instance variables cannot be of reference type">;
def err_typecheck_illegal_increment_decrement : Error<
"cannot %select{decrement|increment}1 value of type %0">;
def err_typecheck_arithmetic_incomplete_type : Error<
@@ -2003,10 +2071,16 @@ def error_no_super_class : Error<
"no super class declared in @interface for %0">;
def err_invalid_receiver_to_message : Error<
"invalid receiver to message expression">;
+def err_invalid_receiver_to_message_super : Error<
+ "'super' is only valid in a method body">;
+def err_invalid_receiver_class_message : Error<
+ "receiver type %0 is not an Objective-C class">;
def warn_bad_receiver_type : Warning<
"receiver type %0 is not 'id' or interface pointer, consider "
"casting it to 'id'">;
def err_bad_receiver_type : Error<"bad receiver type %0">;
+def err_unknown_receiver_suggest : Error<
+ "unknown receiver %0; did you mean %1?">;
def error_objc_throw_expects_object : Error<
"@throw requires an Objective-C object type (%0 invalid)">;
def error_objc_synchronized_expects_object : Error<
@@ -2019,8 +2093,15 @@ def err_catch_param_not_objc_type : Error<
"@catch parameter is not a pointer to an interface type">;
def err_illegal_qualifiers_on_catch_parm : Error<
"illegal qualifiers on @catch parameter">;
-def err_illegal_super_cast : Error<
- "cannot cast 'super' (it isn't an expression)">;
+def err_storage_spec_on_catch_parm : Error<
+ "@catch parameter cannot have storage specifier %select{|'typedef'|'extern'|"
+ "'static'|'auto'|'register'|'__private_extern__'|'mutable'}0">;
+def warn_register_objc_catch_parm : Warning<
+ "'register' storage specifier on @catch parameter will be ignored">;
+def err_qualified_objc_catch_parm : Error<
+ "@catch parameter declarator cannot be qualified">;
+
+
def warn_setter_getter_impl_required : Warning<
"property %0 requires method %1 to be defined - "
"use @synthesize, @dynamic or provide a method implementation">;
@@ -2029,7 +2110,10 @@ def warn_setter_getter_impl_required_in_category : Warning<
"use @dynamic or provide a method implementation in category">;
def note_property_impl_required : Note<
"implementation is here">;
-
+def note_parameter_named_here : Note<
+ "passing argument to parameter %0 here">;
+def note_parameter_here : Note<
+ "passing argument to parameter here">;
// C++ casts
// These messages adhere to the TryCast pattern: %0 is an int specifying the
@@ -2099,6 +2183,8 @@ def err_new_incomplete_type : Error<
"allocation of incomplete type %0">;
def err_new_array_nonconst : Error<
"only the first dimension of an allocated array may have dynamic size">;
+def err_new_array_init_args : Error<
+ "array 'new' cannot have initialization arguments">;
def err_new_paren_array_nonconst : Error<
"when type is in parentheses, array cannot have dynamic size">;
def err_placement_new_non_placement_delete : Error<
@@ -2116,8 +2202,8 @@ def warn_delete_incomplete : Warning<
"deleting pointer to incomplete type %0 may cause undefined behaviour">;
def err_no_suitable_delete_member_function_found : Error<
"no suitable member %0 in %1">;
-def note_delete_member_function_declared_here : Note<
- "%0 declared here">;
+def note_member_declared_here : Note<
+ "member %0 declared here">;
def err_decrement_bool : Error<"cannot decrement expression of type bool">;
def warn_increment_bool : Warning<
"incrementing expression of type bool is deprecated">, InGroup<Deprecated>;
@@ -2132,6 +2218,8 @@ def err_qualified_catch_declarator : Error<
def err_early_catch_all : Error<"catch-all handler must come last">;
def err_bad_memptr_rhs : Error<
"right hand operand to %0 has non pointer-to-member type %1">;
+def err_memptr_rhs_to_incomplete : Error<
+ "cannot dereference pointer into incomplete class type %0">;
def err_bad_memptr_lhs : Error<
"left hand operand to %0 must be a %select{|pointer to }1class "
"compatible with the right hand operand, but is %2">;
@@ -2190,6 +2278,8 @@ def err_typecheck_deleted_function : Error<
"conversion function from %0 to %1 invokes a deleted function">;
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
+def err_missing_qualified_for_redecl : Error<
+ "must qualify the name %0 to declare %q1 in this scope">;
def err_invalid_declarator_scope : Error<
"definition or redeclaration of %0 not in a namespace enclosing %1">;
def err_invalid_declarator_global_scope : Error<
@@ -2213,6 +2303,8 @@ def warn_condition_is_idiomatic_assignment : Warning<"using the result "
InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore;
def note_condition_assign_to_comparison : Note<
"use '==' to turn this assignment into an equality comparison">;
+def note_condition_assign_silence : Note<
+ "place parentheses around the assignment to silence this warning">;
def warn_value_always_zero : Warning<
"%0 is always %select{zero|false|NULL}1 in this context">;
@@ -2221,53 +2313,91 @@ def warn_value_always_zero : Warning<
// In most of these diagnostics the %2 is a value from the
// Sema::AssignmentAction enumeration
def err_typecheck_convert_incompatible : Error<
- "incompatible type %select{assigning|passing|returning|converting|initializing|sending|casting}2"
- " %1, expected %0">;
-def err_typecheck_convert_ambiguous : Error<
- "ambiguity in initializing value of type %0 with initializer of type %1">;
-def err_cannot_initialize_decl_noname : Error<
- "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
- "of type %2">;
-def err_cannot_initialize_decl : Error<
- "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%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">;
def warn_incompatible_qualified_id : Warning<
- "incompatible type %select{assigning|passing|returning|converting|initializing|sending|casting}2"
- " %1, expected %0">;
+ "%select{assigning to|passing|returning|converting|initializing|sending|casting}2"
+ " %0 "
+ "%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">;
def ext_typecheck_convert_pointer_int : ExtWarn<
"incompatible pointer to integer conversion "
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">;
+ "%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">;
def ext_typecheck_convert_int_pointer : ExtWarn<
"incompatible integer to pointer conversion "
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">;
+ "%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">;
def ext_typecheck_convert_pointer_void_func : Extension<
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2"
- " %1 converts between void* and function pointer, expected %0">;
+ "%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 "
+ "converts between void pointer and function pointer">;
def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn<
- "pointer types point to integer types with different sign "
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">,
+ "%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 "
+ "converts between pointers to integer types with different sign">,
InGroup<DiagGroup<"pointer-sign">>;
def ext_typecheck_convert_incompatible_pointer : ExtWarn<
"incompatible pointer types "
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">;
+ "%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">;
def ext_typecheck_convert_discards_qualifiers : ExtWarn<
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2"
- " %1 discards qualifiers, expected %0">;
+ "%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">;
def ext_nested_pointer_qualifier_mismatch : ExtWarn<
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2,"
- " %0 and %1 have different qualifiers in nested pointer types">;
+ "%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">;
def warn_incompatible_vectors : Warning<
- "incompatible vector types %select{assigning|passing|returning|converting|initializing|sending|casting}2"
- " %1, expected %0">,
+ "incompatible vector types "
+ "%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<VectorConversions>, DefaultIgnore;
def err_int_to_block_pointer : Error<
- "invalid conversion "
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2"
- " integer %1, expected block pointer %0">;
-def err_typecheck_comparison_of_distinct_blocks : Error<
- "comparison of distinct block types (%0 and %1)">;
+ "invalid block 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">;
def err_typecheck_convert_incompatible_block_pointer : Error<
"incompatible block pointer types "
- "%select{assigning|passing|returning|converting|initializing|sending|casting}2 %1, expected %0">;
+ "%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">;
+
+def err_typecheck_convert_ambiguous : Error<
+ "ambiguity in initializing value of type %0 with initializer of type %1">;
+def err_cannot_initialize_decl_noname : Error<
+ "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 "
+ "of type %2">;
+def err_cannot_initialize_decl : Error<
+ "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2">;
+def err_typecheck_comparison_of_distinct_blocks : Error<
+ "comparison of distinct block types (%0 and %1)">;
def err_typecheck_array_not_modifiable_lvalue : Error<
"array type %0 is not assignable">;
@@ -2295,9 +2425,17 @@ 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 arguments to %select{function|block|method}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, "
+ "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 arguments to %select{function|block|method}0 call, "
+ "expected %1, have %2">;
+def err_typecheck_call_too_many_args_at_most : Error<
+ "too many arguments to %select{function|block|method}0 call, "
+ "expected at most %1, have %2">;
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<
@@ -2359,8 +2497,11 @@ def ext_typecheck_expression_not_constant_but_accepted : Extension<
InGroup<GNU>;
def warn_unused_expr : Warning<"expression result unused">,
InGroup<UnusedValue>;
+def warn_unused_voidptr : Warning<
+ "expression result unused; should this cast be to 'void'?">,
+ InGroup<UnusedValue>;
def warn_unused_property_expr : Warning<
- "property access result unused - getters should not have side effects">,
+ "property access result unused - getters should not be used for side effects">,
InGroup<UnusedValue>;
def warn_unused_call : Warning<
"ignoring return value of function declared with %0 attribute">,
@@ -2412,24 +2553,21 @@ def err_overload_incorrect_fntype : Error<
def err_only_constructors_take_base_inits : Error<
"only constructors take base initializers">;
-def error_multiple_mem_initialization : Error <
- "multiple initializations given for non-static member '%0'">;
-
-def error_multiple_base_initialization : Error <
+def err_multiple_mem_initialization : Error <
+ "multiple initializations given for non-static member %0">;
+def err_multiple_mem_union_initialization : Error <
+ "initializing multiple members of anonymous union">;
+def err_multiple_base_initialization : Error <
"multiple initializations given for base %0">;
def err_mem_init_not_member_or_class : Error<
"member initializer %0 does not name a non-static data member or base "
"class">;
-def warn_field_initialized : Warning<
- "member '%0' will be initialized after">,
- InGroup<Reorder>, DefaultIgnore;
-def warn_base_initialized : Warning<
- "base class %0 will be initialized after">,
+def warn_initializer_out_of_order : Warning<
+ "%select{field|base class}0 %1 will be initialized after "
+ "%select{field|base}2 %3">,
InGroup<Reorder>, DefaultIgnore;
-def note_fieldorbase_initialized_here : Note<
- "%select{field|base}0 %1">;
def err_base_init_does_not_name_class : Error<
"constructor initializer %0 does not name a class">;
@@ -2437,9 +2575,7 @@ def err_base_init_direct_and_virtual : Error<
"base class initializer %0 names both a direct base class and an "
"inherited virtual base class">;
def err_not_direct_base_or_virtual : Error<
- "type %0 is not a direct or virtual base of '%1'">;
-def err_not_direct_base_or_virtual_multi : Error<
- "type %0 is not a direct or virtual base of '%1'">;
+ "type %0 is not a direct or virtual base of %1">;
def err_in_class_initializer_non_integral_type : Error<
"in-class initializer has non-integral, non-enumeration type %0">;
@@ -2587,6 +2723,8 @@ def err_conv_function_to_array : Error<
"conversion function cannot convert to an array type">;
def err_conv_function_to_function : Error<
"conversion function cannot convert to a function type">;
+def err_conv_function_with_complex_decl : Error<
+ "must use a typedef to declare a conversion to %0">;
def err_conv_function_redeclared : Error<
"conversion function cannot be redeclared">;
def warn_conv_to_self_not_used : Warning<
@@ -2669,7 +2807,7 @@ def warn_selfcomparison : Warning<
"self-comparison always results in a constant value">;
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
- "unspecified (use strcmp instead)">;
+ "unspecified (use strncmp instead)">;
@@ -2698,7 +2836,7 @@ def err_default_not_in_switch : Error<
"'default' statement not in switch statement">;
def err_case_not_in_switch : Error<"'case' statement not in switch statement">;
def warn_bool_switch_condition : Warning<
- "switch condition is a bool">;
+ "switch condition has boolean value">;
def warn_case_value_overflow : Warning<
"overflow converting case value to switch condition type (%0 to %1)">,
InGroup<DiagGroup<"switch">>;
@@ -2770,22 +2908,15 @@ def err_vector_incorrect_num_initializers : Error<
"%select{too many|too few}0 elements in vector initialization (expected %1 elements, have %2)">;
def err_altivec_empty_initializer : Error<"expected initializer">;
-def err_stack_const_level : Error<
- "level argument for a stack address builtin must be constant">;
-
-def err_prefetch_invalid_arg_type : Error<
- "argument to __builtin_prefetch must be of integer type">;
-def err_prefetch_invalid_arg_ice : Error<
- "argument to __builtin_prefetch must be a constant integer">;
def err_argument_invalid_range : Error<
"argument should be a value from %0 to %1">;
-def err_object_size_invalid_argument : Error<
- "argument to __builtin_object_size must be a constant integer">;
-
def err_builtin_longjmp_invalid_val : Error<
"argument to __builtin_longjmp must be a constant 1">;
+def err_constant_integer_arg_type : Error<
+ "argument to %0 must be a constant integer">;
+
def ext_mixed_decls_code : Extension<
"ISO C90 forbids mixing declarations and code">;
def err_non_variable_decl_in_for : Error<
@@ -2834,9 +2965,9 @@ def warn_ivar_use_hidden : Warning<
def error_ivar_use_in_class_method : Error<
"instance variable %0 accessed in class method">;
def error_private_ivar_access : Error<"instance variable %0 is private">,
- NoSFINAE;
+ NoSFINAE;
def error_protected_ivar_access : Error<"instance variable %0 is protected">,
- NoSFINAE;
+ NoSFINAE;
def warn_maynot_respond : Warning<"%0 may not respond to %1">;
def warn_attribute_method_def : Warning<
"method attribute can only be specified on method declarations">;
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index fdf69d063f4d..1ed86f190af3 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -28,6 +28,7 @@ public:
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.
@@ -98,8 +99,13 @@ public:
unsigned ElideConstructors : 1; // Whether C++ copy constructors should be
// elided if possible.
unsigned CatchUndefined : 1; // Generate code to check for undefined ops.
- unsigned DumpVtableLayouts : 1; // Dump the layouts of all the emitted
- // vtables.
+ 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
+
+ // FIXME: This is just a temporary option, for testing purposes.
+ unsigned NoBitFieldTypeAlign : 1;
+
private:
unsigned GC : 2; // Objective-C Garbage Collection modes. We
// declare this enum as unsigned because MSVC
@@ -126,9 +132,10 @@ public:
LangOptions() {
Trigraphs = BCPLComment = Bool = DollarIdents = AsmPreprocessor = 0;
- GNUMode = ImplicitInt = Digraphs = 0;
+ GNUMode = GNUKeywords = ImplicitInt = Digraphs = 0;
HexFloats = 0;
GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0;
+ NoConstantCFStrings = 0;
C99 = Microsoft = CPlusPlus = CPlusPlus0x = 0;
CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0;
Exceptions = SjLjExceptions = Freestanding = NoBuiltin = 0;
@@ -155,7 +162,7 @@ public:
OverflowChecking = 0;
ObjCGCBitmapPrint = 0;
- InstantiationDepth = 500;
+ InstantiationDepth = 1024;
Optimize = 0;
OptimizeSize = 0;
@@ -169,7 +176,9 @@ public:
CharIsSigned = 1;
ShortWChar = 0;
CatchUndefined = 0;
- DumpVtableLayouts = 0;
+ DumpRecordLayouts = 0;
+ DumpVTableLayouts = 0;
+ NoBitFieldTypeAlign = 0;
}
GCMode getGCMode() const { return (GCMode) GC; }
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index 555e6f5a919a..0bbeffefc725 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -176,19 +176,14 @@ public:
/// FullSourceLoc - A SourceLocation and its associated SourceManager. Useful
/// for argument passing to functions that expect both objects.
class FullSourceLoc : public SourceLocation {
- SourceManager* SrcMgr;
+ const SourceManager *SrcMgr;
public:
/// Creates a FullSourceLoc where isValid() returns false.
- explicit FullSourceLoc() : SrcMgr((SourceManager*) 0) {}
+ explicit FullSourceLoc() : SrcMgr(0) {}
- explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM)
+ explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
: SourceLocation(Loc), SrcMgr(&SM) {}
- SourceManager &getManager() {
- assert(SrcMgr && "SourceManager is NULL.");
- return *SrcMgr;
- }
-
const SourceManager &getManager() const {
assert(SrcMgr && "SourceManager is NULL.");
return *SrcMgr;
diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h
index d1239694fc16..930fb52873eb 100644
--- a/include/clang/Basic/SourceManager.h
+++ b/include/clang/Basic/SourceManager.h
@@ -78,8 +78,13 @@ namespace SrcMgr {
/// \param Diag Object through which diagnostics will be emitted it 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(Diagnostic &Diag,
+ const SourceManager &SM,
+ SourceLocation Loc = SourceLocation(),
bool *Invalid = 0) const;
/// getSize - Returns the size of the content encapsulated by this
@@ -447,11 +452,17 @@ public:
/// getBuffer - Return the buffer for the specified FileID. If there is an
/// error opening this buffer the first time, this manufactures a temporary
/// buffer and returns a non-empty error string.
- const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
- return getSLocEntry(FID).getFile().getContentCache()->getBuffer(Diag,
- Invalid);
+ const llvm::MemoryBuffer *getBuffer(FileID FID, SourceLocation Loc,
+ bool *Invalid = 0) const {
+ return getSLocEntry(FID).getFile().getContentCache()
+ ->getBuffer(Diag, *this, Loc, Invalid);
}
+ const llvm::MemoryBuffer *getBuffer(FileID FID, bool *Invalid = 0) const {
+ return getSLocEntry(FID).getFile().getContentCache()
+ ->getBuffer(Diag, *this, SourceLocation(), Invalid);
+ }
+
/// getFileEntryForID - Returns the FileEntry record for the provided FileID.
const FileEntry *getFileEntryForID(FileID FID) const {
return getSLocEntry(FID).getFile().getContentCache()->Entry;
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index bc2cf198c3f5..19987508baf3 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -45,6 +45,7 @@ protected:
// Target values set by the ctor of the actual target implementation. Default
// values are specified by the TargetInfo constructor.
bool TLSSupported;
+ bool NoAsmVariants; // True if {|} are normal characters.
unsigned char PointerWidth, PointerAlign;
unsigned char IntWidth, IntAlign;
unsigned char FloatWidth, FloatAlign;
@@ -85,6 +86,14 @@ public:
protected:
IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType;
+
+ /// Control whether the alignment of bit-field types is respected when laying
+ /// out structures. If true, then the alignment of the bit-field type will be
+ /// used to (a) impact the alignment of the containing structure, and (b)
+ /// ensure that the individual bit-field will not straddle an alignment
+ /// boundary.
+ unsigned UseBitFieldTypeAlignment : 1;
+
public:
IntType getSizeType() const { return SizeType; }
IntType getIntMaxType() const { return IntMaxType; }
@@ -197,6 +206,10 @@ public:
return UserLabelPrefix;
}
+ bool useBitFieldTypeAlignment() const {
+ return UseBitFieldTypeAlignment;
+ }
+
/// getTypeName - Return the user string for the specified integer type enum.
/// For example, SignedShort -> "short".
static const char *getTypeName(IntType T);
@@ -326,6 +339,18 @@ public:
return "__DATA,__cfstring";
}
+ /// getNSStringSection - Return the section to use for NSString
+ /// literals, or 0 if no special section is used.
+ virtual const char *getNSStringSection() const {
+ return "__OBJC,__cstring_object,regular,no_dead_strip";
+ }
+
+ /// getNSStringNonFragileABISection - Return the section to use for
+ /// NSString literals, or 0 if no special section is used (NonFragile ABI).
+ virtual const char *getNSStringNonFragileABISection() const {
+ return "__DATA, __objc_stringobj, regular, no_dead_strip";
+ }
+
/// isValidSectionSpecifier - This is an optional hook that targets can
/// implement to perform semantic checking on attribute((section("foo")))
/// specifiers. In this case, "foo" is passed in to be checked. If the
@@ -402,6 +427,15 @@ public:
return TLSSupported;
}
+ /// hasNoAsmVariants - Return true if {|} are normal characters in the
+ /// asm string. If this returns false (the default), then {abc|xyz} is syntax
+ /// that says that when compiling for asm variant #0, "abc" should be
+ /// generated, but when compiling for asm variant #1, "xyz" should be
+ /// generated.
+ bool hasNoAsmVariants() const {
+ return NoAsmVariants;
+ }
+
/// getEHDataRegisterNumber - Return the register number that
/// __builtin_eh_return_regno would return with the specified argument.
virtual int getEHDataRegisterNumber(unsigned RegNo) const {
diff --git a/include/clang/Basic/Version.h b/include/clang/Basic/Version.h
index 2e0993ab52a1..b3b61841a8c3 100644
--- a/include/clang/Basic/Version.h
+++ b/include/clang/Basic/Version.h
@@ -18,11 +18,11 @@
#include "llvm/ADT/StringRef.h"
/// \brief Clang major version
-#define CLANG_VERSION_MAJOR 1
+#define CLANG_VERSION_MAJOR 2
// FIXME: Updates to this file must also update CMakeLists.txt and VER.
/// \brief Clang minor version
-#define CLANG_VERSION_MINOR 5
+#define CLANG_VERSION_MINOR 0
/// \brief Clang patchlevel version
// #define CLANG_VERSION_PATCHLEVEL 1
diff --git a/include/clang/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h
index 617034292638..5b65d52a9a96 100644
--- a/include/clang/Checker/BugReporter/BugReporter.h
+++ b/include/clang/Checker/BugReporter/BugReporter.h
@@ -458,7 +458,6 @@ public:
namespace bugreporter {
const Stmt *GetDerefExpr(const ExplodedNode *N);
-const Stmt *GetReceiverExpr(const ExplodedNode *N);
const Stmt *GetDenomExpr(const ExplodedNode *N);
const Stmt *GetCalleeExpr(const ExplodedNode *N);
const Stmt *GetRetValExpr(const ExplodedNode *N);
diff --git a/include/clang/Checker/PathSensitive/AnalysisManager.h b/include/clang/Checker/PathSensitive/AnalysisManager.h
index fdf52a7dc770..0c59d7b572a4 100644
--- a/include/clang/Checker/PathSensitive/AnalysisManager.h
+++ b/include/clang/Checker/PathSensitive/AnalysisManager.h
@@ -37,6 +37,8 @@ class AnalysisManager : public BugReporterData {
enum AnalysisScope { ScopeTU, ScopeDecl } AScope;
+ unsigned MaxNodes;
+
bool VisualizeEGDot;
bool VisualizeEGUbi;
bool PurgeDead;
@@ -55,12 +57,12 @@ public:
AnalysisManager(ASTContext &ctx, Diagnostic &diags,
const LangOptions &lang, PathDiagnosticClient *pd,
StoreManagerCreator storemgr,
- ConstraintManagerCreator constraintmgr,
+ ConstraintManagerCreator constraintmgr, unsigned maxnodes,
bool vizdot, bool vizubi, bool purge, bool eager, bool trim)
: Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd),
CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
- AScope(ScopeDecl),
+ AScope(ScopeDecl), MaxNodes(maxnodes),
VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge),
EagerlyAssume(eager), TrimGraph(trim) {}
@@ -104,6 +106,8 @@ public:
PD->FlushDiagnostics();
}
+ unsigned getMaxNodes() const { return MaxNodes; }
+
bool shouldVisualizeGraphviz() const { return VisualizeEGDot; }
bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; }
diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
index a3ff0dbedc7b..2d8afeeb0da6 100644
--- a/include/clang/Checker/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -239,31 +239,7 @@ public:
}
ExplodedNode* MakeNode(ExplodedNodeSet& Dst, Stmt* S, ExplodedNode* Pred,
- const GRState* St, ProgramPoint::Kind K) {
-
- const GRState* PredState = GetState(Pred);
-
- // If the state hasn't changed, don't generate a new node.
- if (!BuildSinks && St == PredState && Auditor == 0) {
- Dst.Add(Pred);
- return NULL;
- }
-
- ExplodedNode* N = generateNode(S, St, Pred, K);
-
- if (N) {
- if (BuildSinks)
- N->markAsSink();
- else {
- if (Auditor && Auditor->Audit(N, Mgr))
- N->markAsSink();
-
- Dst.Add(N);
- }
- }
-
- return N;
- }
+ const GRState* St, ProgramPoint::Kind K);
ExplodedNode* MakeSinkNode(ExplodedNodeSet& Dst, Stmt* S,
ExplodedNode* Pred, const GRState* St) {
@@ -273,7 +249,6 @@ public:
BuildSinks = Tmp;
return N;
}
-
};
class GRBranchNodeBuilder {
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
index 161cb28df033..f04ca75084b7 100644
--- a/include/clang/Checker/PathSensitive/GRExprEngine.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -87,6 +87,15 @@ class GRExprEngine : public GRSubEngine {
llvm::OwningPtr<GRTransferFuncs> TF;
+ class CallExprWLItem {
+ public:
+ CallExpr::arg_iterator I;
+ ExplodedNode *N;
+
+ CallExprWLItem(const CallExpr::arg_iterator &i, ExplodedNode *n)
+ : I(i), N(n) {}
+ };
+
public:
GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf);
@@ -333,6 +342,10 @@ public:
/// VisitReturnStmt - Transfer function logic for return statements.
void VisitReturnStmt(ReturnStmt* R, ExplodedNode* Pred, ExplodedNodeSet& Dst);
+
+ /// VisitOffsetOfExpr - Transfer function for offsetof.
+ void VisitOffsetOfExpr(OffsetOfExpr* Ex, ExplodedNode* Pred,
+ ExplodedNodeSet& Dst);
/// VisitSizeOfAlignOfExpr - Transfer function for sizeof.
void VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr* Ex, ExplodedNode* Pred,
@@ -352,6 +365,12 @@ public:
void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
+ void VisitCXXNewExpr(CXXNewExpr *CNE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ void VisitCXXDeleteExpr(CXXDeleteExpr *CDE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
@@ -363,6 +382,11 @@ public:
const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD,
const StackFrameContext *SFC);
+ /// Evaluate arguments with a work list algorithm.
+ void EvalArguments(ExprIterator AI, ExprIterator AE,
+ const FunctionProtoType *FnType,
+ ExplodedNode *Pred, ExplodedNodeSet &Dst);
+
/// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic
/// expressions of the form 'x != 0' and generate new nodes (stored in Dst)
/// with those assumptions.
diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
index 57ea8a3f6d9d..2ab3b420c313 100644
--- a/include/clang/Checker/PathSensitive/MemRegion.h
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -869,11 +869,11 @@ public:
/// getElementRegion - Retrieve the memory region associated with the
/// associated element type, index, and super region.
const ElementRegion *getElementRegion(QualType elementType, SVal Idx,
- const MemRegion *superRegion,
- ASTContext &Ctx);
+ const MemRegion *superRegion,
+ ASTContext &Ctx);
const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
- const MemRegion *superRegion) {
+ const MemRegion *superRegion) {
return getElementRegion(ER->getElementType(), ER->getIndex(),
superRegion, ER->getContext());
}
diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h
index 72565f4d740d..41d7c2bd713e 100644
--- a/include/clang/Checker/PathSensitive/Store.h
+++ b/include/clang/Checker/PathSensitive/Store.h
@@ -129,11 +129,14 @@ public:
CastResult(const GRState *s, const MemRegion* r = 0) : state(s), region(r){}
};
+ const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
+
/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
/// a MemRegion* to a specific location type. 'R' is the region being
/// casted and 'CastToTy' the result type of the cast.
const MemRegion *CastRegion(const MemRegion *region, QualType CastToTy);
+
/// EvalBinOp - Perform pointer arithmetic.
virtual SVal EvalBinOp(BinaryOperator::Opcode Op,
Loc lhs, NonLoc rhs, QualType resultTy) {
diff --git a/include/clang/Checker/PathSensitive/ValueManager.h b/include/clang/Checker/PathSensitive/ValueManager.h
index f80ad421742f..5a9d54d337b0 100644
--- a/include/clang/Checker/PathSensitive/ValueManager.h
+++ b/include/clang/Checker/PathSensitive/ValueManager.h
@@ -22,6 +22,7 @@
#include "clang/Checker/PathSensitive/BasicValueFactory.h"
#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SValuator.h"
+#include "clang/AST/ExprCXX.h"
namespace llvm { class BumpPtrAllocator; }
@@ -133,6 +134,11 @@ public:
I->getType()->isUnsignedIntegerType()));
}
+ nonloc::ConcreteInt makeIntVal(const CXXBoolLiteralExpr *E) {
+ return E->getValue() ? nonloc::ConcreteInt(BasicVals.getValue(1, 1, true))
+ : nonloc::ConcreteInt(BasicVals.getValue(0, 1, true));
+ }
+
nonloc::ConcreteInt makeIntVal(const llvm::APSInt& V) {
return nonloc::ConcreteInt(BasicVals.getValue(V));
}
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
index 638ed516ed0b..54d3ba03f3f0 100644
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -28,10 +28,17 @@ public:
OnlyAlwaysInlining // Only run the always inlining pass.
};
+ enum ObjCDispatchMethodKind {
+ Legacy = 0,
+ NonLegacy = 1,
+ Mixed = 2
+ };
+
unsigned AsmVerbose : 1; /// -dA, -fverbose-asm.
unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors.
unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
/// aliases to base ctors when possible.
+ unsigned DataSections : 1; /// Set when -fdata-sections is enabled
unsigned DebugInfo : 1; /// Should generate deubg info (-g).
unsigned DisableFPElim : 1; /// Set when -fomit-frame-pointer is enabled.
unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
@@ -39,12 +46,12 @@ public:
/// internal state before optimizations are
/// done.
unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
+ unsigned FunctionSections : 1; /// Set when -ffunction-sections is enabled
unsigned MergeAllConstants : 1; /// Merge identical constants.
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
unsigned NoZeroInitializedInBSS : 1; /// -fno-zero-initialized-in-bss
- unsigned ObjCLegacyDispatch: 1; /// Use legacy Objective-C dispatch, even with
- /// 2.0 runtime.
+ unsigned ObjCDispatchMethod : 2; /// Method of Objective-C dispatch to use.
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
unsigned OptimizeSize : 1; /// If -Os is specified.
unsigned SoftFloat : 1; /// -soft-float.
@@ -88,15 +95,17 @@ public:
AsmVerbose = 0;
CXAAtExit = 1;
CXXCtorDtorAliases = 0;
+ DataSections = 0;
DebugInfo = 0;
DisableFPElim = 0;
DisableLLVMOpts = 0;
DisableRedZone = 0;
+ FunctionSections = 0;
MergeAllConstants = 1;
NoCommon = 0;
NoImplicitFloat = 0;
NoZeroInitializedInBSS = 0;
- ObjCLegacyDispatch = 0;
+ ObjCDispatchMethod = Legacy;
OptimizationLevel = 0;
OptimizeSize = 0;
SoftFloat = 0;
@@ -109,6 +118,10 @@ public:
Inlining = NoInlining;
RelocationModel = "pic";
}
+
+ ObjCDispatchMethodKind getObjCDispatchMethod() const {
+ return ObjCDispatchMethodKind(ObjCDispatchMethod);
+ }
};
} // end namespace clang
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 124288a76305..18b54ef5e072 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -97,6 +97,8 @@ def analyzer_viz_egraph_graphviz : Flag<"-analyzer-viz-egraph-graphviz">,
HelpText<"Display exploded graph using GraphViz">;
def analyzer_viz_egraph_ubigraph : Flag<"-analyzer-viz-egraph-ubigraph">,
HelpText<"Display exploded graph using Ubigraph">;
+def analyzer_max_nodes : Separate<"-analyzer-max-nodes">,
+ HelpText<"The maximum number of nodes the analyzer can generate">;
//===----------------------------------------------------------------------===//
// CodeGen Options
@@ -123,6 +125,10 @@ def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
HelpText<"Do not emit code to make initialization of local statics thread safe">;
def fdump_vtable_layouts : Flag<"-fdump-vtable-layouts">,
HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">;
+def ffunction_sections : Flag<"-ffunction-sections">,
+ HelpText<"Place each function in its own section (ELF Only)">;
+def fdata_sections : Flag<"-fdata-sections">,
+ HelpText<"Place each data in its own section (ELF Only)">;
def masm_verbose : Flag<"-masm-verbose">,
HelpText<"Generate verbose assembly output">;
def mcode_model : Separate<"-mcode-model">,
@@ -192,6 +198,10 @@ def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">,
HelpText<"Print diagnostic name with mappable diagnostics">;
def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">,
HelpText<"Set the tab stop distance.">;
+def ferror_limit : Separate<"-ferror-limit">, MetaVarName<"<N>">,
+ HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">;
+def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">,
+ HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,
@@ -235,8 +245,6 @@ def x : Separate<"-x">, HelpText<"Input language type">;
def cxx_inheritance_view : Separate<"-cxx-inheritance-view">,
MetaVarName<"<class name>">,
HelpText<"View C++ inheritance for a specified class">;
-def fixit_at : Separate<"-fixit-at">, MetaVarName<"<source location>">,
- HelpText<"Perform Fix-It modifications at the given source location">;
def o : Separate<"-o">, MetaVarName<"<path>">, HelpText<"Specify output file">;
def load : Separate<"-load">, MetaVarName<"<dsopath>">,
HelpText<"Load the named plugin (dynamic shared object)">;
@@ -269,6 +277,8 @@ def fsyntax_only : Flag<"-fsyntax-only">,
HelpText<"Run parser and perform semantic analysis">;
def fixit : Flag<"-fixit">,
HelpText<"Apply fix-it advice to the input source">;
+def fixit_EQ : Joined<"-fixit=">,
+ HelpText<"Apply fix-it advice creating a file with the given suffix">;
def parse_print_callbacks : Flag<"-parse-print-callbacks">,
HelpText<"Run parser and print each callback invoked">;
def emit_html : Flag<"-emit-html">,
@@ -283,8 +293,6 @@ def ast_view : Flag<"-ast-view">,
HelpText<"Build ASTs and view them with GraphViz">;
def print_decl_contexts : Flag<"-print-decl-contexts">,
HelpText<"Print DeclContexts and their Decls">;
-def dump_record_layouts : Flag<"-dump-record-layouts">,
- HelpText<"Dump record layout information">;
def emit_pth : Flag<"-emit-pth">,
HelpText<"Generate pre-tokenized header file">;
def emit_pch : Flag<"-emit-pch">,
@@ -315,6 +323,14 @@ def print_stats : Flag<"-print-stats">,
def ftime_report : Flag<"-ftime-report">,
HelpText<"Print the amount of time each phase of compilation takes">;
+def fdump_record_layouts : Flag<"-fdump-record-layouts">,
+ HelpText<"Dump record layout information">;
+
+// Generic forwarding to LLVM options. This should only be used for debugging
+// and experimental features.
+def mllvm : Separate<"-mllvm">,
+ HelpText<"Additional arguments to forward to LLVM's option processing">;
+
//===----------------------------------------------------------------------===//
// Language Options
//===----------------------------------------------------------------------===//
@@ -323,10 +339,14 @@ def fno_builtin : Flag<"-fno-builtin">,
HelpText<"Disable implicit builtin knowledge of functions">;
def faltivec : Flag<"-faltivec">,
HelpText<"Enable AltiVec vector initializer syntax">;
-def faccess_control : Flag<"-faccess-control">,
- HelpText<"Enable C++ access control">;
+def fno_access_control : Flag<"-fno-access-control">,
+ HelpText<"Disable C++ access control">;
def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">,
HelpText<"Don't assume that C++'s global operator new can't alias any pointer">;
+def fgnu_keywords : Flag<"-fgnu-keywords">,
+ HelpText<"Allow GNU-extension keywords regardless of language standard">;
+def fno_gnu_keywords : Flag<"-fno-gnu-keywords">,
+ HelpText<"Disallow GNU-extension keywords regardless of language standard">;
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">,
HelpText<"Allow '$' in identifiers">;
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">,
@@ -365,12 +385,14 @@ def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">,
def fconstant_string_class : Separate<"-fconstant-string-class">,
MetaVarName<"<class name>">,
HelpText<"Specify the class to use for constant Objective-C string objects.">;
+def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">,
+ HelpText<"Enable creation of CodeFoundation-type constant strings">;
def fobjc_gc : Flag<"-fobjc-gc">,
HelpText<"Enable Objective-C garbage collection">;
def fobjc_gc_only : Flag<"-fobjc-gc-only">,
HelpText<"Use GC exclusively for Objective-C related memory management">;
-def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">,
- HelpText<"Use legacy dispatch with the Objective-C non-fragile ABI">;
+def fobjc_dispatch_method_EQ : Joined<"-fobjc-dispatch-method=">,
+ HelpText<"Objective-C dispatch method to use">;
def print_ivar_layout : Flag<"-print-ivar-layout">,
HelpText<"Enable Objective-C Ivar layout bitmap print trace">;
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">,
@@ -401,6 +423,8 @@ def trigraphs : Flag<"-trigraphs">,
HelpText<"Process trigraph sequences">;
def fwritable_strings : Flag<"-fwritable-strings">,
HelpText<"Store string literals as writable data">;
+def fno_bitfield_type_align : Flag<"-fno-bitfield-type-align">,
+ HelpText<"Ignore bit-field types when aligning structures">;
//===----------------------------------------------------------------------===//
// Header Search Options
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index ed68d68dd621..2127e5724f97 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -248,7 +248,7 @@ def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
def fcommon : Flag<"-fcommon">, Group<f_Group>;
def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
-def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<clang_ignored_f_Group>;
+def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<f_Group>;
def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
@@ -265,6 +265,10 @@ def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
def fhosted : Flag<"-fhosted">, Group<f_Group>;
def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
+
+def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>;
+def fasm : Flag<"-fasm">, Alias<fgnu_keywords>;
+
def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
@@ -300,6 +304,10 @@ def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
+
+def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, Group<f_Group>;
+def fno_asm : Flag<"-fno-asm">, Alias<fno_gnu_keywords>;
+
def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
@@ -321,6 +329,7 @@ def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>;
def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>;
def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
+def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>;
def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
@@ -356,7 +365,10 @@ def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<clang_ignored_f_Group>;
def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
+def ferror_limit_EQ : Joined<"-ferror-limit=">, Group<f_Group>;
def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
+def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">,
+ Group<f_Group>;
def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
diff --git a/include/clang/Driver/Tool.h b/include/clang/Driver/Tool.h
index 851e4235b00e..ef77206c6593 100644
--- a/include/clang/Driver/Tool.h
+++ b/include/clang/Driver/Tool.h
@@ -48,6 +48,10 @@ public:
virtual bool hasIntegratedAssembler() const { return false; }
virtual bool hasIntegratedCPP() const = 0;
+ /// \brief Does this tool have "good" standardized diagnostics, or should the
+ /// driver add an additional "command failed" diagnostic on failures.
+ virtual bool hasGoodDiagnostics() const { return false; }
+
/// ConstructJob - Construct jobs to perform the action \arg JA,
/// writing to \arg Output and with \arg Inputs.
///
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 9a82973dca27..1a8ae7749143 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -103,6 +103,10 @@ public:
/// ABI).
virtual bool IsObjCLegacyDispatchDefault() const { return false; }
+ /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
+ /// mixed dispatch method be used?
+ virtual bool UseObjCMixedDispatch() const { return false; }
+
/// GetDefaultStackProtectorLevel - Get the default stack protector level for
/// this tool chain (0=off, 1=on, 2=all).
virtual unsigned GetDefaultStackProtectorLevel() const { return 0; }
@@ -120,6 +124,9 @@ public:
/// particular PIC mode.
virtual const char *GetForcedPicModel() const = 0;
+ /// Does this tool chain support Objective-C garbage collection.
+ virtual bool SupportsObjCGC() const { return false; }
+
/// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf
/// compile unit information.
virtual bool UseDwarfDebugFlags() const { return false; }
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h
index b5b09f536d6e..9163a208de2e 100644
--- a/include/clang/Frontend/ASTConsumers.h
+++ b/include/clang/Frontend/ASTConsumers.h
@@ -57,10 +57,6 @@ ASTConsumer *CreateASTViewer();
// to stderr; this is intended for debugging.
ASTConsumer *CreateDeclContextPrinter();
-// RecordLayout dumper: prints out the record layout information for all records
-// in the translation unit; this is intended for debugging.
-ASTConsumer *CreateRecordLayoutDumper();
-
// ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code.
// This is considered experimental, and only works with Apple's ObjC runtime.
ASTConsumer *CreateObjCRewriter(const std::string &InFile,
diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def
index 287c67ebb7ef..aaa3920cee4f 100644
--- a/include/clang/Frontend/Analyses.def
+++ b/include/clang/Frontend/Analyses.def
@@ -15,22 +15,21 @@
#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
#endif
-ANALYSIS(CFGDump, "cfg-dump",
+ANALYSIS(CFGDump, "cfg-dump",
"Display Control-Flow Graphs", Code)
-ANALYSIS(CFGView, "cfg-view",
+ANALYSIS(CFGView, "cfg-view",
"View Control-Flow Graphs using GraphViz", Code)
ANALYSIS(DisplayLiveVariables, "dump-live-variables",
"Print results of live variable analysis", Code)
ANALYSIS(SecuritySyntacticChecks, "analyzer-check-security-syntactic",
- "Perform quick security checks that require no data flow",
- Code)
+ "Perform quick security checks that require no data flow", Code)
ANALYSIS(LLVMConventionChecker, "analyzer-check-llvm-conventions",
- "Check code for LLVM codebase conventions (domain-specific)",
- TranslationUnit)
+ "Check code for LLVM codebase conventions (domain-specific)",
+ TranslationUnit)
ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
"Warn about stores to dead variables", Code)
@@ -39,15 +38,15 @@ ANALYSIS(WarnUninitVals, "warn-uninit-values",
"Warn about uses of uninitialized variables", Code)
ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
- "Warn about Objective-C method signatures with type incompatibilities",
- ObjCImplementation)
+ "Warn about Objective-C method signatures with type incompatibilities",
+ ObjCImplementation)
ANALYSIS(WarnObjCDealloc, "analyzer-check-objc-missing-dealloc",
- "Warn about Objective-C classes that lack a correct implementation of -dealloc",
- ObjCImplementation)
+"Warn about Objective-C classes that lack a correct implementation of -dealloc",
+ ObjCImplementation)
ANALYSIS(WarnObjCUnusedIvars, "analyzer-check-objc-unused-ivars",
- "Warn about private ivars that are never used", ObjCImplementation)
+ "Warn about private ivars that are never used", ObjCImplementation)
ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
"Run the [Core] Foundation reference count checker", Code)
@@ -55,10 +54,6 @@ ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
"Warn about unintended use of sizeof() on pointer expressions", Code)
-ANALYSIS(InlineCall, "inline-call",
- "Experimental transfer function inling callees when its definition"
- " is available.", TranslationUnit)
-
#ifndef ANALYSIS_STORE
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
#endif
diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h
index f55e5dc04055..3341bb01f0fa 100644
--- a/include/clang/Frontend/AnalysisConsumer.h
+++ b/include/clang/Frontend/AnalysisConsumer.h
@@ -60,6 +60,7 @@ public:
AnalysisConstraints AnalysisConstraintsOpt;
AnalysisDiagClients AnalysisDiagOpt;
std::string AnalyzeSpecificFunction;
+ unsigned MaxNodes;
unsigned AnalyzeAll : 1;
unsigned AnalyzerDisplayProgress : 1;
unsigned AnalyzeNestedBlocks : 1;
diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h
index b37c18057f0f..797cb34023db 100644
--- a/include/clang/Frontend/DiagnosticOptions.h
+++ b/include/clang/Frontend/DiagnosticOptions.h
@@ -38,6 +38,9 @@ public:
/// binary serialization mechanism, to be
/// deserialized by, e.g., the CIndex library.
+ unsigned ErrorLimit; /// Limit # errors emitted.
+ unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
+
/// The distance between tab stops.
unsigned TabStop;
enum { DefaultTabStop = 8, MaxTabStop = 100 };
@@ -70,6 +73,8 @@ public:
ShowSourceRanges = 0;
VerifyDiagnostics = 0;
BinaryOutput = 0;
+ ErrorLimit = 0;
+ TemplateBacktraceLimit = 0;
}
};
diff --git a/include/clang/Frontend/FixItRewriter.h b/include/clang/Frontend/FixItRewriter.h
index fac87afadef2..b432d747de97 100644
--- a/include/clang/Frontend/FixItRewriter.h
+++ b/include/clang/Frontend/FixItRewriter.h
@@ -16,23 +16,24 @@
#define LLVM_CLANG_FRONTEND_FIX_IT_REWRITER_H
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Rewrite/Rewriter.h"
#include "llvm/ADT/SmallVector.h"
+namespace llvm { class raw_ostream; }
+
namespace clang {
class SourceManager;
class FileEntry;
-/// \brief Stores a source location in the form that it shows up on
-/// the Clang command line, e.g., file:line:column.
-///
-/// FIXME: Would prefer to use real SourceLocations, but I don't see a
-/// good way to resolve them during parsing.
-struct RequestedSourceLocation {
- const FileEntry *File;
- unsigned Line;
- unsigned Column;
+class FixItPathRewriter {
+public:
+ virtual ~FixItPathRewriter();
+
+ /// \brief This file is about to be rewritten. Return the name of the file
+ /// that is okay to write to.
+ virtual std::string RewriteFilename(const std::string &Filename) = 0;
};
class FixItRewriter : public DiagnosticClient {
@@ -47,38 +48,46 @@ class FixItRewriter : public DiagnosticClient {
/// of error messages.
DiagnosticClient *Client;
+ /// \brief Turn an input path into an output path. NULL implies overwriting
+ /// the original.
+ FixItPathRewriter *PathRewriter;
+
/// \brief The number of rewriter failures.
unsigned NumFailures;
- /// \brief Locations at which we should perform fix-its.
- ///
- /// When empty, perform fix-it modifications everywhere.
- llvm::SmallVector<RequestedSourceLocation, 4> FixItLocations;
-
public:
+ typedef Rewriter::buffer_iterator iterator;
+
/// \brief Initialize a new fix-it rewriter.
FixItRewriter(Diagnostic &Diags, SourceManager &SourceMgr,
- const LangOptions &LangOpts);
+ const LangOptions &LangOpts, FixItPathRewriter *PathRewriter);
/// \brief Destroy the fix-it rewriter.
~FixItRewriter();
- /// \brief Add a location where fix-it modifications should be
- /// performed.
- void addFixItLocation(RequestedSourceLocation Loc) {
- FixItLocations.push_back(Loc);
+ /// \brief Check whether there are modifications for a given file.
+ bool IsModified(FileID ID) const {
+ return Rewrite.getRewriteBufferFor(ID) != NULL;
}
- /// \brief Write the modified source file.
+ // Iteration over files with changes.
+ iterator buffer_begin() { return Rewrite.buffer_begin(); }
+ iterator buffer_end() { return Rewrite.buffer_end(); }
+
+ /// \brief Write a single modified source file.
+ ///
+ /// \returns true if there was an error, false otherwise.
+ bool WriteFixedFile(FileID ID, llvm::raw_ostream &OS);
+
+ /// \brief Write the modified source files.
///
/// \returns true if there was an error, false otherwise.
- bool WriteFixedFile(const std::string &InFileName,
- const std::string &OutFileName = std::string());
+ bool WriteFixedFiles();
/// 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.
+ /// returns true) indicates whether the diagnostics handled by this
+ /// DiagnosticClient should be included in the number of diagnostics
+ /// reported by Diagnostic.
virtual bool IncludeInDiagnosticCounts() const;
/// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index a7b6aa7e752f..3ddd77dc39e0 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -16,6 +16,7 @@
namespace clang {
class FixItRewriter;
+class FixItPathRewriter;
//===----------------------------------------------------------------------===//
// Custom Consumer Actions
@@ -73,15 +74,10 @@ protected:
llvm::StringRef InFile);
};
-class DumpRecordAction : public ASTFrontendAction {
-protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- llvm::StringRef InFile);
-};
-
class FixItAction : public ASTFrontendAction {
private:
llvm::OwningPtr<FixItRewriter> Rewriter;
+ llvm::OwningPtr<FixItPathRewriter> PathRewriter;
protected:
diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index ee3811a30b94..60512edd6c1f 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -24,7 +24,6 @@ namespace frontend {
ASTPrintXML, ///< Parse ASTs and print them in XML.
ASTView, ///< Parse ASTs and view them in Graphviz.
DumpRawTokens, ///< Dump out raw tokens.
- DumpRecordLayouts, ///< Dump record layout information.
DumpTokens, ///< Dump out preprocessed tokens.
EmitAssembly, ///< Emit a .s file.
EmitBC, ///< Emit a .bc file.
@@ -93,8 +92,8 @@ public:
/// If given, the name for a C++ class to view the inheritance of.
std::string ViewClassInheritance;
- /// A list of locations to apply fix-its at.
- std::vector<ParsedSourceLocation> FixItLocations;
+ /// If given, the new suffix for fix-it rewritten files.
+ std::string FixItSuffix;
/// If given, enable code completion at the provided location.
ParsedSourceLocation CodeCompletionAt;
@@ -111,6 +110,10 @@ public:
/// \brief The list of AST files to merge.
std::vector<std::string> ASTMergeFiles;
+ /// \brief A list of arguments to forward to LLVM's option processing; this
+ /// should only be used for debugging and experimental features.
+ std::vector<std::string> LLVMArgs;
+
public:
FrontendOptions() {
DebugCodeCompletionPrinter = 1;
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index f975c497bee9..1640afb4122a 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -453,7 +453,9 @@ namespace clang {
/// \brief Block extedned descriptor type for Blocks CodeGen
SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13,
/// \brief Objective-C "SEL" redefinition type
- SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14
+ SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14,
+ /// \brief NSConstantString type
+ SPECIAL_TYPE_NS_CONSTANT_STRING = 15
};
/// \brief Record codes for each kind of declaration.
@@ -601,6 +603,8 @@ namespace clang {
EXPR_PAREN,
/// \brief A UnaryOperator record.
EXPR_UNARY_OPERATOR,
+ /// \brief An OffsetOfExpr record.
+ EXPR_OFFSETOF,
/// \brief A SizefAlignOfExpr record.
EXPR_SIZEOF_ALIGN_OF,
/// \brief An ArraySubscriptExpr record.
diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h
index 73c1bf4cce5c..c2352301caa0 100644
--- a/include/clang/Frontend/PCHReader.h
+++ b/include/clang/Frontend/PCHReader.h
@@ -436,7 +436,7 @@ private:
std::deque<PendingIdentifierInfo> PendingIdentifierInfos;
/// \brief FIXME: document!
- llvm::SmallVector<uint64_t, 4> SpecialTypes;
+ llvm::SmallVector<uint64_t, 16> SpecialTypes;
/// \brief Contains declarations and definitions that will be
/// "interesting" to the ASTConsumer, when we get that AST consumer.
@@ -688,6 +688,9 @@ public:
Selector DecodeSelector(unsigned Idx);
+ virtual Selector GetSelector(uint32_t ID);
+ virtual uint32_t GetNumKnownSelectors();
+
Selector GetSelector(const RecordData &Record, unsigned &Idx) {
return DecodeSelector(Record[Idx++]);
}
diff --git a/include/clang/Frontend/StmtXML.def b/include/clang/Frontend/StmtXML.def
index 2f0da9e7b117..f63761a908af 100644
--- a/include/clang/Frontend/StmtXML.def
+++ b/include/clang/Frontend/StmtXML.def
@@ -254,7 +254,7 @@ NODE_XML(UnaryOperator, "UnaryOperator") // op(expr) or (expr)op
ENUM_XML(UnaryOperator::Real, "__real")
ENUM_XML(UnaryOperator::Imag, "__imag")
ENUM_XML(UnaryOperator::Extension, "__extension__")
- ENUM_XML(UnaryOperator::OffsetOf, "__builtin_offsetof")
+ ENUM_XML(UnaryOperator::OffsetOf, "__builtin_offsetof")
END_ENUM_XML
SUB_NODE_XML(Expr) // expr
END_NODE_XML
@@ -311,6 +311,13 @@ NODE_XML(ConditionalOperator, "ConditionalOperator") // expr1 ? expr2 : expr3
SUB_NODE_XML(Expr) // expr3
END_NODE_XML
+NODE_XML(OffsetOfExpr, "OffsetOfExpr") // offsetof(basetype, components)
+ ATTRIBUTE_FILE_LOCATION_XML
+ TYPE_ATTRIBUTE_XML(getTypeSourceInfo()->getType())
+ ATTRIBUTE_XML(getNumComponents(), "num_components")
+ SUB_NODE_SEQUENCE_XML(OffsetOfExpr::OffsetOfNode)
+END_NODE_XML
+
NODE_XML(SizeOfAlignOfExpr, "SizeOfAlignOfExpr") // sizeof(expr) or alignof(expr)
ATTRIBUTE_FILE_LOCATION_XML
TYPE_ATTRIBUTE_XML(getType())
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index 157876b59d34..336713661a28 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -68,7 +68,7 @@ public:
void EmitCaretDiagnostic(SourceLocation Loc,
SourceRange *Ranges, unsigned NumRanges,
- SourceManager &SM,
+ const SourceManager &SM,
const FixItHint *Hints,
unsigned NumHints,
unsigned Columns);
diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h
index 08adbb04d166..6f45e49ec0ef 100644
--- a/include/clang/Frontend/VerifyDiagnosticsClient.h
+++ b/include/clang/Frontend/VerifyDiagnosticsClient.h
@@ -25,7 +25,10 @@ class TextDiagnosticBuffer;
/// USING THE DIAGNOSTIC CHECKER:
///
/// Indicating that a line expects an error or a warning is simple. Put a
-/// comment on the line that has the diagnostic, use "expected-{error,warning}"
+/// comment on the line that has the diagnostic, use:
+///
+/// expected-{error,warning,note}
+///
/// to tag if it's an expected error or warning, and place the expected text
/// between {{ and }} markers. The full text doesn't have to be included, only
/// enough to ensure that the correct diagnostic was emitted.
@@ -45,6 +48,20 @@ class TextDiagnosticBuffer;
///
/// void f(); // expected-note 2 {{previous declaration is here}}
///
+/// Regex matching mode may be selected by appending '-re' to type. Example:
+///
+/// expected-error-re
+///
+/// Examples matching error: "variable has incomplete type 'struct s'"
+///
+/// // expected-error {{variable has incomplete type 'struct s'}}
+/// // expected-error {{variable has incomplete type}}
+///
+/// // expected-error-re {{variable has has type 'struct .'}}
+/// // expected-error-re {{variable has has type 'struct .*'}}
+/// // expected-error-re {{variable has has type 'struct (.*)'}}
+/// // expected-error-re {{variable has has type 'struct[[:space:]](.*)'}}
+///
class VerifyDiagnosticsClient : public DiagnosticClient {
public:
Diagnostic &Diags;
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index e891e94d4cbc..d74124e9c79b 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -44,6 +44,14 @@ public:
SrcMgr::CharacteristicKind FileType) {
}
+ /// FileSkipped - This callback is invoked whenever a source file is
+ /// skipped as the result of header guard optimization. ParentFile
+ /// is the file that #includes the skipped file. FilenameTok is the
+ /// token in ParentFile that indicates the skipped file.
+ virtual void FileSkipped(const FileEntry &ParentFile,
+ const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) {
+ }
/// EndOfMainFile - This callback is invoked when the end of the main file is
/// reach, no subsequent callbacks will be made.
@@ -96,6 +104,13 @@ public:
Second->FileChanged(Loc, Reason, FileType);
}
+ virtual void FileSkipped(const FileEntry &ParentFile,
+ const Token &FilenameTok,
+ SrcMgr::CharacteristicKind FileType) {
+ First->FileSkipped(ParentFile, FilenameTok, FileType);
+ Second->FileSkipped(ParentFile, FilenameTok, FileType);
+ }
+
virtual void EndOfMainFile() {
First->EndOfMainFile();
Second->EndOfMainFile();
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 312a760e01d3..20d9fc50e49f 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -366,17 +366,17 @@ public:
/// EnterMainSourceFile - Enter the specified FileID as the main source file,
/// which implicitly adds the builtin defines etc.
- bool EnterMainSourceFile();
+ void EnterMainSourceFile();
/// EndSourceFile - Inform the preprocessor callbacks that processing is
/// complete.
void EndSourceFile();
/// EnterSourceFile - Add a source file to the top of the include stack and
- /// start lexing tokens from it instead of the current buffer. Return true
- /// and fill in ErrorStr with the error information on failure.
- bool EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
- std::string &ErrorStr);
+ /// start lexing tokens from it instead of the current buffer. Emit an error
+ /// and don't enter the file on error.
+ void EnterSourceFile(FileID CurFileID, const DirectoryLookup *Dir,
+ SourceLocation Loc);
/// EnterMacro - Add a Macro to the top of the include stack and start lexing
/// tokens from it instead of the current buffer. Args specifies the
diff --git a/include/clang/Lex/TokenConcatenation.h b/include/clang/Lex/TokenConcatenation.h
index d759e47e57fc..094990a6e317 100644
--- a/include/clang/Lex/TokenConcatenation.h
+++ b/include/clang/Lex/TokenConcatenation.h
@@ -58,7 +58,9 @@ namespace clang {
public:
TokenConcatenation(Preprocessor &PP);
- bool AvoidConcat(const Token &PrevTok, const Token &Tok) const;
+ bool AvoidConcat(const Token &PrevPrevTok,
+ const Token &PrevTok,
+ const Token &Tok) const;
private:
/// StartsWithL - Return true if the spelling of this token starts with 'L'.
diff --git a/include/clang/Makefile b/include/clang/Makefile
index 624292a128ee..d76e0a9c63ba 100644
--- a/include/clang/Makefile
+++ b/include/clang/Makefile
@@ -2,3 +2,30 @@ LEVEL = ../../../..
DIRS := Basic Driver
include $(LEVEL)/Makefile.common
+
+install-local::
+ $(Echo) Installing Clang include files
+ $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir)
+ $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/clang/include/clang" ; then \
+ cd $(PROJ_SRC_ROOT)/tools/clang/include && \
+ for hdr in `find clang -type f '!' '(' -name '*~' \
+ -o -name '.#*' -o -name '*.in' -o -name '*.txt' \
+ -o -name 'Makefile' -o -name '*.td' ')' -print \
+ | grep -v CVS | grep -v .svn | grep -v .dir` ; do \
+ instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \
+ if test \! -d "$$instdir" ; then \
+ $(EchoCmd) Making install directory $$instdir ; \
+ $(MKDIR) $$instdir ;\
+ fi ; \
+ $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
+ done ; \
+ fi
+ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT))
+ $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang" ; then \
+ cd $(PROJ_OBJ_ROOT)/tools/clang/include && \
+ for hdr in `find clang -type f '!' '(' -name 'Makefile' ')' -print \
+ | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \
+ $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \
+ done ; \
+ fi
+endif
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index 59cc0d218cec..3d68d80ef9f0 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -205,7 +205,7 @@ public:
/// \returns the type referred to by this identifier, or NULL if the type
/// does not name an identifier.
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, const CXXScopeSpec *SS = 0,
+ Scope *S, CXXScopeSpec *SS = 0,
bool isClassName = false,
TypeTy *ObjectType = 0) = 0;
@@ -243,7 +243,7 @@ public:
virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
SourceLocation IILoc,
Scope *S,
- const CXXScopeSpec *SS,
+ CXXScopeSpec *SS,
TypeTy *&SuggestedType) {
return false;
}
@@ -281,7 +281,7 @@ public:
///
/// \returns the kind of template that this name refers to.
virtual TemplateNameKind isTemplateName(Scope *S,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &Name,
TypeTy *ObjectType,
bool EnteringContext,
@@ -329,7 +329,7 @@ public:
/// This actual is used in the parsing of pseudo-destructor names to
/// distinguish a nested-name-specifier and a "type-name ::" when we
/// see the token sequence "X :: ~".
- virtual bool isNonTypeNestedNameSpecifier(Scope *S, const CXXScopeSpec &SS,
+ virtual bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS,
SourceLocation IdLoc,
IdentifierInfo &II,
TypeTy *ObjectType) {
@@ -371,7 +371,7 @@ public:
///
/// \returns a CXXScopeTy* object representing the C++ scope.
virtual CXXScopeTy *ActOnCXXNestedNameSpecifier(Scope *S,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
SourceLocation IdLoc,
SourceLocation CCLoc,
IdentifierInfo &II,
@@ -387,7 +387,7 @@ public:
///
/// The arguments are the same as those passed to ActOnCXXNestedNameSpecifier.
virtual bool IsInvalidUnlessNestedName(Scope *S,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
IdentifierInfo &II,
TypeTy *ObjectType,
bool EnteringContext) {
@@ -428,7 +428,7 @@ public:
/// ActOnCXXExitDeclaratorScope is called.
/// The 'SS' should be a non-empty valid CXXScopeSpec.
/// \returns true if an error occurred, false otherwise.
- virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
+ virtual bool ActOnCXXEnterDeclaratorScope(Scope *S, CXXScopeSpec &SS) {
return false;
}
@@ -468,7 +468,11 @@ public:
virtual DeclPtrTy ActOnParamDeclarator(Scope *S, Declarator &D) {
return DeclPtrTy();
}
- virtual void ActOnObjCCatchParam(DeclPtrTy D) {
+
+ /// \brief Parsed an exception object declaration within an Objective-C
+ /// @catch statement.
+ virtual DeclPtrTy ActOnObjCExceptionDecl(Scope *S, Declarator &D) {
+ return DeclPtrTy();
}
/// AddInitializerToDecl - This action is called immediately after
@@ -576,8 +580,7 @@ public:
virtual DeclPtrTy ActOnStartLinkageSpecification(Scope *S,
SourceLocation ExternLoc,
SourceLocation LangLoc,
- const char *Lang,
- unsigned StrSize,
+ llvm::StringRef Lang,
SourceLocation LBraceLoc) {
return DeclPtrTy();
}
@@ -655,7 +658,7 @@ public:
///
/// \returns the declaration to which this tag refers.
virtual DeclPtrTy ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
- SourceLocation KWLoc, const CXXScopeSpec &SS,
+ SourceLocation KWLoc, CXXScopeSpec &SS,
IdentifierInfo *Name, SourceLocation NameLoc,
AttributeList *Attr, AccessSpecifier AS,
MultiTemplateParamsArg TemplateParameterLists,
@@ -938,20 +941,46 @@ public:
}
// Objective-c statements
+
+ /// \brief Parsed an Objective-C @catch statement.
+ ///
+ /// \param AtLoc The location of the '@' starting the '@catch'.
+ ///
+ /// \param RParen The location of the right parentheses ')' after the
+ /// exception variable.
+ ///
+ /// \param Parm The variable that will catch the exception. Will be NULL if
+ /// this is a @catch(...) block.
+ ///
+ /// \param Body The body of the @catch block.
virtual OwningStmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc,
SourceLocation RParen,
- DeclPtrTy Parm, StmtArg Body,
- StmtArg CatchList) {
+ DeclPtrTy Parm, StmtArg Body) {
return StmtEmpty();
}
+ /// \brief Parsed an Objective-C @finally statement.
+ ///
+ /// \param AtLoc The location of the '@' starting the '@finally'.
+ ///
+ /// \param Body The body of the @finally block.
virtual OwningStmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc,
StmtArg Body) {
return StmtEmpty();
}
+ /// \brief Parsed an Objective-C @try-@catch-@finally statement.
+ ///
+ /// \param AtLoc The location of the '@' starting '@try'.
+ ///
+ /// \param Try The body of the '@try' statement.
+ ///
+ /// \param CatchStmts The @catch statements.
+ ///
+ /// \param Finally The @finally statement.
virtual OwningStmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc,
- StmtArg Try, StmtArg Catch,
+ StmtArg Try,
+ MultiStmtArg CatchStmts,
StmtArg Finally) {
return StmtEmpty();
}
@@ -1049,7 +1078,7 @@ public:
/// id-expression or identifier was an ampersand ('&'), indicating that
/// we will be taking the address of this expression.
virtual OwningExprResult ActOnIdExpression(Scope *S,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &Name,
bool HasTrailingLParen,
bool IsAddressOfOperand) {
@@ -1127,7 +1156,7 @@ public:
virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &Member,
DeclPtrTy ObjCImpDecl,
bool HasTrailingLParen) {
@@ -1315,7 +1344,7 @@ public:
virtual DeclPtrTy ActOnUsingDirective(Scope *CurScope,
SourceLocation UsingLoc,
SourceLocation NamespcLoc,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
SourceLocation IdentLoc,
IdentifierInfo *NamespcName,
AttributeList *AttrList);
@@ -1326,7 +1355,7 @@ public:
SourceLocation NamespaceLoc,
SourceLocation AliasLoc,
IdentifierInfo *Alias,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
SourceLocation IdentLoc,
IdentifierInfo *Ident) {
return DeclPtrTy();
@@ -1372,7 +1401,7 @@ public:
AccessSpecifier AS,
bool HasUsingKeyword,
SourceLocation UsingLoc,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
bool IsTypeName,
@@ -1501,7 +1530,7 @@ public:
/// \returns the type being destructed.
virtual TypeTy *getDestructorName(SourceLocation TildeLoc,
IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, const CXXScopeSpec &SS,
+ Scope *S, CXXScopeSpec &SS,
TypeTy *ObjectType,
bool EnteringContext) {
return getTypeName(II, NameLoc, S, &SS, false, ObjectType);
@@ -1683,7 +1712,7 @@ public:
virtual OwningExprResult ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &FirstTypeName,
SourceLocation CCLoc,
SourceLocation TildeLoc,
@@ -1729,7 +1758,7 @@ public:
virtual MemInitResult ActOnMemInitializer(DeclPtrTy ConstructorDecl,
Scope *S,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
IdentifierInfo *MemberOrBase,
TypeTy *TemplateTypeTy,
SourceLocation IdLoc,
@@ -1939,7 +1968,7 @@ public:
/// \param EnteringContext whether we are entering the context of this
/// template.
virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &Name,
TypeTy *ObjectType,
bool EnteringContext) {
@@ -1995,7 +2024,7 @@ public:
virtual DeclResult
ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagUseKind TUK,
SourceLocation KWLoc,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
@@ -2133,7 +2162,7 @@ public:
SourceLocation TemplateLoc,
unsigned TagSpec,
SourceLocation KWLoc,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
IdentifierInfo *Name,
SourceLocation NameLoc,
AttributeList *Attr) {
@@ -2306,7 +2335,7 @@ public:
TypeTy *ReturnType, // the method return type.
Selector Sel, // a unique name for the method.
ObjCArgInfo *ArgInfo, // ArgInfo: Has 'Sel.getNumArgs()' entries.
- llvm::SmallVectorImpl<Declarator> &Cdecls, // c-style args
+ DeclaratorChunk::ParamInfo *CParamInfo, unsigned CNumArgs, // c-style args
AttributeList *MethodAttrList, // optional
// tok::objc_not_keyword, tok::objc_optional, tok::objc_required
tok::ObjCKeywordKind impKind,
@@ -2336,36 +2365,118 @@ public:
return DeclPtrTy();
}
- virtual OwningExprResult ActOnClassPropertyRefExpr(
- IdentifierInfo &receiverName,
- IdentifierInfo &propertyName,
- SourceLocation &receiverNameLoc,
- SourceLocation &propertyNameLoc) {
+ virtual OwningExprResult
+ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName,
+ IdentifierInfo &propertyName,
+ SourceLocation receiverNameLoc,
+ SourceLocation propertyNameLoc) {
return ExprEmpty();
}
- // ActOnClassMessage - used for both unary and keyword messages.
- // ArgExprs is optional - if it is present, the number of expressions
- // is obtained from NumArgs.
- virtual ExprResult ActOnClassMessage(
- Scope *S,
- IdentifierInfo *receivingClassName,
- Selector Sel,
- SourceLocation lbrac, SourceLocation receiverLoc,
- SourceLocation selectorLoc,
- SourceLocation rbrac,
- ExprTy **ArgExprs, unsigned NumArgs) {
- return ExprResult();
- }
- // ActOnInstanceMessage - used for both unary and keyword messages.
- // ArgExprs is optional - if it is present, the number of expressions
- // is obtained from NumArgs.
- virtual ExprResult ActOnInstanceMessage(
- ExprTy *receiver, Selector Sel,
- SourceLocation lbrac, SourceLocation selectorLoc, SourceLocation rbrac,
- ExprTy **ArgExprs, unsigned NumArgs) {
- return ExprResult();
+ /// \brief Describes the kind of message expression indicated by a message
+ /// send that starts with an identifier.
+ enum ObjCMessageKind {
+ /// \brief The message is sent to 'super'.
+ ObjCSuperMessage,
+ /// \brief The message is an instance message.
+ ObjCInstanceMessage,
+ /// \brief The message is a class message, and the identifier is a type
+ /// name.
+ ObjCClassMessage
+ };
+
+ /// \brief Determine the kind of Objective-C message send that we will be
+ /// performing based on the identifier given.
+ ///
+ /// This action determines how a message send that starts with [
+ /// identifier (followed by another identifier) will be parsed,
+ /// e.g., as a class message, instance message, super message. The
+ /// result depends on the meaning of the given identifier. If the
+ /// identifier is unknown, the action should indicate that the
+ /// message is an instance message.
+ ///
+ /// By default, this routine applies syntactic disambiguation and uses
+ /// \c getTypeName() to determine whether the identifier refers to a type.
+ /// However, \c Action subclasses may override this routine to improve
+ /// error recovery.
+ ///
+ /// \param S The scope in which the message send occurs.
+ ///
+ /// \param Name The identifier following the '['.
+ ///
+ /// \param NameLoc The location of the identifier.
+ ///
+ /// \param IsSuper Whether the name is the pseudo-keyword "super".
+ ///
+ /// \param HasTrailingDot Whether the name is followed by a period.
+ ///
+ /// \param ReceiverType If this routine returns \c ObjCClassMessage,
+ /// this argument will be set to the receiver type.
+ ///
+ /// \returns The kind of message send.
+ virtual ObjCMessageKind getObjCMessageKind(Scope *S,
+ IdentifierInfo *Name,
+ SourceLocation NameLoc,
+ bool IsSuper,
+ bool HasTrailingDot,
+ TypeTy *&ReceiverType);
+
+ /// \brief Parsed a message send to 'super'.
+ ///
+ /// \param S The scope in which the message send occurs.
+ /// \param SuperLoc The location of the 'super' keyword.
+ /// \param Sel The selector to which the message is being sent.
+ /// \param LBracLoc The location of the opening square bracket ']'.
+ /// \param SelectorLoc The location of the first identifier in the selector.
+ /// \param RBrac The location of the closing square bracket ']'.
+ /// \param Args The message arguments.
+ virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
+ return OwningExprResult(*this);
+ }
+
+ /// \brief Parsed a message send to a class.
+ ///
+ /// \param S The scope in which the message send occurs.
+ /// \param Receiver The type of the class receiving the message.
+ /// \param Sel The selector to which the message is being sent.
+ /// \param LBracLoc The location of the opening square bracket ']'.
+ /// \param SelectorLoc The location of the first identifier in the selector.
+ /// \param RBrac The location of the closing square bracket ']'.
+ /// \param Args The message arguments.
+ virtual OwningExprResult ActOnClassMessage(Scope *S,
+ TypeTy *Receiver,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
+ return OwningExprResult(*this);
+ }
+
+ /// \brief Parsed a message send to an object instance.
+ ///
+ /// \param S The scope in which the message send occurs.
+ /// \param Receiver The expression that computes the receiver object.
+ /// \param Sel The selector to which the message is being sent.
+ /// \param LBracLoc The location of the opening square bracket ']'.
+ /// \param SelectorLoc The location of the first identifier in the selector.
+ /// \param RBrac The location of the closing square bracket ']'.
+ /// \param Args The message arguments.
+ virtual OwningExprResult ActOnInstanceMessage(Scope *S,
+ ExprArg Receiver,
+ Selector Sel,
+ SourceLocation LBracLoc,
+ SourceLocation SelectorLoc,
+ SourceLocation RBracLoc,
+ MultiExprArg Args) {
+ return OwningExprResult(*this);
}
+
virtual DeclPtrTy ActOnForwardClassDeclaration(
SourceLocation AtClassLoc,
IdentifierInfo **IdentList,
@@ -2581,7 +2692,7 @@ public:
///
/// \parame EnteringContext whether we're entering the context of this
/// scope specifier.
- virtual void CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
+ virtual void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
bool EnteringContext) { }
/// \brief Code completion for a C++ "using" declaration or directive.
@@ -2692,21 +2803,33 @@ public:
unsigned NumMethods) {
}
+ /// \brief Code completion for an ObjC message expression that sends
+ /// a message to the superclass.
+ ///
+ /// This code completion action is invoked when the code-completion token is
+ /// found after the class name and after each argument.
+ ///
+ /// \param S The scope in which the message expression occurs.
+ /// \param SuperLoc The location of the 'super' keyword.
+ /// \param SelIdents The identifiers that describe the selector (thus far).
+ /// \param NumSelIdents The number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
+ IdentifierInfo **SelIdents,
+ unsigned NumSelIdents) { }
+
/// \brief Code completion for an ObjC message expression that refers to
/// a class method.
///
/// This code completion action is invoked when the code-completion token is
/// found after the class name and after each argument.
///
- /// \param S the scope in which the message expression occurs.
- /// \param FName the factory name.
- /// \param FNameLoc the source location of the factory name.
- /// \param SelIdents the identifiers that describe the selector (thus far).
- /// \param NumSelIdents the number of identifiers in \p SelIdents.
- virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
- SourceLocation FNameLoc,
+ /// \param S The scope in which the message expression occurs.
+ /// \param Receiver The type of the class that is receiving a message.
+ /// \param SelIdents The identifiers that describe the selector (thus far).
+ /// \param NumSelIdents The number of identifiers in \p SelIdents.
+ virtual void CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
IdentifierInfo **SelIdents,
- unsigned NumSelIdents){ }
+ unsigned NumSelIdents) { }
/// \brief Code completion for an ObjC message expression that refers to
/// an instance method.
@@ -2752,7 +2875,8 @@ public:
///
/// \param ClassName the name of the class being defined.
virtual void CodeCompleteObjCSuperclass(Scope *S,
- IdentifierInfo *ClassName) {
+ IdentifierInfo *ClassName,
+ SourceLocation ClassNameLoc) {
}
/// \brief Code completion for an Objective-C implementation, after the
@@ -2765,7 +2889,8 @@ public:
/// This code completion action is invoked after the '(' that indicates
/// a category name within an Objective-C interface declaration.
virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
- IdentifierInfo *ClassName) {
+ IdentifierInfo *ClassName,
+ SourceLocation ClassNameLoc) {
}
/// \brief Code completion for the category name in an Objective-C category
@@ -2774,7 +2899,8 @@ public:
/// This code completion action is invoked after the '(' that indicates
/// the category name within an Objective-C category implementation.
virtual void CodeCompleteObjCImplementationCategory(Scope *S,
- IdentifierInfo *ClassName) {
+ IdentifierInfo *ClassName,
+ SourceLocation ClassNameLoc) {
}
/// \brief Code completion for the property names when defining an
@@ -2795,6 +2921,32 @@ public:
IdentifierInfo *PropertyName,
DeclPtrTy ObjCImpDecl) {
}
+
+ /// \brief Code completion for an Objective-C method declaration or
+ /// definition, which may occur within an interface, category,
+ /// extension, protocol, or implementation thereof (where applicable).
+ ///
+ /// This code completion action is invoked after the "-" or "+" that
+ /// starts a method declaration or definition, and after the return
+ /// type such a declaration (e.g., "- (id)").
+ ///
+ /// \param S The scope in which the completion occurs.
+ ///
+ /// \param IsInstanceMethod Whether this is an instance method
+ /// (introduced with '-'); otherwise, it's a class method
+ /// (introduced with '+').
+ ///
+ /// \param ReturnType If non-NULL, the specified return type of the method
+ /// being declared or defined.
+ ///
+ /// \param IDecl The interface, category, protocol, or
+ /// implementation, or category implementation in which this method
+ /// declaration or definition occurs.
+ virtual void CodeCompleteObjCMethodDecl(Scope *S,
+ bool IsInstanceMethod,
+ TypeTy *ReturnType,
+ DeclPtrTy IDecl) {
+ }
//@}
};
@@ -2837,7 +2989,7 @@ public:
/// \returns the type referred to by this identifier, or NULL if the type
/// does not name an identifier.
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
- Scope *S, const CXXScopeSpec *SS,
+ Scope *S, CXXScopeSpec *SS,
bool isClassName = false,
TypeTy *ObjectType = 0);
@@ -2847,7 +2999,7 @@ public:
const CXXScopeSpec *SS);
virtual TemplateNameKind isTemplateName(Scope *S,
- const CXXScopeSpec &SS,
+ CXXScopeSpec &SS,
UnqualifiedId &Name,
TypeTy *ObjectType,
bool EnteringContext,
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 37acab9b019b..12512f33c761 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -41,6 +41,7 @@ class AttributeList {
unsigned NumArgs;
AttributeList *Next;
bool DeclspecAttribute, CXX0XAttribute;
+ mutable bool Invalid; /// True if already diagnosed as invalid.
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
void operator=(const AttributeList &); // DO NOT IMPLEMENT
public:
@@ -128,6 +129,9 @@ public:
bool isDeclspecAttribute() const { return DeclspecAttribute; }
bool isCXX0XAttribute() const { return CXX0XAttribute; }
+ bool isInvalid() const { return Invalid; }
+ void setInvalid(bool b = true) const { Invalid = b; }
+
Kind getKind() const { return getKind(getName()); }
static Kind getKind(const IdentifierInfo *Name);
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index f6f1eb936b7a..9c19a674732a 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -27,9 +27,18 @@ namespace clang {
class Preprocessor;
class Declarator;
struct TemplateIdAnnotation;
-
+
/// CXXScopeSpec - Represents a C++ nested-name-specifier or a global scope
-/// specifier.
+/// specifier. These can be in 3 states:
+/// 1) Not present, identified by isEmpty()
+/// 2) Present, identified by isNotEmpty()
+/// 2.a) Valid, idenified by isValid()
+/// 2.b) Invalid, identified by isInvalid().
+///
+/// isSet() is deprecated because it mostly corresponded to "valid" but was
+/// often used as if it meant "present".
+///
+/// The actual scope is described by getScopeRep().
class CXXScopeSpec {
SourceRange Range;
void *ScopeRep;
@@ -47,13 +56,18 @@ public:
ActionBase::CXXScopeTy *getScopeRep() const { return ScopeRep; }
void setScopeRep(ActionBase::CXXScopeTy *S) { ScopeRep = S; }
+ /// No scope specifier.
bool isEmpty() const { return !Range.isValid(); }
+ /// A scope specifier is present, but may be valid or invalid.
bool isNotEmpty() const { return !isEmpty(); }
- /// isInvalid - An error occured during parsing of the scope specifier.
+ /// An error occured during parsing of the scope specifier.
bool isInvalid() const { return isNotEmpty() && ScopeRep == 0; }
+ /// A scope specifier is present, and it refers to a real scope.
+ bool isValid() const { return isNotEmpty() && ScopeRep != 0; }
- /// isSet - A scope specifier was resolved to a valid C++ scope.
+ /// Deprecated. Some call sites intend isNotEmpty() while others intend
+ /// isValid().
bool isSet() const { return ScopeRep != 0; }
void clear() {
@@ -68,8 +82,9 @@ public:
class DeclSpec {
public:
// storage-class-specifier
+ // Note: The order of these enumerators is important for diagnostics.
enum SCS {
- SCS_unspecified,
+ SCS_unspecified = 0,
SCS_typedef,
SCS_extern,
SCS_static,
@@ -171,6 +186,8 @@ private:
// constexpr-specifier
bool Constexpr_specified : 1;
+ /*SCS*/unsigned StorageClassSpecAsWritten : 3;
+
/// TypeRep - This contains action-specific information about a specific TST.
/// For example, for a typedef or struct, it might contain the declaration for
/// these.
@@ -203,6 +220,9 @@ private:
WrittenBuiltinSpecs writtenBS;
void SaveWrittenBuiltinSpecs();
+ void SaveStorageSpecifierAsWritten() {
+ StorageClassSpecAsWritten = StorageClassSpec;
+ }
DeclSpec(const DeclSpec&); // DO NOT IMPLEMENT
void operator=(const DeclSpec&); // DO NOT IMPLEMENT
@@ -224,6 +244,7 @@ public:
FS_explicit_specified(false),
Friend_specified(false),
Constexpr_specified(false),
+ StorageClassSpecAsWritten(SCS_unspecified),
TypeRep(0),
AttrList(0),
ProtocolQualifiers(0),
@@ -321,6 +342,10 @@ public:
///
unsigned getParsedSpecifiers() const;
+ SCS getStorageClassSpecAsWritten() const {
+ return (SCS)StorageClassSpecAsWritten;
+ }
+
/// isEmpty - Return true if this declaration specifier is completely empty:
/// no tokens were parsed in the production of it.
bool isEmpty() const {
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 9a4634a42085..42a41d6d3028 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -41,6 +41,29 @@ public:
virtual void print(llvm::raw_ostream &OS) const;
};
+/// PrecedenceLevels - These are precedences for the binary/ternary
+/// operators in the C99 grammar. These have been named to relate
+/// with the C99 grammar productions. Low precedences numbers bind
+/// more weakly than high numbers.
+namespace prec {
+ enum Level {
+ Unknown = 0, // Not binary operator.
+ Comma = 1, // ,
+ Assignment = 2, // =, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=
+ Conditional = 3, // ?
+ LogicalOr = 4, // ||
+ LogicalAnd = 5, // &&
+ InclusiveOr = 6, // |
+ ExclusiveOr = 7, // ^
+ And = 8, // &
+ Equality = 9, // ==, !=
+ Relational = 10, // >=, <=, >, <
+ Shift = 11, // <<, >>
+ Additive = 12, // -, +
+ Multiplicative = 13, // *, /, %
+ PointerToMember = 14 // .*, ->*
+ };
+}
/// Parser - This implements a parser for the C family of languages. After
/// parsing units of the grammar, productions are invoked to handle whatever has
@@ -460,9 +483,11 @@ private:
//===--------------------------------------------------------------------===//
// Diagnostic Emission and Error recovery.
+public:
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID);
DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID);
+private:
void SuggestParentheses(SourceLocation Loc, unsigned DK,
SourceRange ParenRange);
@@ -771,9 +796,15 @@ private:
const ParsedTemplateInfo &TemplateInfo);
void ParseLexedMethodDeclarations(ParsingClass &Class);
void ParseLexedMethodDefs(ParsingClass &Class);
+ bool ConsumeAndStoreUntil(tok::TokenKind T1,
+ CachedTokens &Toks,
+ bool StopAtSemi = true,
+ bool ConsumeFinalToken = true) {
+ return ConsumeAndStoreUntil(T1, T1, Toks, StopAtSemi, ConsumeFinalToken);
+ }
bool ConsumeAndStoreUntil(tok::TokenKind T1, tok::TokenKind T2,
CachedTokens &Toks,
- tok::TokenKind EarlyAbortIf = tok::unknown,
+ bool StopAtSemi = true,
bool ConsumeFinalToken = true);
//===--------------------------------------------------------------------===//
@@ -846,7 +877,7 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
-
+
OwningExprResult ParseExpression();
OwningExprResult ParseConstantExpression();
// Expr that doesn't include commas.
@@ -857,7 +888,7 @@ private:
OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc);
OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS,
- unsigned MinPrec);
+ prec::Level MinPrec);
OwningExprResult ParseCastExpression(bool isUnaryExpression,
bool isAddressOfOperand,
bool &NotCastExpr,
@@ -954,6 +985,8 @@ private:
// C++ 5.2.3: Explicit type conversion (functional notation)
OwningExprResult ParseCXXTypeConstructExpression(const DeclSpec &DS);
+ bool isCXXSimpleTypeSpecifier() const;
+
/// ParseCXXSimpleTypeSpecifier - [C++ 7.1.5.2] Simple type specifiers.
/// This should only be called when the current token is known to be part of
/// simple-type-specifier.
@@ -998,18 +1031,6 @@ private:
//===--------------------------------------------------------------------===//
// Objective-C Expressions
-
- bool isTokObjCMessageIdentifierReceiver() const {
- if (!Tok.is(tok::identifier))
- return false;
-
- IdentifierInfo *II = Tok.getIdentifierInfo();
- if (Actions.getTypeName(*II, Tok.getLocation(), CurScope))
- return true;
-
- return II == Ident_super;
- }
-
OwningExprResult ParseObjCAtExpression(SourceLocation AtLocation);
OwningExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
OwningExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
@@ -1017,12 +1038,13 @@ private:
OwningExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
OwningExprResult ParseObjCMessageExpression();
OwningExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
- SourceLocation NameLoc,
- IdentifierInfo *ReceiverName,
+ SourceLocation SuperLoc,
+ TypeTy *ReceiverType,
ExprArg ReceiverExpr);
OwningExprResult ParseAssignmentExprWithObjCMessageExprStart(
- SourceLocation LBracloc, SourceLocation NameLoc,
- IdentifierInfo *ReceiverName, ExprArg ReceiverExpr);
+ SourceLocation LBracloc, SourceLocation SuperLoc,
+ TypeTy *ReceiverType, ExprArg ReceiverExpr);
+ bool ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr);
//===--------------------------------------------------------------------===//
// C99 6.8: Statements and Blocks.
@@ -1354,7 +1376,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
TypeResult ParseClassName(SourceLocation &EndLocation,
- const CXXScopeSpec *SS = 0);
+ CXXScopeSpec *SS = 0);
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS,
const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(),
diff --git a/include/clang/Parse/Scope.h b/include/clang/Parse/Scope.h
index c9825f60c25c..d7a0e3583ca5 100644
--- a/include/clang/Parse/Scope.h
+++ b/include/clang/Parse/Scope.h
@@ -52,8 +52,8 @@ public:
/// BlockScope - This is a scope that corresponds to a block object.
/// Blocks serve as top-level scopes for some objects like labels, they
- /// also prevent things like break and continue. BlockScopes have the
- /// other flags set as well.
+ /// also prevent things like break and continue. BlockScopes always have
+ /// the FnScope, BreakScope, ContinueScope, and DeclScope flags set as well.
BlockScope = 0x40,
/// TemplateParamScope - This is a scope that corresponds to the
@@ -68,7 +68,15 @@ public:
/// AtCatchScope - This is a scope that corresponds to the Objective-C
/// @catch statement.
- AtCatchScope = 0x200
+ AtCatchScope = 0x200,
+
+ /// ObjCMethodScope - This scope corresponds to an Objective-C method body.
+ /// It always has FnScope and DeclScope set as well.
+ ObjCMethodScope = 0x400,
+
+ /// ElseScope - This scoep corresponds to an 'else' scope of an if/then/else
+ /// statement.
+ ElseScope = 0x800
};
private:
/// The parent scope for this scope. This is null for the translation-unit
@@ -77,15 +85,11 @@ private:
/// Depth - This is the depth of this scope. The translation-unit scope has
/// depth 0.
- unsigned Depth : 16;
+ unsigned short Depth;
/// Flags - This contains a set of ScopeFlags, which indicates how the scope
/// interrelates with other control flow statements.
- unsigned Flags : 10;
-
- /// WithinElse - Whether this scope is part of the "else" branch in
- /// its parent ControlScope.
- bool WithinElse : 1;
+ unsigned short Flags;
/// FnParent - If this scope has a parent scope that is a function body, this
/// pointer is non-null and points to it. This is used for label processing.
@@ -140,6 +144,7 @@ public:
/// getFlags - Return the flags for this scope.
///
unsigned getFlags() const { return Flags; }
+ void setFlags(unsigned F) { Flags = F; }
/// isBlockScope - Return true if this scope does not correspond to a
/// closure.
@@ -233,6 +238,17 @@ public:
}
return false;
}
+
+ /// isInObjcMethodScope - Return true if this scope is, or is contained in, an
+ /// Objective-C method body. Note that this method is not constant time.
+ bool isInObjcMethodScope() const {
+ for (const Scope *S = this; S; S = S->getParent()) {
+ // If this scope is an objc method scope, then we succeed.
+ if (S->getFlags() & ObjCMethodScope)
+ return true;
+ }
+ return false;
+ }
/// isTemplateParamScope - Return true if this scope is a C++
/// template parameter scope.
@@ -251,12 +267,6 @@ public:
return getFlags() & Scope::AtCatchScope;
}
- /// isWithinElse - Whether we are within the "else" of the
- /// ControlParent (if any).
- bool isWithinElse() const { return WithinElse; }
-
- void setWithinElse(bool WE) { WithinElse = WE; }
-
typedef UsingDirectivesTy::iterator udir_iterator;
typedef UsingDirectivesTy::const_iterator const_udir_iterator;
@@ -286,7 +296,6 @@ public:
AnyParent = Parent;
Depth = AnyParent ? AnyParent->Depth+1 : 0;
Flags = ScopeFlags;
- WithinElse = false;
if (AnyParent) {
FnParent = AnyParent->FnParent;
diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h
index 1692180a6da9..adda86699965 100644
--- a/include/clang/Rewrite/Rewriter.h
+++ b/include/clang/Rewrite/Rewriter.h
@@ -16,18 +16,20 @@
#define LLVM_CLANG_REWRITER_H
#include "clang/Basic/SourceLocation.h"
+#include "clang/Rewrite/DeltaTree.h"
#include "clang/Rewrite/RewriteRope.h"
-#include <map>
-#include <vector>
+#include "llvm/ADT/StringRef.h"
#include <cstring>
+#include <map>
#include <string>
-#include "clang/Rewrite/DeltaTree.h"
-#include "llvm/ADT/StringRef.h"
+#include <vector>
+
+namespace llvm { class raw_ostream; }
namespace clang {
- class SourceManager;
class LangOptions;
class Rewriter;
+ class SourceManager;
class Stmt;
/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original
@@ -53,6 +55,8 @@ public:
iterator end() const { return Buffer.end(); }
unsigned size() const { return Buffer.size(); }
+ llvm::raw_ostream &write(llvm::raw_ostream &) const;
+
/// RemoveText - Remove the specified text.
void RemoveText(unsigned OrigOffset, unsigned Size);
@@ -125,6 +129,8 @@ class Rewriter {
const LangOptions *LangOpts;
std::map<FileID, RewriteBuffer> RewriteBuffers;
public:
+ typedef std::map<FileID, RewriteBuffer>::iterator buffer_iterator;
+
explicit Rewriter(SourceManager &SM, const LangOptions &LO)
: SourceMgr(&SM), LangOpts(&LO) {}
explicit Rewriter() : SourceMgr(0), LangOpts(0) {}
@@ -192,6 +198,12 @@ public:
/// could not be rewritten, or false if successful.
bool ReplaceStmt(Stmt *From, Stmt *To);
+ /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
+ /// buffer, and allows you to write on it directly. This is useful if you
+ /// want efficient low-level access to apis for scribbling on one specific
+ /// FileID's buffer.
+ RewriteBuffer &getEditBuffer(FileID FID);
+
/// getRewriteBufferFor - Return the rewrite buffer for the specified FileID.
/// If no modification has been made to it, return null.
const RewriteBuffer *getRewriteBufferFor(FileID FID) const {
@@ -200,11 +212,9 @@ public:
return I == RewriteBuffers.end() ? 0 : &I->second;
}
- /// getEditBuffer - This is like getRewriteBufferFor, but always returns a
- /// buffer, and allows you to write on it directly. This is useful if you
- /// want efficient low-level access to apis for scribbling on one specific
- /// FileID's buffer.
- RewriteBuffer &getEditBuffer(FileID FID);
+ // Iterators over rewrite buffers.
+ buffer_iterator buffer_begin() { return RewriteBuffers.begin(); }
+ buffer_iterator buffer_end() { return RewriteBuffers.end(); }
private:
unsigned getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const;