aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-04-02 08:55:10 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-04-02 08:55:10 +0000
commit11d2b2d2bb706fca0656f2760839721bb7f6cb6f (patch)
treed374cdca417e76f1bf101f139dba2db1d10ee8f7 /include
parentc0c7bca4e5b8d12699dc93a0da49e9e4bb79671b (diff)
downloadsrc-11d2b2d2bb706fca0656f2760839721bb7f6cb6f.tar.gz
src-11d2b2d2bb706fca0656f2760839721bb7f6cb6f.zip
Update clang to r100181.
Notes
Notes: svn path=/vendor/clang/dist/; revision=206084
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/ASTContext.h48
-rw-r--r--include/clang/AST/CXXInheritance.h132
-rw-r--r--include/clang/AST/CanonicalType.h11
-rw-r--r--include/clang/AST/Decl.h57
-rw-r--r--include/clang/AST/DeclBase.h43
-rw-r--r--include/clang/AST/DeclCXX.h35
-rw-r--r--include/clang/AST/DeclContextInternals.h24
-rw-r--r--include/clang/AST/DeclFriend.h6
-rw-r--r--include/clang/AST/DeclTemplate.h6
-rw-r--r--include/clang/AST/DeclarationName.h2
-rw-r--r--include/clang/AST/DependentDiagnostic.h183
-rw-r--r--include/clang/AST/Expr.h51
-rw-r--r--include/clang/AST/ExprCXX.h4
-rw-r--r--include/clang/AST/Type.h235
-rw-r--r--include/clang/AST/TypeLoc.h6
-rw-r--r--include/clang/AST/TypeNodes.def2
-rw-r--r--include/clang/Analysis/AnalysisContext.h31
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowSolver.h45
-rw-r--r--include/clang/Basic/Builtins.def15
-rw-r--r--include/clang/Basic/BuiltinsX86.def8
-rw-r--r--include/clang/Basic/CMakeLists.txt8
-rw-r--r--include/clang/Basic/Diagnostic.h160
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td5
-rw-r--r--include/clang/Basic/DiagnosticGroups.td5
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td22
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td82
-rw-r--r--include/clang/Basic/PartialDiagnostic.h177
-rw-r--r--include/clang/Basic/SourceLocation.h1
-rw-r--r--include/clang/Checker/BugReporter/BugReporter.h7
-rw-r--r--include/clang/Checker/BugReporter/BugType.h7
-rw-r--r--include/clang/Checker/BugReporter/PathDiagnostic.h18
-rw-r--r--include/clang/Checker/DomainSpecific/CocoaConventions.h1
-rw-r--r--include/clang/Checker/PathSensitive/BasicValueFactory.h1
-rw-r--r--include/clang/Checker/PathSensitive/Checker.h8
-rw-r--r--include/clang/Checker/PathSensitive/Environment.h5
-rw-r--r--include/clang/Checker/PathSensitive/ExplodedGraph.h4
-rw-r--r--include/clang/Checker/PathSensitive/GRBlockCounter.h9
-rw-r--r--include/clang/Checker/PathSensitive/GRCoreEngine.h10
-rw-r--r--include/clang/Checker/PathSensitive/GRExprEngine.h24
-rw-r--r--include/clang/Checker/PathSensitive/GRSimpleAPICheck.h9
-rw-r--r--include/clang/Checker/PathSensitive/GRState.h34
-rw-r--r--include/clang/Checker/PathSensitive/GRSubEngine.h3
-rw-r--r--include/clang/Checker/PathSensitive/GRTransferFuncs.h10
-rw-r--r--include/clang/Checker/PathSensitive/MemRegion.h10
-rw-r--r--include/clang/Checker/PathSensitive/Store.h3
-rw-r--r--include/clang/Checker/PathSensitive/SymbolManager.h10
-rw-r--r--include/clang/CodeGen/CodeGenOptions.h1
-rw-r--r--include/clang/Driver/CC1Options.td3
-rw-r--r--include/clang/Driver/CMakeLists.txt4
-rw-r--r--include/clang/Driver/Driver.h9
-rw-r--r--include/clang/Driver/Options.td3
-rw-r--r--include/clang/Frontend/HeaderSearchOptions.h6
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h2
-rw-r--r--include/clang/Frontend/TypeXML.def2
-rw-r--r--include/clang/Lex/PPCallbacks.h11
-rw-r--r--include/clang/Lex/Preprocessor.h4
-rw-r--r--include/clang/Lex/PreprocessorLexer.h1
-rw-r--r--include/clang/Parse/Action.h3
58 files changed, 1165 insertions, 461 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index e77dcf86cca6..c41857ec0200 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -17,6 +17,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
@@ -57,6 +58,7 @@ namespace clang {
class ObjCIvarRefExpr;
class ObjCPropertyDecl;
class RecordDecl;
+ class StoredDeclsMap;
class TagDecl;
class TemplateTypeParmDecl;
class TranslationUnitDecl;
@@ -115,7 +117,7 @@ class ASTContext {
llvm::FoldingSet<SubstTemplateTypeParmType> SubstTemplateTypeParmTypes;
llvm::FoldingSet<TemplateSpecializationType> TemplateSpecializationTypes;
llvm::FoldingSet<QualifiedNameType> QualifiedNameTypes;
- llvm::FoldingSet<TypenameType> TypenameTypes;
+ llvm::FoldingSet<DependentNameType> DependentNameTypes;
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
@@ -264,6 +266,9 @@ class ASTContext {
llvm::MallocAllocator MallocAlloc;
llvm::BumpPtrAllocator BumpAlloc;
+ /// \brief Allocator for partial diagnostics.
+ PartialDiagnostic::StorageAllocator DiagAllocator;
+
public:
const TargetInfo &Target;
IdentifierTable &Idents;
@@ -289,6 +294,11 @@ public:
if (FreeMemory)
MallocAlloc.Deallocate(Ptr);
}
+
+ PartialDiagnostic::StorageAllocator &getDiagAllocator() {
+ return DiagAllocator;
+ }
+
const LangOptions& getLangOptions() const { return LangOpts; }
FullSourceLoc getFullLoc(SourceLocation Loc) const {
@@ -437,6 +447,11 @@ public:
/// allowable type.
QualType getCallConvType(QualType T, CallingConv CallConv);
+ /// getRegParmType - Sets the specified regparm attribute to
+ /// the given type, which must be a FunctionType or a pointer to an
+ /// allowable type.
+ QualType getRegParmType(QualType T, unsigned RegParm);
+
/// getComplexType - Return the uniqued reference to the type for a complex
/// number with the specified element type.
QualType getComplexType(QualType T);
@@ -554,8 +569,12 @@ public:
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
///
- QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn = false,
- CallingConv CallConv = CC_Default);
+ QualType getFunctionNoProtoType(QualType ResultTy,
+ const FunctionType::ExtInfo &Info);
+
+ QualType getFunctionNoProtoType(QualType ResultTy) {
+ return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo());
+ }
/// getFunctionType - Return a normal function type with a typed argument
/// list. isVariadic indicates whether the argument list includes '...'.
@@ -564,8 +583,7 @@ public:
unsigned TypeQuals, bool hasExceptionSpec,
bool hasAnyExceptionSpec,
unsigned NumExs, const QualType *ExArray,
- bool NoReturn,
- CallingConv CallConv);
+ const FunctionType::ExtInfo &Info);
/// getTypeDeclType - Return the unique reference to the type for
/// the specified type declaration.
@@ -612,12 +630,14 @@ public:
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
- QualType getTypenameType(NestedNameSpecifier *NNS,
- const IdentifierInfo *Name,
- QualType Canon = QualType());
- QualType getTypenameType(NestedNameSpecifier *NNS,
- const TemplateSpecializationType *TemplateId,
- QualType Canon = QualType());
+ QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name,
+ QualType Canon = QualType());
+ QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ const TemplateSpecializationType *TemplateId,
+ QualType Canon = QualType());
QualType getElaboratedType(QualType UnderlyingType,
ElaboratedType::TagKind Tag);
@@ -937,8 +957,7 @@ public:
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
void CollectNonClassIvars(const ObjCInterfaceDecl *OI,
llvm::SmallVectorImpl<ObjCIvarDecl*> &Ivars);
- unsigned CountSynthesizedIvars(const ObjCInterfaceDecl *OI);
- unsigned CountProtocolSynthesizedIvars(const ObjCProtocolDecl *PD);
+ unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI);
void CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
@@ -1273,9 +1292,8 @@ private:
// FIXME: This currently contains the set of StoredDeclMaps used
// by DeclContext objects. This probably should not be in ASTContext,
// but we include it here so that ASTContext can quickly deallocate them.
- std::vector<void*> SDMs;
+ llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM;
friend class DeclContext;
- void *CreateStoredDeclsMap();
void ReleaseDeclContextMaps();
};
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index c89e5e4b167a..edd633e8e140 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -19,6 +19,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeOrdering.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include <list>
#include <map>
@@ -227,6 +228,137 @@ public:
/// object.
void swap(CXXBasePaths &Other);
};
+
+/// \brief Uniquely identifies a virtual method within a class
+/// hierarchy by the method itself and a class subobject number.
+struct UniqueVirtualMethod {
+ UniqueVirtualMethod() : Method(0), Subobject(0), InVirtualSubobject(0) { }
+
+ UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
+ const CXXRecordDecl *InVirtualSubobject)
+ : Method(Method), Subobject(Subobject),
+ InVirtualSubobject(InVirtualSubobject) { }
+
+ /// \brief The overriding virtual method.
+ CXXMethodDecl *Method;
+
+ /// \brief The subobject in which the overriding virtual method
+ /// resides.
+ unsigned Subobject;
+
+ /// \brief The virtual base class subobject of which this overridden
+ /// virtual method is a part. Note that this records the closest
+ /// derived virtual base class subobject.
+ const CXXRecordDecl *InVirtualSubobject;
+
+ friend bool operator==(const UniqueVirtualMethod &X,
+ const UniqueVirtualMethod &Y) {
+ return X.Method == Y.Method && X.Subobject == Y.Subobject &&
+ X.InVirtualSubobject == Y.InVirtualSubobject;
+ }
+
+ friend bool operator!=(const UniqueVirtualMethod &X,
+ const UniqueVirtualMethod &Y) {
+ return !(X == Y);
+ }
+};
+
+/// \brief The set of methods that override a given virtual method in
+/// each subobject where it occurs.
+///
+/// The first part of the pair is the subobject in which the
+/// overridden virtual function occurs, while the second part of the
+/// pair is the virtual method that overrides it (including the
+/// subobject in which that virtual function occurs).
+class OverridingMethods {
+ llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+ Overrides;
+
+public:
+ // Iterate over the set of subobjects that have overriding methods.
+ typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+ ::iterator iterator;
+ typedef llvm::DenseMap<unsigned, llvm::SmallVector<UniqueVirtualMethod, 4> >
+ ::const_iterator const_iterator;
+ iterator begin() { return Overrides.begin(); }
+ const_iterator begin() const { return Overrides.begin(); }
+ iterator end() { return Overrides.end(); }
+ const_iterator end() const { return Overrides.end(); }
+ unsigned size() const { return Overrides.size(); }
+
+ // Iterate over the set of overriding virtual methods in a given
+ // subobject.
+ typedef llvm::SmallVector<UniqueVirtualMethod, 4>::iterator
+ overriding_iterator;
+ typedef llvm::SmallVector<UniqueVirtualMethod, 4>::const_iterator
+ overriding_const_iterator;
+
+ // Add a new overriding method for a particular subobject.
+ void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
+
+ // Add all of the overriding methods from "other" into overrides for
+ // this method. Used when merging the overrides from multiple base
+ // class subobjects.
+ void add(const OverridingMethods &Other);
+
+ // Replace all overriding virtual methods in all subobjects with the
+ // given virtual method.
+ void replaceAll(UniqueVirtualMethod Overriding);
+};
+
+/// \brief A mapping from each virtual member function to its set of
+/// final overriders.
+///
+/// Within a class hierarchy for a given derived class, each virtual
+/// member function in that hierarchy has one or more "final
+/// overriders" (C++ [class.virtual]p2). A final overrider for a
+/// virtual function "f" is the virtual function that will actually be
+/// invoked when dispatching a call to "f" through the
+/// vtable. Well-formed classes have a single final overrider for each
+/// virtual function; in abstract classes, the final overrider for at
+/// least one virtual function is a pure virtual function. Due to
+/// multiple, virtual inheritance, it is possible for a class to have
+/// more than one final overrider. Athough this is an error (per C++
+/// [class.virtual]p2), it is not considered an error here: the final
+/// overrider map can represent multiple final overriders for a
+/// method, and it is up to the client to determine whether they are
+/// problem. For example, the following class \c D has two final
+/// overriders for the virtual function \c A::f(), one in \c C and one
+/// in \c D:
+///
+/// \code
+/// struct A { virtual void f(); };
+/// struct B : virtual A { virtual void f(); };
+/// struct C : virtual A { virtual void f(); };
+/// struct D : B, C { };
+/// \endcode
+///
+/// This data structure contaings a mapping from every virtual
+/// function *that does not override an existing virtual function* and
+/// in every subobject where that virtual function occurs to the set
+/// of virtual functions that override it. Thus, the same virtual
+/// function \c A::f can actually occur in multiple subobjects of type
+/// \c A due to multiple inheritance, and may be overriden by
+/// different virtual functions in each, as in the following example:
+///
+/// \code
+/// struct A { virtual void f(); };
+/// struct B : A { virtual void f(); };
+/// struct C : A { virtual void f(); };
+/// struct D : B, C { };
+/// \endcode
+///
+/// Unlike in the previous example, where the virtual functions \c
+/// B::f and \c C::f both overrode \c A::f in the same subobject of
+/// type \c A, in this example the two virtual functions both override
+/// \c A::f but in *different* subobjects of type A. This is
+/// represented by numbering the subobjects in which the overridden
+/// and the overriding virtual member functions are located. Subobject
+/// 0 represents the virtua base class subobject of that type, while
+/// subobject numbers greater than 0 refer to non-virtual base class
+/// subobjects of that type.
+class CXXFinalOverriderMap
+ : public llvm::DenseMap<const CXXMethodDecl *, OverridingMethods> { };
} // end namespace clang
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 1f459b08ca78..b2a87f617063 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -165,6 +165,8 @@ public:
// (dynamic) type.
static CanQual<T> CreateUnsafe(QualType Other);
+ void dump() const { Stored.dump(); }
+
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(getAsOpaquePtr());
}
@@ -562,24 +564,21 @@ struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
template<>
struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
};
template<>
struct CanProxyAdaptor<FunctionNoProtoType>
: public CanProxyBase<FunctionNoProtoType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
};
template<>
struct CanProxyAdaptor<FunctionProtoType>
: public CanProxyBase<FunctionProtoType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
CanQualType getArgType(unsigned i) const {
return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index e23811d8f9c0..2cdb98351394 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -224,18 +224,26 @@ class NamespaceDecl : public NamedDecl, public DeclContext {
// NextNamespace points to the next extended declaration.
// OrigNamespace points to the original namespace declaration.
// OrigNamespace of the first namespace decl points to itself.
- NamespaceDecl *OrigNamespace, *NextNamespace;
+ NamespaceDecl *NextNamespace;
- // The (most recently entered) anonymous namespace inside this
- // namespace.
- NamespaceDecl *AnonymousNamespace;
+ /// \brief A pointer to either the original namespace definition for
+ /// this namespace (if the boolean value is false) or the anonymous
+ /// namespace that lives just inside this namespace (if the boolean
+ /// value is true).
+ ///
+ /// We can combine these two notions because the anonymous namespace
+ /// must only be stored in one of the namespace declarations (so all
+ /// of the namespace declarations can find it). We therefore choose
+ /// the original namespace declaration, since all of the namespace
+ /// declarations have a link directly to it; the original namespace
+ /// declaration itself only needs to know that it is the original
+ /// namespace declaration (which the boolean indicates).
+ llvm::PointerIntPair<NamespaceDecl *, 1, bool> OrigOrAnonNamespace;
NamespaceDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id)
- : NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace) {
- OrigNamespace = this;
- NextNamespace = 0;
- AnonymousNamespace = 0;
- }
+ : NamedDecl(Namespace, DC, L, Id), DeclContext(Namespace),
+ NextNamespace(0), OrigOrAnonNamespace(0, true) { }
+
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
@@ -258,22 +266,33 @@ public:
void setNextNamespace(NamespaceDecl *ND) { NextNamespace = ND; }
NamespaceDecl *getOriginalNamespace() const {
- return OrigNamespace;
+ if (OrigOrAnonNamespace.getInt())
+ return const_cast<NamespaceDecl *>(this);
+
+ return OrigOrAnonNamespace.getPointer();
+ }
+
+ void setOriginalNamespace(NamespaceDecl *ND) {
+ if (ND != this) {
+ OrigOrAnonNamespace.setPointer(ND);
+ OrigOrAnonNamespace.setInt(false);
+ }
}
- void setOriginalNamespace(NamespaceDecl *ND) { OrigNamespace = ND; }
NamespaceDecl *getAnonymousNamespace() const {
- return AnonymousNamespace;
+ return getOriginalNamespace()->OrigOrAnonNamespace.getPointer();
}
void setAnonymousNamespace(NamespaceDecl *D) {
assert(!D || D->isAnonymousNamespace());
assert(!D || D->getParent() == this);
- AnonymousNamespace = D;
+ getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
}
- virtual NamespaceDecl *getCanonicalDecl() { return OrigNamespace; }
- const NamespaceDecl *getCanonicalDecl() const { return OrigNamespace; }
+ virtual NamespaceDecl *getCanonicalDecl() { return getOriginalNamespace(); }
+ const NamespaceDecl *getCanonicalDecl() const {
+ return getOriginalNamespace();
+ }
virtual SourceRange getSourceRange() const {
return SourceRange(getLocation(), RBracLoc);
@@ -1819,12 +1838,12 @@ class RecordDecl : public TagDecl {
/// If so, this cannot be contained in arrays or other structs as a member.
bool HasFlexibleArrayMember : 1;
- /// AnonymousStructOrUnion - Whether this is the type of an
- /// anonymous struct or union.
+ /// AnonymousStructOrUnion - Whether this is the type of an anonymous struct
+ /// or union.
bool AnonymousStructOrUnion : 1;
- /// HasObjectMember - This is true if this struct has at least one
- /// member containing an object
+ /// HasObjectMember - This is true if this struct has at least one member
+ /// containing an object.
bool HasObjectMember : 1;
protected:
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 6f8284458f2b..d5913e236c2c 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -41,6 +41,8 @@ class LinkageSpecDecl;
class BlockDecl;
class DeclarationName;
class CompoundStmt;
+class StoredDeclsMap;
+class DependentDiagnostic;
}
namespace llvm {
@@ -450,15 +452,23 @@ public:
/// same entity may not (and probably don't) share this property.
void setObjectOfFriendDecl(bool PreviouslyDeclared) {
unsigned OldNS = IdentifierNamespace;
- assert((OldNS == IDNS_Tag || OldNS == IDNS_Ordinary ||
- OldNS == (IDNS_Tag | IDNS_Ordinary))
- && "unsupported namespace for undeclared friend");
- if (!PreviouslyDeclared) IdentifierNamespace = 0;
-
- if (OldNS == IDNS_Tag)
+ assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
+ IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+ "namespace includes neither ordinary nor tag");
+ assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary |
+ IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+ "namespace includes other than ordinary or tag");
+
+ IdentifierNamespace = 0;
+ if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
IdentifierNamespace |= IDNS_TagFriend;
- else
+ if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag;
+ }
+
+ if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
IdentifierNamespace |= IDNS_OrdinaryFriend;
+ if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Ordinary;
+ }
}
enum FriendObjectKind {
@@ -545,9 +555,9 @@ class DeclContext {
mutable bool ExternalVisibleStorage : 1;
/// \brief Pointer to the data structure used to lookup declarations
- /// within this context, which is a DenseMap<DeclarationName,
- /// StoredDeclsList>.
- mutable void* LookupPtr;
+ /// within this context (or a DependentStoredDeclsMap if this is a
+ /// dependent context).
+ mutable StoredDeclsMap *LookupPtr;
/// FirstDecl - The first declaration stored within this declaration
/// context.
@@ -674,6 +684,9 @@ public:
/// "primary" DeclContext structure, which will contain the
/// information needed to perform name lookup into this context.
DeclContext *getPrimaryContext();
+ const DeclContext *getPrimaryContext() const {
+ return const_cast<DeclContext*>(this)->getPrimaryContext();
+ }
/// getLookupContext - Retrieve the innermost non-transparent
/// context of this context, which corresponds to the innermost
@@ -976,10 +989,15 @@ public:
return getUsingDirectives().second;
}
+ // These are all defined in DependentDiagnostic.h.
+ class ddiag_iterator;
+ inline ddiag_iterator ddiag_begin() const;
+ inline ddiag_iterator ddiag_end() const;
+
// Low-level accessors
/// \brief Retrieve the internal representation of the lookup structure.
- void* getLookupPtr() const { return LookupPtr; }
+ StoredDeclsMap* getLookupPtr() const { return LookupPtr; }
/// \brief Whether this DeclContext has external storage containing
/// additional declarations that are lexically in this context.
@@ -1013,6 +1031,9 @@ private:
void LoadLexicalDeclsFromExternalStorage() const;
void LoadVisibleDeclsFromExternalStorage() const;
+ friend class DependentDiagnostic;
+ StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
+
void buildLookup(DeclContext *DCtx);
void makeDeclVisibleInContextImpl(NamedDecl *D);
};
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 6b04ed54109a..23769af46b36 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -33,6 +33,7 @@ class CXXDestructorDecl;
class CXXMethodDecl;
class CXXRecordDecl;
class CXXMemberLookupCriteria;
+class CXXFinalOverriderMap;
class FriendDecl;
/// \brief Represents any kind of function declaration, whether it is a
@@ -328,6 +329,10 @@ class CXXRecordDecl : public RecordDecl {
/// instantiated or specialized.
llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
TemplateOrInstantiation;
+
+#ifndef NDEBUG
+ void CheckConversionFunction(NamedDecl *D);
+#endif
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@@ -549,17 +554,26 @@ public:
return getConversionFunctions()->replace(Old, New);
}
+ /// Removes a conversion function from this class. The conversion
+ /// function must currently be a member of this class. Furthermore,
+ /// this class must currently be in the process of being defined.
+ void removeConversion(const NamedDecl *Old);
+
/// getVisibleConversionFunctions - get all conversion functions visible
/// in current class; including conversion function templates.
const UnresolvedSetImpl *getVisibleConversionFunctions();
- /// addConversionFunction - Add a new conversion function to the
- /// list of conversion functions.
- void addConversionFunction(CXXConversionDecl *ConvDecl);
+ /// addConversionFunction - Registers a conversion function which
+ /// this class declares directly.
+ void addConversionFunction(NamedDecl *Decl) {
+#ifndef NDEBUG
+ CheckConversionFunction(Decl);
+#endif
- /// \brief Add a new conversion function template to the list of conversion
- /// functions.
- void addConversionFunction(FunctionTemplateDecl *ConvDecl);
+ // We intentionally don't use the decl's access here because it
+ // hasn't been set yet. That's really just a misdesign in Sema.
+ data().Conversions.addDecl(Decl);
+ }
/// isAggregate - Whether this class is an aggregate (C++
/// [dcl.init.aggr]), which is a class with no user-declared
@@ -879,7 +893,12 @@ public:
static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
void *UserData);
-
+
+ /// \brief Retrieve the final overriders for each virtual member
+ /// function in the class hierarchy where this class is the
+ /// most-derived class in the class hierarchy.
+ void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
+
/// viewInheritance - Renders and displays an inheritance diagram
/// for this C++ class and all of its base classes (transitively) using
/// GraphViz.
@@ -935,7 +954,7 @@ public:
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
}
-
+
/// \brief Determine whether this is a usual deallocation function
/// (C++ [basic.stc.dynamic.deallocation]p2), which is an overloaded
/// delete or delete[] operator with a particular signature.
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 32405ee81260..16cb491344bc 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -24,6 +24,8 @@
namespace clang {
+class DependentDiagnostic;
+
/// StoredDeclsList - This is an array of decls optimized a common case of only
/// containing one entry.
struct StoredDeclsList {
@@ -258,8 +260,28 @@ public:
}
};
-typedef llvm::DenseMap<DeclarationName, StoredDeclsList> StoredDeclsMap;
+class StoredDeclsMap
+ : public llvm::DenseMap<DeclarationName, StoredDeclsList> {
+
+public:
+ static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
+
+private:
+ friend class ASTContext; // walks the chain deleting these
+ friend class DeclContext;
+ llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
+};
+class DependentStoredDeclsMap : public StoredDeclsMap {
+public:
+ DependentStoredDeclsMap() : FirstDiagnostic(0) {}
+
+private:
+ friend class DependentDiagnostic;
+ friend class DeclContext; // iterates over diagnostics
+
+ DependentDiagnostic *FirstDiagnostic;
+};
} // end namespace clang
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 5022ad018f4f..99ef738980cc 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -36,7 +36,7 @@ namespace clang {
/// The semantic context of a friend decl is its declaring class.
class FriendDecl : public Decl {
public:
- typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion;
+ typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
private:
// The declaration that's a friend of this class.
@@ -73,8 +73,8 @@ public:
/// possibly dependent) type, return the type; otherwise
/// return null. This is used only for C++0x's unelaborated
/// friend type declarations.
- Type *getFriendType() const {
- return Friend.dyn_cast<Type*>();
+ TypeSourceInfo *getFriendType() const {
+ return Friend.dyn_cast<TypeSourceInfo*>();
}
/// If this friend declaration doesn't name an unelaborated
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 560ce46ede7c..8d1a4caccb23 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -1238,7 +1238,7 @@ public:
/// template <typename U> friend class Foo<T>::Nested; // friend template
class FriendTemplateDecl : public Decl {
public:
- typedef llvm::PointerUnion<NamedDecl*,Type*> FriendUnion;
+ typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
private:
// The number of template parameters; always non-zero.
@@ -1277,8 +1277,8 @@ public:
/// If this friend declaration names a templated type (or
/// a dependent member type of a templated type), return that
/// type; otherwise return null.
- Type *getFriendType() const {
- return Friend.dyn_cast<Type*>();
+ TypeSourceInfo *getFriendType() const {
+ return Friend.dyn_cast<TypeSourceInfo*>();
}
/// If this friend declaration names a templated function (or
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 2254724410d0..6225069c602f 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -378,7 +378,7 @@ inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
Diagnostic::ak_declarationname);
return PD;
}
-
+
} // end namespace clang
namespace llvm {
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
new file mode 100644
index 000000000000..1954a282e802
--- /dev/null
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -0,0 +1,183 @@
+//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- 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 interfaces for diagnostics which may or may
+// fire based on how a template is instantiated.
+//
+// At the moment, the only consumer of this interface is access
+// control.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+#define LLVM_CLANG_AST_DEPENDENT_DIAGNOSTIC_H
+
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclContextInternals.h"
+
+namespace clang {
+
+class ASTContext;
+class CXXRecordDecl;
+class NamedDecl;
+
+/// A dependently-generated diagnostic.
+class DependentDiagnostic {
+public:
+ enum AccessNonce { Access = 0 };
+
+ static DependentDiagnostic *Create(ASTContext &Context,
+ DeclContext *Parent,
+ AccessNonce _,
+ SourceLocation Loc,
+ bool IsMemberAccess,
+ AccessSpecifier AS,
+ NamedDecl *TargetDecl,
+ CXXRecordDecl *NamingClass,
+ const PartialDiagnostic &PDiag) {
+ DependentDiagnostic *DD = Create(Context, Parent, PDiag);
+ DD->AccessData.Loc = Loc.getRawEncoding();
+ DD->AccessData.IsMember = IsMemberAccess;
+ DD->AccessData.Access = AS;
+ DD->AccessData.TargetDecl = TargetDecl;
+ DD->AccessData.NamingClass = NamingClass;
+ return DD;
+ }
+
+ unsigned getKind() const {
+ return Access;
+ }
+
+ bool isAccessToMember() const {
+ assert(getKind() == Access);
+ return AccessData.IsMember;
+ }
+
+ AccessSpecifier getAccess() const {
+ assert(getKind() == Access);
+ return AccessSpecifier(AccessData.Access);
+ }
+
+ SourceLocation getAccessLoc() const {
+ assert(getKind() == Access);
+ return SourceLocation::getFromRawEncoding(AccessData.Loc);
+ }
+
+ NamedDecl *getAccessTarget() const {
+ assert(getKind() == Access);
+ return AccessData.TargetDecl;
+ }
+
+ NamedDecl *getAccessNamingClass() const {
+ assert(getKind() == Access);
+ return AccessData.NamingClass;
+ }
+
+ const PartialDiagnostic &getDiagnostic() const {
+ return Diag;
+ }
+
+private:
+ DependentDiagnostic(const PartialDiagnostic &PDiag,
+ PartialDiagnostic::Storage *Storage)
+ : Diag(PDiag, Storage) {}
+
+ static DependentDiagnostic *Create(ASTContext &Context,
+ DeclContext *Parent,
+ const PartialDiagnostic &PDiag);
+
+ friend class DependentStoredDeclsMap;
+ friend class DeclContext::ddiag_iterator;
+ DependentDiagnostic *NextDiagnostic;
+
+ PartialDiagnostic Diag;
+
+ union {
+ struct {
+ unsigned Loc;
+ unsigned Access : 2;
+ unsigned IsMember : 1;
+ NamedDecl *TargetDecl;
+ CXXRecordDecl *NamingClass;
+ } AccessData;
+ };
+};
+
+///
+
+/// An iterator over the dependent diagnostics in a dependent context.
+class DeclContext::ddiag_iterator {
+public:
+ ddiag_iterator() : Ptr(0) {}
+ explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
+
+ typedef DependentDiagnostic *value_type;
+ typedef DependentDiagnostic *reference;
+ typedef DependentDiagnostic *pointer;
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ reference operator*() const { return Ptr; }
+
+ ddiag_iterator &operator++() {
+ assert(Ptr && "attempt to increment past end of diag list");
+ Ptr = Ptr->NextDiagnostic;
+ return *this;
+ }
+
+ ddiag_iterator operator++(int) {
+ ddiag_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(ddiag_iterator Other) const {
+ return Ptr == Other.Ptr;
+ }
+
+ bool operator!=(ddiag_iterator Other) const {
+ return Ptr != Other.Ptr;
+ }
+
+ ddiag_iterator &operator+=(difference_type N) {
+ assert(N >= 0 && "cannot rewind a DeclContext::ddiag_iterator");
+ while (N--)
+ ++*this;
+ return *this;
+ }
+
+ ddiag_iterator operator+(difference_type N) const {
+ ddiag_iterator tmp = *this;
+ tmp += N;
+ return tmp;
+ }
+
+private:
+ DependentDiagnostic *Ptr;
+};
+
+inline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
+ assert(isDependentContext()
+ && "cannot iterate dependent diagnostics of non-dependent context");
+ const DependentStoredDeclsMap *Map
+ = static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->LookupPtr);
+
+ if (!Map) return ddiag_iterator();
+ return ddiag_iterator(Map->FirstDiagnostic);
+}
+
+inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
+ return ddiag_iterator();
+}
+
+}
+
+#endif
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 6b14e47cbef5..507a61c6d7a6 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1263,6 +1263,11 @@ public:
/// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F.
///
class MemberExpr : public Expr {
+ /// Extra data stored in some member expressions.
+ struct MemberNameQualifier : public NameQualifier {
+ NamedDecl *FoundDecl;
+ };
+
/// Base - the expression for the base pointer or structure references. In
/// X.F, this is "X".
Stmt *Base;
@@ -1278,27 +1283,26 @@ class MemberExpr : public Expr {
bool IsArrow : 1;
/// \brief True if this member expression used a nested-name-specifier to
- /// refer to the member, e.g., "x->Base::f". When true, a NameQualifier
+ /// refer to the member, e.g., "x->Base::f", or found its member via a using
+ /// declaration. When true, a MemberNameQualifier
/// structure is allocated immediately after the MemberExpr.
- bool HasQualifier : 1;
+ bool HasQualifierOrFoundDecl : 1;
/// \brief True if this member expression specified a template argument list
/// explicitly, e.g., x->f<int>. When true, an ExplicitTemplateArgumentList
/// structure (and its TemplateArguments) are allocated immediately after
/// the MemberExpr or, if the member expression also has a qualifier, after
- /// the NameQualifier structure.
+ /// the MemberNameQualifier structure.
bool HasExplicitTemplateArgumentList : 1;
/// \brief Retrieve the qualifier that preceded the member name, if any.
- NameQualifier *getMemberQualifier() {
- if (!HasQualifier)
- return 0;
-
- return reinterpret_cast<NameQualifier *> (this + 1);
+ MemberNameQualifier *getMemberQualifier() {
+ assert(HasQualifierOrFoundDecl);
+ return reinterpret_cast<MemberNameQualifier *> (this + 1);
}
/// \brief Retrieve the qualifier that preceded the member name, if any.
- const NameQualifier *getMemberQualifier() const {
+ const MemberNameQualifier *getMemberQualifier() const {
return const_cast<MemberExpr *>(this)->getMemberQualifier();
}
@@ -1308,7 +1312,7 @@ class MemberExpr : public Expr {
if (!HasExplicitTemplateArgumentList)
return 0;
- if (!HasQualifier)
+ if (!HasQualifierOrFoundDecl)
return reinterpret_cast<ExplicitTemplateArgumentList *>(this + 1);
return reinterpret_cast<ExplicitTemplateArgumentList *>(
@@ -1321,26 +1325,22 @@ class MemberExpr : public Expr {
return const_cast<MemberExpr *>(this)->getExplicitTemplateArgumentList();
}
- MemberExpr(Expr *base, bool isarrow, NestedNameSpecifier *qual,
- SourceRange qualrange, ValueDecl *memberdecl, SourceLocation l,
- const TemplateArgumentListInfo *targs, QualType ty);
-
public:
MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl,
SourceLocation l, QualType ty)
: Expr(MemberExprClass, ty,
base->isTypeDependent(), base->isValueDependent()),
Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow),
- HasQualifier(false), HasExplicitTemplateArgumentList(false) {}
+ HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
/// \brief Build an empty member reference expression.
explicit MemberExpr(EmptyShell Empty)
- : Expr(MemberExprClass, Empty), HasQualifier(false),
+ : Expr(MemberExprClass, Empty), HasQualifierOrFoundDecl(false),
HasExplicitTemplateArgumentList(false) { }
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifier *qual, SourceRange qualrange,
- ValueDecl *memberdecl,
+ ValueDecl *memberdecl, NamedDecl *founddecl,
SourceLocation l,
const TemplateArgumentListInfo *targs,
QualType ty);
@@ -1355,16 +1355,23 @@ public:
ValueDecl *getMemberDecl() const { return MemberDecl; }
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
+ /// \brief Retrieves the declaration found by lookup.
+ NamedDecl *getFoundDecl() const {
+ if (!HasQualifierOrFoundDecl)
+ return getMemberDecl();
+ return getMemberQualifier()->FoundDecl;
+ }
+
/// \brief Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
/// x->Base::foo.
- bool hasQualifier() const { return HasQualifier; }
+ bool hasQualifier() const { return getQualifier() != 0; }
/// \brief If the member name was qualified, retrieves the source range of
/// the nested-name-specifier that precedes the member name. Otherwise,
/// returns an empty source range.
SourceRange getQualifierRange() const {
- if (!HasQualifier)
+ if (!HasQualifierOrFoundDecl)
return SourceRange();
return getMemberQualifier()->Range;
@@ -1374,7 +1381,7 @@ public:
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const {
- if (!HasQualifier)
+ if (!HasQualifierOrFoundDecl)
return 0;
return getMemberQualifier()->NNS;
@@ -1545,6 +1552,10 @@ public:
/// CK_DerivedToBase - Derived to base class casts.
CK_DerivedToBase,
+ /// CK_UncheckedDerivedToBase - Derived to base class casts that
+ /// assume that the derived pointer is not null.
+ CK_UncheckedDerivedToBase,
+
/// CK_Dynamic - Dynamic cast.
CK_Dynamic,
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index d1351b8b1447..6e2e832e3542 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -1095,8 +1095,8 @@ public:
: Expr(CXXPseudoDestructorExprClass,
Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0,
false, 0, false,
- false, 0, 0, false,
- CC_Default)),
+ false, 0, 0,
+ FunctionType::ExtInfo())),
/*isTypeDependent=*/(Base->isTypeDependent() ||
(DestroyedType.getTypeSourceInfo() &&
DestroyedType.getTypeSourceInfo()->getType()->isDependentType())),
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 111be5562199..72793651c4be 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -17,6 +17,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/Linkage.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateName.h"
#include "llvm/Support/Casting.h"
@@ -678,14 +679,6 @@ public:
return getObjCGCAttr() == Qualifiers::Strong;
}
- /// getNoReturnAttr - Returns true if the type has the noreturn attribute,
- /// false otherwise.
- bool getNoReturnAttr() const;
-
- /// getCallConv - Returns the calling convention of the type if the type
- /// is a function type, CC_Default otherwise.
- CallingConv getCallConv() const;
-
private:
// These methods are implemented in a separate translation unit;
// "static"-ize them to avoid creating temporary QualTypes in the
@@ -902,6 +895,9 @@ public:
bool isDependentType() const { return Dependent; }
bool isOverloadableType() const;
+ /// \brief Determine wither this type is a C++ elaborated-type-specifier.
+ bool isElaboratedTypeSpecifier() const;
+
/// hasPointerRepresentation - Whether this type is represented
/// natively as a pointer; this includes pointers, references, block
/// pointers, and Objective-C interface, qualified id, and qualified
@@ -1747,25 +1743,101 @@ class FunctionType : public Type {
/// NoReturn - Indicates if the function type is attribute noreturn.
unsigned NoReturn : 1;
+ /// RegParm - How many arguments to pass inreg.
+ unsigned RegParm : 3;
+
/// CallConv - The calling convention used by the function.
unsigned CallConv : 2;
// The type returned by the function.
QualType ResultType;
+
+ public:
+ // This class is used for passing arround the information needed to
+ // construct a call. It is not actually used for storage, just for
+ // factoring together common arguments.
+ // If you add a field (say Foo), other than the obvious places (both, constructors,
+ // compile failures), what you need to update is
+ // * Operetor==
+ // * getFoo
+ // * withFoo
+ // * functionType. Add Foo, getFoo.
+ // * ASTContext::getFooType
+ // * ASTContext::mergeFunctionTypes
+ // * FunctionNoProtoType::Profile
+ // * FunctionProtoType::Profile
+ // * TypePrinter::PrintFunctionProto
+ // * PCH read and write
+ // * Codegen
+
+ class ExtInfo {
+ public:
+ // Constructor with no defaults. Use this when you know that you
+ // have all the elements (when reading a PCH file for example).
+ ExtInfo(bool noReturn, unsigned regParm, CallingConv cc) :
+ NoReturn(noReturn), RegParm(regParm), CC(cc) {}
+
+ // Constructor with all defaults. Use when for example creating a
+ // function know to use defaults.
+ ExtInfo() : NoReturn(false), RegParm(0), CC(CC_Default) {}
+
+ bool getNoReturn() const { return NoReturn; }
+ unsigned getRegParm() const { return RegParm; }
+ CallingConv getCC() const { return CC; }
+
+ bool operator==(const ExtInfo &Other) const {
+ return getNoReturn() == Other.getNoReturn() &&
+ getRegParm() == Other.getRegParm() &&
+ getCC() == Other.getCC();
+ }
+ bool operator!=(const ExtInfo &Other) const {
+ return !(*this == Other);
+ }
+
+ // Note that we don't have setters. That is by design, use
+ // the following with methods instead of mutating these objects.
+
+ ExtInfo withNoReturn(bool noReturn) const {
+ return ExtInfo(noReturn, getRegParm(), getCC());
+ }
+
+ ExtInfo withRegParm(unsigned RegParm) const {
+ return ExtInfo(getNoReturn(), RegParm, getCC());
+ }
+
+ ExtInfo withCallingConv(CallingConv cc) const {
+ return ExtInfo(getNoReturn(), getRegParm(), cc);
+ }
+
+ private:
+ // True if we have __attribute__((noreturn))
+ bool NoReturn;
+ // The value passed to __attribute__((regparm(x)))
+ unsigned RegParm;
+ // The calling convention as specified via
+ // __attribute__((cdecl|stdcall||fastcall))
+ CallingConv CC;
+ };
+
protected:
FunctionType(TypeClass tc, QualType res, bool SubclassInfo,
unsigned typeQuals, QualType Canonical, bool Dependent,
- bool noReturn = false, CallingConv callConv = CC_Default)
+ const ExtInfo &Info)
: Type(tc, Canonical, Dependent),
- SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn),
- CallConv(callConv), ResultType(res) {}
+ SubClassData(SubclassInfo), TypeQuals(typeQuals),
+ NoReturn(Info.getNoReturn()),
+ RegParm(Info.getRegParm()), CallConv(Info.getCC()), ResultType(res) {}
bool getSubClassData() const { return SubClassData; }
unsigned getTypeQuals() const { return TypeQuals; }
public:
QualType getResultType() const { return ResultType; }
+ unsigned getRegParmType() const { return RegParm; }
bool getNoReturnAttr() const { return NoReturn; }
CallingConv getCallConv() const { return (CallingConv)CallConv; }
+ ExtInfo getExtInfo() const {
+ return ExtInfo(NoReturn, RegParm, (CallingConv)CallConv);
+ }
static llvm::StringRef getNameForCallConv(CallingConv CC);
@@ -1780,9 +1852,9 @@ public:
/// no information available about its arguments.
class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionNoProtoType(QualType Result, QualType Canonical,
- bool NoReturn = false, CallingConv CallConv = CC_Default)
+ const ExtInfo &Info)
: FunctionType(FunctionNoProto, Result, false, 0, Canonical,
- /*Dependent=*/false, NoReturn, CallConv) {}
+ /*Dependent=*/false, Info) {}
friend class ASTContext; // ASTContext creates these.
public:
// No additional state past what FunctionType provides.
@@ -1791,12 +1863,13 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getResultType(), getNoReturnAttr(), getCallConv());
+ Profile(ID, getResultType(), getExtInfo());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType,
- bool NoReturn, CallingConv CallConv) {
- ID.AddInteger(CallConv);
- ID.AddInteger(NoReturn);
+ const ExtInfo &Info) {
+ ID.AddInteger(Info.getCC());
+ ID.AddInteger(Info.getRegParm());
+ ID.AddInteger(Info.getNoReturn());
ID.AddPointer(ResultType.getAsOpaquePtr());
}
@@ -1827,12 +1900,12 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode {
FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs,
bool isVariadic, unsigned typeQuals, bool hasExs,
bool hasAnyExs, const QualType *ExArray,
- unsigned numExs, QualType Canonical, bool NoReturn,
- CallingConv CallConv)
+ unsigned numExs, QualType Canonical,
+ const ExtInfo &Info)
: FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical,
(Result->isDependentType() ||
- hasAnyDependentType(ArgArray, numArgs)), NoReturn,
- CallConv),
+ hasAnyDependentType(ArgArray, numArgs)),
+ Info),
NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs),
AnyExceptionSpec(hasAnyExs) {
// Fill in the trailing argument array.
@@ -1918,7 +1991,7 @@ public:
bool isVariadic, unsigned TypeQuals,
bool hasExceptionSpec, bool anyExceptionSpec,
unsigned NumExceptions, exception_iterator Exs,
- bool NoReturn, CallingConv CallConv);
+ const ExtInfo &ExtInfo);
};
@@ -2481,6 +2554,24 @@ public:
static bool classof(const InjectedClassNameType *T) { return true; }
};
+/// \brief The elaboration keyword that precedes a qualified type name or
+/// introduces an elaborated-type-specifier.
+enum ElaboratedTypeKeyword {
+ /// \brief No keyword precedes the qualified type name.
+ ETK_None,
+ /// \brief The "typename" keyword precedes the qualified type name, e.g.,
+ /// \c typename T::type.
+ ETK_Typename,
+ /// \brief The "class" keyword introduces the elaborated-type-specifier.
+ ETK_Class,
+ /// \brief The "struct" keyword introduces the elaborated-type-specifier.
+ ETK_Struct,
+ /// \brief The "union" keyword introduces the elaborated-type-specifier.
+ ETK_Union,
+ /// \brief The "enum" keyword introduces the elaborated-type-specifier.
+ ETK_Enum
+};
+
/// \brief Represents a type that was referred to via a qualified
/// name, e.g., N::M::type.
///
@@ -2531,19 +2622,19 @@ public:
static bool classof(const QualifiedNameType *T) { return true; }
};
-/// \brief Represents a 'typename' specifier that names a type within
-/// a dependent type, e.g., "typename T::type".
+/// \brief Represents a qualified type name for which the type name is
+/// dependent.
///
-/// TypenameType has a very similar structure to QualifiedNameType,
-/// which also involves a nested-name-specifier following by a type,
-/// and (FIXME!) both can even be prefixed by the 'typename'
-/// keyword. However, the two types serve very different roles:
-/// QualifiedNameType is a non-semantic type that serves only as sugar
-/// to show how a particular type was written in the source
-/// code. TypenameType, on the other hand, only occurs when the
-/// nested-name-specifier is dependent, such that we cannot resolve
-/// the actual type until after instantiation.
-class TypenameType : public Type, public llvm::FoldingSetNode {
+/// DependentNameType represents a class of dependent types that involve a
+/// dependent nested-name-specifier (e.g., "T::") followed by a (dependent)
+/// name of a type. The DependentNameType may start with a "typename" (for a
+/// typename-specifier), "class", "struct", "union", or "enum" (for a
+/// dependent elaborated-type-specifier), or nothing (in contexts where we
+/// know that we must be referring to a type, e.g., in a base class specifier).
+class DependentNameType : public Type, public llvm::FoldingSetNode {
+ /// \brief The keyword used to elaborate this type.
+ ElaboratedTypeKeyword Keyword;
+
/// \brief The nested name specifier containing the qualifier.
NestedNameSpecifier *NNS;
@@ -2553,23 +2644,28 @@ class TypenameType : public Type, public llvm::FoldingSetNode {
/// \brief The type that this typename specifier refers to.
NameType Name;
- TypenameType(NestedNameSpecifier *NNS, const IdentifierInfo *Name,
- QualType CanonType)
- : Type(Typename, CanonType, true), NNS(NNS), Name(Name) {
+ DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name, QualType CanonType)
+ : Type(DependentName, CanonType, true),
+ Keyword(Keyword), NNS(NNS), Name(Name) {
assert(NNS->isDependent() &&
- "TypenameType requires a dependent nested-name-specifier");
+ "DependentNameType requires a dependent nested-name-specifier");
}
- TypenameType(NestedNameSpecifier *NNS, const TemplateSpecializationType *Ty,
- QualType CanonType)
- : Type(Typename, CanonType, true), NNS(NNS), Name(Ty) {
+ DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ const TemplateSpecializationType *Ty, QualType CanonType)
+ : Type(DependentName, CanonType, true),
+ Keyword(Keyword), NNS(NNS), Name(Ty) {
assert(NNS->isDependent() &&
- "TypenameType requires a dependent nested-name-specifier");
+ "DependentNameType requires a dependent nested-name-specifier");
}
friend class ASTContext; // ASTContext creates these
public:
+ /// \brief Retrieve the keyword used to elaborate this type.
+ ElaboratedTypeKeyword getKeyword() const { return Keyword; }
+
/// \brief Retrieve the qualification on this type.
NestedNameSpecifier *getQualifier() const { return NNS; }
@@ -2593,19 +2689,20 @@ public:
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, NNS, Name);
+ Profile(ID, Keyword, NNS, Name);
}
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
- NameType Name) {
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS, NameType Name) {
+ ID.AddInteger(Keyword);
ID.AddPointer(NNS);
ID.AddPointer(Name.getOpaqueValue());
}
static bool classof(const Type *T) {
- return T->getTypeClass() == Typename;
+ return T->getTypeClass() == DependentName;
}
- static bool classof(const TypenameType *T) { return true; }
+ static bool classof(const DependentNameType *T) { return true; }
};
/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for
@@ -2936,37 +3033,18 @@ inline Qualifiers::GC QualType::getObjCGCAttr() const {
return Qualifiers::GCNone;
}
- /// getNoReturnAttr - Returns true if the type has the noreturn attribute,
- /// false otherwise.
-inline bool QualType::getNoReturnAttr() const {
- QualType CT = getTypePtr()->getCanonicalTypeInternal();
- if (const PointerType *PT = getTypePtr()->getAs<PointerType>()) {
+inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) {
+ if (const PointerType *PT = t.getAs<PointerType>()) {
if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>())
- return FT->getNoReturnAttr();
- } else if (const FunctionType *FT = getTypePtr()->getAs<FunctionType>())
- return FT->getNoReturnAttr();
+ return FT->getExtInfo();
+ } else if (const FunctionType *FT = t.getAs<FunctionType>())
+ return FT->getExtInfo();
- return false;
+ return FunctionType::ExtInfo();
}
-/// getCallConv - Returns the calling convention of the type if the type
-/// is a function type, CC_Default otherwise.
-inline CallingConv QualType::getCallConv() const {
- if (const PointerType *PT = getTypePtr()->getAs<PointerType>())
- return PT->getPointeeType().getCallConv();
- else if (const ReferenceType *RT = getTypePtr()->getAs<ReferenceType>())
- return RT->getPointeeType().getCallConv();
- else if (const MemberPointerType *MPT =
- getTypePtr()->getAs<MemberPointerType>())
- return MPT->getPointeeType().getCallConv();
- else if (const BlockPointerType *BPT =
- getTypePtr()->getAs<BlockPointerType>()) {
- if (const FunctionType *FT = BPT->getPointeeType()->getAs<FunctionType>())
- return FT->getCallConv();
- } else if (const FunctionType *FT = getTypePtr()->getAs<FunctionType>())
- return FT->getCallConv();
-
- return CC_Default;
+inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) {
+ return getFunctionExtInfo(*t);
}
/// isMoreQualifiedThan - Determine whether this type is more
@@ -3152,6 +3230,15 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
return DB;
}
+/// Insertion operator for partial diagnostics. This allows sending QualType's
+/// into a diagnostic with <<.
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ QualType T) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
+ Diagnostic::ak_qualtype);
+ return PD;
+}
+
// Helper class template that is used by Type::getAs to ensure that one does
// not try to look through a qualified type to get to an array type.
template<typename T,
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 27659bd02f97..a51da7474d37 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -1242,9 +1242,9 @@ class QualifiedNameTypeLoc :
};
// FIXME: locations for the typename keyword and nested name specifier.
-class TypenameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TypenameTypeLoc,
- TypenameType> {
+class DependentNameTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
+ DependentNameTypeLoc,
+ DependentNameType> {
};
}
diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def
index e75202e50abf..7e8b73c7a5f9 100644
--- a/include/clang/AST/TypeNodes.def
+++ b/include/clang/AST/TypeNodes.def
@@ -92,7 +92,7 @@ NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type)
NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
NON_CANONICAL_TYPE(InjectedClassName, Type)
-DEPENDENT_TYPE(Typename, Type)
+DEPENDENT_TYPE(DependentName, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index bde441741227..9ebd93b75b38 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -33,7 +33,7 @@ class ParentMap;
class ImplicitParamDecl;
class LocationContextManager;
class StackFrameContext;
-
+
/// AnalysisContext contains the context data for the function or method under
/// analysis.
class AnalysisContext {
@@ -41,6 +41,7 @@ class AnalysisContext {
// AnalysisContext owns the following data.
CFG *cfg;
+ bool builtCFG;
LiveVariables *liveness;
ParentMap *PM;
llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
@@ -48,8 +49,8 @@ class AnalysisContext {
bool AddEHEdges;
public:
AnalysisContext(const Decl *d, bool addehedges = false)
- : D(d), cfg(0), liveness(0), PM(0), ReferencedBlockVars(0),
- AddEHEdges(addehedges) {}
+ : D(d), cfg(0), builtCFG(false), liveness(0), PM(0),
+ ReferencedBlockVars(0), AddEHEdges(addehedges) {}
~AnalysisContext();
@@ -69,7 +70,7 @@ public:
std::pair<referenced_decls_iterator, referenced_decls_iterator>
getReferencedBlockVars(const BlockDecl *BD);
-
+
/// Return the ImplicitParamDecl* associated with 'self' if this
/// AnalysisContext wraps an ObjCMethodDecl. Returns NULL otherwise.
const ImplicitParamDecl *getSelfDecl() const;
@@ -82,7 +83,7 @@ public:
~AnalysisContextManager();
AnalysisContext *getContext(const Decl *D);
-
+
// Discard all previously created AnalysisContexts.
void clear();
};
@@ -103,7 +104,7 @@ protected:
public:
virtual ~LocationContext();
-
+
ContextKind getKind() const { return Kind; }
AnalysisContext *getAnalysisContext() const { return Ctx; }
@@ -120,14 +121,14 @@ public:
return getAnalysisContext()->getLiveVariables();
}
- ParentMap &getParentMap() const {
+ ParentMap &getParentMap() const {
return getAnalysisContext()->getParentMap();
}
const ImplicitParamDecl *getSelfDecl() const {
return Ctx->getSelfDecl();
}
-
+
const StackFrameContext *getCurrentStackFrame() const;
const StackFrameContext *
getStackFrameForDeclContext(const DeclContext *DC) const;
@@ -157,7 +158,7 @@ class StackFrameContext : public LocationContext {
friend class LocationContextManager;
StackFrameContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s, const CFGBlock *blk, unsigned idx)
- : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
+ : LocationContext(StackFrame, ctx, parent), CallSite(s), Block(blk),
Index(idx) {}
public:
@@ -170,9 +171,9 @@ public:
unsigned getIndex() const { return Index; }
void Profile(llvm::FoldingSetNodeID &ID);
-
+
static void Profile(llvm::FoldingSetNodeID &ID, AnalysisContext *ctx,
- const LocationContext *parent, const Stmt *s,
+ const LocationContext *parent, const Stmt *s,
const CFGBlock *blk, unsigned idx) {
ProfileCommon(ID, StackFrame, ctx, parent, s);
ID.AddPointer(blk);
@@ -186,7 +187,7 @@ public:
class ScopeContext : public LocationContext {
const Stmt *Enter;
-
+
friend class LocationContextManager;
ScopeContext(AnalysisContext *ctx, const LocationContext *parent,
const Stmt *s)
@@ -229,7 +230,7 @@ public:
const LocationContext *parent, const BlockDecl *bd) {
ProfileCommon(ID, Block, ctx, parent, bd);
}
-
+
static bool classof(const LocationContext* Ctx) {
return Ctx->getKind() == Block;
}
@@ -239,7 +240,7 @@ class LocationContextManager {
llvm::FoldingSet<LocationContext> Contexts;
public:
~LocationContextManager();
-
+
const StackFrameContext *getStackFrame(AnalysisContext *ctx,
const LocationContext *parent,
const Stmt *s, const CFGBlock *blk,
@@ -248,7 +249,7 @@ public:
const ScopeContext *getScope(AnalysisContext *ctx,
const LocationContext *parent,
const Stmt *s);
-
+
/// Discard all previously created LocationContext objects.
void clear();
private:
diff --git a/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
index cbf7010bfdb5..3c762011a657 100644
--- a/include/clang/Analysis/FlowSensitive/DataflowSolver.h
+++ b/include/clang/Analysis/FlowSensitive/DataflowSolver.h
@@ -17,7 +17,8 @@
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/ProgramPoint.h"
#include "clang/Analysis/FlowSensitive/DataflowValues.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "functional" // STL
namespace clang {
@@ -28,23 +29,30 @@ namespace clang {
//===----------------------------------------------------------------------===//
class DataflowWorkListTy {
- typedef llvm::SmallPtrSet<const CFGBlock*,20> BlockSet;
- BlockSet wlist;
+ llvm::DenseMap<const CFGBlock*, unsigned char> BlockSet;
+ llvm::SmallVector<const CFGBlock *, 10> BlockQueue;
public:
/// enqueue - Add a block to the worklist. Blocks already on the
/// worklist are not added a second time.
- void enqueue(const CFGBlock* B) { wlist.insert(B); }
+ void enqueue(const CFGBlock* B) {
+ unsigned char &x = BlockSet[B];
+ if (x == 1)
+ return;
+ x = 1;
+ BlockQueue.push_back(B);
+ }
/// dequeue - Remove a block from the worklist.
const CFGBlock* dequeue() {
- assert (!wlist.empty());
- const CFGBlock* B = *wlist.begin();
- wlist.erase(B);
+ assert(!BlockQueue.empty());
+ const CFGBlock *B = BlockQueue.back();
+ BlockQueue.pop_back();
+ BlockSet[B] = 0;
return B;
}
/// isEmpty - Return true if the worklist is empty.
- bool isEmpty() const { return wlist.empty(); }
+ bool isEmpty() const { return BlockQueue.empty(); }
};
//===----------------------------------------------------------------------===//
@@ -188,10 +196,7 @@ private:
/// SolveDataflowEquations - Perform the actual worklist algorithm
/// to compute dataflow values.
void SolveDataflowEquations(CFG& cfg, bool recordStmtValues) {
- // Enqueue all blocks to ensure the dataflow values are computed
- // for every block. Not all blocks are guaranteed to reach the exit block.
- for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
- WorkList.enqueue(&**I);
+ EnqueueBlocksOnWorklist(cfg, AnalysisDirTag());
while (!WorkList.isEmpty()) {
const CFGBlock* B = WorkList.dequeue();
@@ -201,6 +206,22 @@ private:
}
}
+ void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::forward_analysis_tag) {
+ // Enqueue all blocks to ensure the dataflow values are computed
+ // for every block. Not all blocks are guaranteed to reach the exit block.
+ for (CFG::iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I)
+ WorkList.enqueue(&**I);
+ }
+
+ void EnqueueBlocksOnWorklist(CFG &cfg, dataflow::backward_analysis_tag) {
+ // Enqueue all blocks to ensure the dataflow values are computed
+ // for every block. Not all blocks are guaranteed to reach the exit block.
+ // Enqueue in reverse order since that will more likely match with
+ // the order they should ideally processed by the dataflow algorithm.
+ for (CFG::reverse_iterator I=cfg.rbegin(), E=cfg.rend(); I!=E; ++I)
+ WorkList.enqueue(&**I);
+ }
+
void ProcessMerge(CFG& cfg, const CFGBlock* B) {
ValTy& V = TF.getVal();
TF.SetTopValue(V);
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 3afdaf5b0eb1..453f660c360a 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -397,13 +397,6 @@ BUILTIN(__sync_fetch_and_xor_4, "ii*i.", "n")
BUILTIN(__sync_fetch_and_xor_8, "LLiLLi*LLi.", "n")
BUILTIN(__sync_fetch_and_xor_16, "LLLiLLLi*LLLi.", "n")
-BUILTIN(__sync_fetch_and_nand, "v.", "")
-BUILTIN(__sync_fetch_and_nand_1, "cc*c.", "n")
-BUILTIN(__sync_fetch_and_nand_2, "ss*s.", "n")
-BUILTIN(__sync_fetch_and_nand_4, "ii*i.", "n")
-BUILTIN(__sync_fetch_and_nand_8, "LLiLLi*LLi.", "n")
-BUILTIN(__sync_fetch_and_nand_16, "LLLiLLLi*LLLi.", "n")
-
BUILTIN(__sync_add_and_fetch, "v.", "")
BUILTIN(__sync_add_and_fetch_1, "cc*c.", "n")
@@ -440,14 +433,6 @@ BUILTIN(__sync_xor_and_fetch_4, "ii*i.", "n")
BUILTIN(__sync_xor_and_fetch_8, "LLiLLi*LLi.", "n")
BUILTIN(__sync_xor_and_fetch_16, "LLLiLLLi*LLLi.", "n")
-BUILTIN(__sync_nand_and_fetch, "v.", "")
-BUILTIN(__sync_nand_and_fetch_1, "cc*c.", "n")
-BUILTIN(__sync_nand_and_fetch_2, "ss*s.", "n")
-BUILTIN(__sync_nand_and_fetch_4, "ii*i.", "n")
-BUILTIN(__sync_nand_and_fetch_8, "LLiLLi*LLi.", "n")
-BUILTIN(__sync_nand_and_fetch_16, "LLLiLLLi*LLLi.", "n")
-
-
BUILTIN(__sync_bool_compare_and_swap, "v.", "")
BUILTIN(__sync_bool_compare_and_swap_1, "bcD*cc.", "n")
BUILTIN(__sync_bool_compare_and_swap_2, "bsD*ss.", "n")
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 00b076aa1004..5c75d3799bcb 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -317,4 +317,12 @@ BUILTIN(__builtin_ia32_crc32qi, "iic", "")
BUILTIN(__builtin_ia32_crc32hi, "iis", "")
BUILTIN(__builtin_ia32_crc32si, "iii", "")
BUILTIN(__builtin_ia32_crc32di, "LLiLLiLLi", "")
+
+// AES
+BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "")
+BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLii", "")
#undef BUILTIN
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index 9e643bb3c2c1..c2a4e1364a9e 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -1,8 +1,8 @@
macro(clang_diag_gen component)
- tablegen(Diagnostic${component}Kinds.inc
- -gen-clang-diags-defs -clang-component=${component})
+ tablegen(Diagnostic${component}Kinds.inc
+ -gen-clang-diags-defs -clang-component=${component})
add_custom_target(ClangDiagnostic${component}
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Diagnostic${component}Kinds.inc)
+ DEPENDS Diagnostic${component}Kinds.inc)
endmacro(clang_diag_gen)
set(LLVM_TARGET_DEFINITIONS Diagnostic.td)
@@ -17,4 +17,4 @@ clang_diag_gen(Sema)
tablegen(DiagnosticGroups.inc
-gen-clang-diag-groups)
add_custom_target(ClangDiagnosticGroups
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/DiagnosticGroups.inc)
+ DEPENDS DiagnosticGroups.inc)
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index d6c8797fc901..643868506d8f 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -95,7 +95,7 @@ namespace clang {
/// should also provide full recovery from such errors, such that
/// suppressing the diagnostic output can still result in successful
/// compilation.
-class CodeModificationHint {
+class FixItHint {
public:
/// \brief Tokens that should be removed to correct the error.
SourceRange RemoveRange;
@@ -110,7 +110,7 @@ public:
/// \brief Empty code modification hint, indicating that no code
/// modification is known.
- CodeModificationHint() : RemoveRange(), InsertionLoc() { }
+ FixItHint() : RemoveRange(), InsertionLoc() { }
bool isNull() const {
return !RemoveRange.isValid() && !InsertionLoc.isValid();
@@ -118,9 +118,9 @@ public:
/// \brief Create a code modification hint that inserts the given
/// code string at a specific location.
- static CodeModificationHint CreateInsertion(SourceLocation InsertionLoc,
- llvm::StringRef Code) {
- CodeModificationHint Hint;
+ static FixItHint CreateInsertion(SourceLocation InsertionLoc,
+ llvm::StringRef Code) {
+ FixItHint Hint;
Hint.InsertionLoc = InsertionLoc;
Hint.CodeToInsert = Code;
return Hint;
@@ -128,17 +128,17 @@ public:
/// \brief Create a code modification hint that removes the given
/// source range.
- static CodeModificationHint CreateRemoval(SourceRange RemoveRange) {
- CodeModificationHint Hint;
+ static FixItHint CreateRemoval(SourceRange RemoveRange) {
+ FixItHint Hint;
Hint.RemoveRange = RemoveRange;
return Hint;
}
/// \brief Create a code modification hint that replaces the given
/// source range with the given code string.
- static CodeModificationHint CreateReplacement(SourceRange RemoveRange,
- llvm::StringRef Code) {
- CodeModificationHint Hint;
+ static FixItHint CreateReplacement(SourceRange RemoveRange,
+ llvm::StringRef Code) {
+ FixItHint Hint;
Hint.RemoveRange = RemoveRange;
Hint.InsertionLoc = RemoveRange.getBegin();
Hint.CodeToInsert = Code;
@@ -234,6 +234,18 @@ private:
void *Cookie);
void *ArgToStringCookie;
ArgToStringFnTy ArgToStringFn;
+
+ /// \brief ID of the "delayed" diagnostic, which is a (typically
+ /// fatal) diagnostic that had to be delayed because it was found
+ /// while emitting another diagnostic.
+ unsigned DelayedDiagID;
+
+ /// \brief First string argument for the delayed diagnostic.
+ std::string DelayedDiagArg1;
+
+ /// \brief Second string argument for the delayed diagnostic.
+ std::string DelayedDiagArg2;
+
public:
explicit Diagnostic(DiagnosticClient *client = 0);
~Diagnostic();
@@ -377,6 +389,28 @@ public:
/// the diagnostic, this returns null.
static const char *getWarningOptionForDiag(unsigned DiagID);
+ /// \brief Enumeration describing how the the emission of a diagnostic should
+ /// be treated when it occurs during C++ template argument deduction.
+ enum SFINAEResponse {
+ /// \brief The diagnostic should not be reported, but it should cause
+ /// template argument deduction to fail.
+ ///
+ /// The vast majority of errors that occur during template argument
+ /// deduction fall into this category.
+ SFINAE_SubstitutionFailure,
+
+ /// \brief The diagnostic should be suppressed entirely.
+ ///
+ /// Warnings generally fall into this category.
+ SFINAE_Suppress,
+
+ /// \brief The diagnostic should be reported.
+ ///
+ /// The diagnostic should be reported. Various fatal errors (e.g.,
+ /// template instantiation depth exceeded) fall into this category.
+ SFINAE_Report
+ };
+
/// \brief Determines whether the given built-in diagnostic ID is
/// for an error that is suppressed if it occurs during C++ template
/// argument deduction.
@@ -385,7 +419,7 @@ public:
/// deduction fails but no diagnostic is emitted. Certain classes of
/// errors, such as those errors that involve C++ access control,
/// are not SFINAE errors.
- static bool isBuiltinSFINAEDiag(unsigned DiagID);
+ static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
/// object, classify the specified diagnostic ID into a Level, consumable by
@@ -400,10 +434,41 @@ public:
inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID);
inline DiagnosticBuilder Report(unsigned DiagID);
+ /// \brief Determine whethere there is already a diagnostic in flight.
+ bool isDiagnosticInFlight() const { return CurDiagID != ~0U; }
+
+ /// \brief Set the "delayed" diagnostic that will be emitted once
+ /// the current diagnostic completes.
+ ///
+ /// If a diagnostic is already in-flight but the front end must
+ /// report a problem (e.g., with an inconsistent file system
+ /// state), this routine sets a "delayed" diagnostic that will be
+ /// emitted after the current diagnostic completes. This should
+ /// only be used for fatal errors detected at inconvenient
+ /// times. If emitting a delayed diagnostic causes a second delayed
+ /// diagnostic to be introduced, that second delayed diagnostic
+ /// will be ignored.
+ ///
+ /// \param DiagID The ID of the diagnostic being delayed.
+ ///
+ /// \param Arg1 A string argument that will be provided to the
+ /// diagnostic. A copy of this string will be stored in the
+ /// Diagnostic object itself.
+ ///
+ /// \param Arg2 A string argument that will be provided to the
+ /// diagnostic. A copy of this string will be stored in the
+ /// Diagnostic object itself.
+ void SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1 = "",
+ llvm::StringRef Arg2 = "");
+
/// \brief Clear out the current diagnostic.
void Clear() { CurDiagID = ~0U; }
private:
+ /// \brief Report the delayed diagnostic.
+ void ReportDelayed();
+
+
/// getDiagnosticMappingInfo - Return the mapping info currently set for the
/// specified builtin diagnostic. This returns the high bit encoding, or zero
/// if the field is completely uninitialized.
@@ -454,8 +519,8 @@ private:
/// NumRanges - This is the number of ranges in the DiagRanges array.
unsigned char NumDiagRanges;
/// \brief The number of code modifications hints in the
- /// CodeModificationHints array.
- unsigned char NumCodeModificationHints;
+ /// FixItHints array.
+ unsigned char NumFixItHints;
/// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
/// values, with one for each argument. This specifies whether the argument
@@ -477,11 +542,11 @@ private:
/// only support 10 ranges, could easily be extended if needed.
SourceRange DiagRanges[10];
- enum { MaxCodeModificationHints = 3 };
+ enum { MaxFixItHints = 3 };
- /// CodeModificationHints - If valid, provides a hint with some code
+ /// FixItHints - If valid, provides a hint with some code
/// to insert, remove, or modify at a particular position.
- CodeModificationHint CodeModificationHints[MaxCodeModificationHints];
+ FixItHint FixItHints[MaxFixItHints];
/// ProcessDiag - This is the method used to report a diagnostic that is
/// finally fully formed.
@@ -508,13 +573,12 @@ private:
/// for example.
class DiagnosticBuilder {
mutable Diagnostic *DiagObj;
- mutable unsigned NumArgs, NumRanges, NumCodeModificationHints;
+ mutable unsigned NumArgs, NumRanges, NumFixItHints;
void operator=(const DiagnosticBuilder&); // DO NOT IMPLEMENT
friend class Diagnostic;
explicit DiagnosticBuilder(Diagnostic *diagObj)
- : DiagObj(diagObj), NumArgs(0), NumRanges(0),
- NumCodeModificationHints(0) {}
+ : DiagObj(diagObj), NumArgs(0), NumRanges(0), NumFixItHints(0) {}
public:
/// Copy constructor. When copied, this "takes" the diagnostic info from the
@@ -524,7 +588,7 @@ public:
D.DiagObj = 0;
NumArgs = D.NumArgs;
NumRanges = D.NumRanges;
- NumCodeModificationHints = D.NumCodeModificationHints;
+ NumFixItHints = D.NumFixItHints;
}
/// \brief Simple enumeration value used to give a name to the
@@ -534,7 +598,7 @@ public:
/// \brief Create an empty DiagnosticBuilder object that represents
/// no actual diagnostic.
explicit DiagnosticBuilder(SuppressKind)
- : DiagObj(0), NumArgs(0), NumRanges(0), NumCodeModificationHints(0) { }
+ : DiagObj(0), NumArgs(0), NumRanges(0), NumFixItHints(0) { }
/// \brief Force the diagnostic builder to emit the diagnostic now.
///
@@ -543,29 +607,7 @@ public:
///
/// \returns true if a diagnostic was emitted, false if the
/// diagnostic was suppressed.
- bool Emit() {
- // If DiagObj is null, then its soul was stolen by the copy ctor
- // or the user called Emit().
- if (DiagObj == 0) return false;
-
- // When emitting diagnostics, we set the final argument count into
- // the Diagnostic object.
- DiagObj->NumDiagArgs = NumArgs;
- DiagObj->NumDiagRanges = NumRanges;
- DiagObj->NumCodeModificationHints = NumCodeModificationHints;
-
- // Process the diagnostic, sending the accumulated information to the
- // DiagnosticClient.
- bool Emitted = DiagObj->ProcessDiag();
-
- // Clear out the current diagnostic object.
- DiagObj->Clear();
-
- // This diagnostic is dead.
- DiagObj = 0;
-
- return Emitted;
- }
+ bool Emit();
/// Destructor - The dtor emits the diagnostic if it hasn't already
/// been emitted.
@@ -605,14 +647,14 @@ public:
DiagObj->DiagRanges[NumRanges++] = R;
}
- void AddCodeModificationHint(const CodeModificationHint &Hint) const {
+ void AddFixItHint(const FixItHint &Hint) const {
if (Hint.isNull())
return;
- assert(NumCodeModificationHints < Diagnostic::MaxCodeModificationHints &&
- "Too many code modification hints!");
+ assert(NumFixItHints < Diagnostic::MaxFixItHints &&
+ "Too many fix-it hints!");
if (DiagObj)
- DiagObj->CodeModificationHints[NumCodeModificationHints++] = Hint;
+ DiagObj->FixItHints[NumFixItHints++] = Hint;
}
};
@@ -673,8 +715,8 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
}
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
- const CodeModificationHint &Hint) {
- DB.AddCodeModificationHint(Hint);
+ const FixItHint &Hint) {
+ DB.AddFixItHint(Hint);
return DB;
}
@@ -770,17 +812,17 @@ public:
return DiagObj->DiagRanges[Idx];
}
- unsigned getNumCodeModificationHints() const {
- return DiagObj->NumCodeModificationHints;
+ unsigned getNumFixItHints() const {
+ return DiagObj->NumFixItHints;
}
- const CodeModificationHint &getCodeModificationHint(unsigned Idx) const {
- return DiagObj->CodeModificationHints[Idx];
+ const FixItHint &getFixItHint(unsigned Idx) const {
+ return DiagObj->FixItHints[Idx];
}
- const CodeModificationHint *getCodeModificationHints() const {
- return DiagObj->NumCodeModificationHints?
- &DiagObj->CodeModificationHints[0] : 0;
+ const FixItHint *getFixItHints() const {
+ return DiagObj->NumFixItHints?
+ &DiagObj->FixItHints[0] : 0;
}
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
@@ -803,7 +845,7 @@ class StoredDiagnostic {
FullSourceLoc Loc;
std::string Message;
std::vector<SourceRange> Ranges;
- std::vector<CodeModificationHint> FixIts;
+ std::vector<FixItHint> FixIts;
public:
StoredDiagnostic();
@@ -823,7 +865,7 @@ public:
range_iterator range_end() const { return Ranges.end(); }
unsigned range_size() const { return Ranges.size(); }
- typedef std::vector<CodeModificationHint>::const_iterator fixit_iterator;
+ typedef std::vector<FixItHint>::const_iterator fixit_iterator;
fixit_iterator fixit_begin() const { return FixIts.begin(); }
fixit_iterator fixit_end() const { return FixIts.end(); }
unsigned fixit_size() const { return FixIts.size(); }
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 3a28282d5522..2e0b4bad6b5b 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -22,7 +22,7 @@ def err_fe_stdout_binary : Error<"unable to change standard output to binary">,
def err_fe_stderr_binary : Error<"unable to change standard error to binary">,
DefaultFatal;
def err_fe_dependency_file_requires_MT : Error<
- "-dependency-file requires at least one -MT option">;
+ "-dependency-file requires at least one -MT or -MQ option">;
def err_fe_incompatible_options : Error<
"'%0' cannot be used with '%1'">, DefaultFatal;
def err_fe_no_fixit_and_codegen : Error<
@@ -57,6 +57,9 @@ def err_fe_pch_malformed_block : Error<
"malformed block record in PCH file: '%0'">, DefaultFatal;
def err_fe_pch_error_at_end_block : Error<
"error at end of module block in PCH file: '%0'">, DefaultFatal;
+def err_fe_pch_file_modified : Error<
+ "file '%0' has been modified since the precompiled header was built">,
+ DefaultFatal;
def err_fe_unable_to_open_output : Error<
"unable to open output file '%0': '%1'">;
def err_fe_unable_to_open_logfile : Error<
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 203ab1eed547..b0c016bbfd28 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -31,6 +31,7 @@ def : DiagGroup<"char-align">;
def Comment : DiagGroup<"comment">;
def : DiagGroup<"ctor-dtor-privacy">;
def : DiagGroup<"declaration-after-statement">;
+def GNUDesignator : DiagGroup<"gnu-designator">;
def Deprecated : DiagGroup<"deprecated">;
def : DiagGroup<"disabled-optimization">;
def : DiagGroup<"discard-qual">;
@@ -115,6 +116,7 @@ def UnusedVariable : DiagGroup<"unused-variable">;
def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
+def Protocol : DiagGroup<"protocol">;
def SuperSubClassMismatch : DiagGroup<"super-class-method-mismatch">;
def : DiagGroup<"variadic-macros">;
def VariadicMacros : DiagGroup<"variadic-macros">;
@@ -185,3 +187,6 @@ def : DiagGroup<"comments", [Comment]>; // -Wcomments = -Wcomment
// but which aren't on by default in GCC.
def NonGCC : DiagGroup<"non-gcc",
[SignCompare, Conversion, LiteralRange]>;
+
+// A warning group for warnings about GCC extensions.
+def GNU : DiagGroup<"gnu", [GNUDesignator]>;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 9d001d48cc2a..facf15f52e85 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -50,22 +50,26 @@ def ext_enumerator_list_comma : Extension<
"feature">;
def ext_gnu_indirect_goto : Extension<
- "use of GNU indirect-goto extension">;
+ "use of GNU indirect-goto extension">, InGroup<GNU>;
def ext_gnu_address_of_label : Extension<
- "use of GNU address-of-label extension">;
+ "use of GNU address-of-label extension">, InGroup<GNU>;
def ext_gnu_statement_expr : Extension<
- "use of GNU statement expression extension">;
+ "use of GNU statement expression extension">, InGroup<GNU>;
def ext_gnu_conditional_expr : Extension<
- "use of GNU ?: expression extension, eliding middle term">;
+ "use of GNU ?: expression extension, eliding middle term">, InGroup<GNU>;
def ext_gnu_empty_initializer : Extension<
- "use of GNU empty initializer extension">;
-def ext_gnu_array_range : Extension<"use of GNU array range extension">;
+ "use of GNU empty initializer extension">, InGroup<GNU>;
+def ext_gnu_array_range : Extension<"use of GNU array range extension">,
+ InGroup<GNUDesignator>;
def ext_gnu_missing_equal_designator : ExtWarn<
- "use of GNU 'missing =' extension in designator">;
+ "use of GNU 'missing =' extension in designator">,
+ InGroup<GNUDesignator>;
def err_expected_equal_designator : Error<"expected '=' or another designator">;
def ext_gnu_old_style_field_designator : ExtWarn<
- "use of GNU old-style field designator extension">;
-def ext_gnu_case_range : Extension<"use of GNU case range extension">;
+ "use of GNU old-style field designator extension">,
+ InGroup<GNUDesignator>;
+def ext_gnu_case_range : Extension<"use of GNU case range extension">,
+ InGroup<GNU>;
// Generic errors.
def err_parse_error : Error<"parse error">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 752be5df7a12..be00972dac5c 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -68,7 +68,7 @@ def err_designator_into_flexible_array_member : Error<
def note_flexible_array_member : Note<
"initialized flexible array member %0 is here">;
def ext_flexible_array_init : Extension<
- "flexible array initialization is a GNU extension">;
+ "flexible array initialization is a GNU extension">, InGroup<GNU>;
// Declarations.
def ext_vla : Extension<
@@ -268,8 +268,6 @@ def err_duplicate_ivar_declaration : Error<
"instance variable is already declared">;
def warn_on_superclass_use : Warning<
"class implementation may not have super class">;
-def err_non_private_ivar_declaration : Error<
- "only private ivars may be declared in implementation">;
def err_conflicting_ivar_bitwidth : Error<
"instance variable %0 has conflicting bit-field width">;
def err_conflicting_ivar_name : Error<
@@ -277,7 +275,9 @@ def err_conflicting_ivar_name : Error<
def err_inconsistant_ivar_count : Error<
"inconsistent number of instance variables specified">;
def warn_incomplete_impl : Warning<"incomplete implementation">;
-def warn_undef_method_impl : Warning<"method definition for %0 not found">;
+def note_undef_method_impl : Note<"method definition for %0 not found">;
+def note_required_for_protocol_at :
+ Note<"required for direct or indirect protocol %0">;
def warn_conflicting_ret_types : Warning<
"conflicting return type in implementation of %0: %1 vs %2">;
@@ -350,7 +350,7 @@ def error_synthesized_ivar_yet_not_supported : Error<
" (need to declare %0 explicitly)">;
def error_property_ivar_type : Error<
- "type of property %0 does not match type of ivar %1">;
+ "type of property %0 (%1) does not match type of ivar %2 (%3)">;
def error_ivar_in_superclass_use : Error<
"property %0 attempting to use ivar %1 declared in super class %2">;
def error_weak_property : Error<
@@ -367,6 +367,8 @@ def warn_objc_property_attr_mutually_exclusive : Warning<
InGroup<ReadOnlySetterAttrs>, DefaultIgnore;
def warn_undeclared_selector : Warning<
"undeclared selector %0">, InGroup<UndeclaredSelector>, DefaultIgnore;
+def warn_unimplemented_protocol_method : Warning<
+ "method in protocol not implemented">, InGroup<Protocol>;
// C++ declarations
def err_static_assert_expression_is_not_constant : Error<
@@ -393,7 +395,11 @@ 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_multiple_final_overriders : Error<
+ "virtual function %q0 has more than one final overrider in %1">;
+def note_final_overrider : Note<"final overrider of %q0 in %1">;
+
def err_type_defined_in_type_specifier : Error<
"%0 can not be defined in a type specifier">;
def err_type_defined_in_result_type : Error<
@@ -432,6 +438,8 @@ def err_incompatible_exception_specs : Error<
"target exception specification is not superset of source">;
def err_deep_exception_specs_differ : Error<
"exception specifications of %select{return|argument}0 types differ">;
+def warn_missing_exception_specification : Warning<
+ "%0 is missing exception specification '%1'">;
// C++ access checking
def err_class_redeclared_with_different_access : Error<
@@ -532,6 +540,7 @@ def err_implicit_object_parameter_init : Error<
"of type %1">;
def note_field_decl : Note<"member is declared here">;
+def note_ivar_decl : Note<"ivar is declared here">;
def note_bitfield_decl : Note<"bit-field is declared here">;
def note_previous_decl : Note<"%0 declared here">;
def note_member_synthesized_at : Note<
@@ -776,8 +785,9 @@ def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning<
def warn_attribute_ignored : Warning<"%0 attribute ignored">;
def warn_attribute_precede_definition : Warning<
"attribute declaration must precede definition">;
-def warn_attribute_void_function : Warning<
- "attribute %0 cannot be applied to functions without return value">;
+def warn_attribute_void_function_method : Warning<
+ "attribute %0 cannot be applied to "
+ "%select{functions|Objective-C method}1 without return value">;
def warn_attribute_weak_on_field : Warning<
"__weak attribute cannot be specified on a field declaration">;
def warn_attribute_weak_on_local : Warning<
@@ -1199,26 +1209,40 @@ def err_template_arg_not_integral_or_enumeral : Error<
def err_template_arg_not_ice : Error<
"non-type template argument of type %0 is not an integral constant "
"expression">;
+def err_deduced_non_type_template_arg_type_mismatch : Error<
+ "deduced non-type template argument does not have the same type as the "
+ "its corresponding template parameter (%0 vs %1)">;
def err_template_arg_not_convertible : Error<
"non-type template argument of type %0 cannot be converted to a value "
"of type %1">;
-def err_template_arg_negative : Error<
- "non-type template argument provides negative value '%0' for unsigned "
- "template parameter of type %1">;
-def err_template_arg_too_large : Error<
- "non-type template argument value '%0' is too large for template "
- "parameter of type %1">;
+def warn_template_arg_negative : Warning<
+ "non-type template argument with value '%0' converted to '%1' for unsigned "
+ "template parameter of type %2">;
+def warn_template_arg_too_large : Warning<
+ "non-type template argument value '%0' truncated to '%1' for "
+ "template parameter of type %2">;
def err_template_arg_no_ref_bind : Error<
"non-type template parameter of reference type %0 cannot bind to template "
"argument of type %1">;
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<
"non-type template argument does not directly refer to an object or "
"function">;
+def err_template_arg_not_address_of : Error<
+ "non-type template argument for template parameter of pointer type %0 must "
+ "have its address taken">;
+def err_template_arg_address_of_non_pointer : Error<
+ "address taken in non-type template argument for template parameter of "
+ "reference type %0">;
+def err_template_arg_reference_var : Error<
+ "non-type template argument of reference type %0 is not an object">;
def err_template_arg_field : Error<
"non-type template argument refers to non-static data member %0">;
def err_template_arg_method : Error<
@@ -1251,6 +1275,8 @@ def err_template_spec_decl_function_scope : Error<
"explicit specialization of %0 in function scope">;
def err_template_spec_decl_class_scope : Error<
"explicit specialization of %0 in class scope">;
+def err_template_spec_decl_friend : Error<
+ "cannot declare an explicit specialization in a friend">;
def err_template_spec_decl_out_of_scope_global : Error<
"%select{class template|class template partial|function template|member "
"function|static data member|member class}0 specialization of %1 must "
@@ -1372,13 +1398,13 @@ def note_default_function_arg_instantiation_here : Note<
"for '%0' required here">;
def note_explicit_template_arg_substitution_here : Note<
"while substituting explicitly-specified template arguments into function "
- "template %f, here">;
+ "template %0 %1">;
def note_function_template_deduction_instantiation_here : Note<
- "while substituting deduced template arguments into function template %0, "
- "here">;
+ "while substituting deduced template arguments into function template %0 "
+ "%1">;
def note_partial_spec_deduct_instantiation_here : Note<
"during template argument deduction for class template partial "
- "specialization %0, here">;
+ "specialization %0 %1">;
def note_prior_template_arg_substitution : Note<
"while substituting prior template arguments into %select{non-type|template}0"
" template parameter%1 %2">;
@@ -1537,7 +1563,8 @@ def err_forward_ref_enum : Error<
"ISO C++ forbids forward references to 'enum' types">;
def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
def err_duplicate_member : Error<"duplicate member %0">;
-def err_misplaced_ivar : Error<"ivars may not be placed in categories">;
+def err_misplaced_ivar : Error<
+ "ivars may not be placed in %select{categories|class extension}0">;
def ext_enum_value_not_int : Extension<
"ISO C restricts enumerator values to range of 'int' (%0 is too "
"%select{small|large}1)">;
@@ -1575,6 +1602,8 @@ def err_typecheck_invalid_restrict_invalid_pointee : Error<
"pointer to function type %0 may not be 'restrict' qualified">;
def ext_typecheck_zero_array_size : Extension<
"zero size arrays are an extension">;
+def err_typecheck_zero_array_size : Error<
+ "zero-length arrays are not permitted in C++">;
def err_at_least_one_initializer_needed_to_size_array : Error<
"at least one initializer value required to size array">;
def err_array_size_non_int : Error<"size of array has non-integer type %0">;
@@ -1664,7 +1693,7 @@ def err_field_declared_as_function : Error<"field %0 declared as a function">;
def err_field_incomplete : Error<"field has incomplete type %0">;
def ext_variable_sized_type_in_struct : ExtWarn<
"field %0 with variable sized type %1 not at the end of a struct or class is"
- " a GNU extension">;
+ " a GNU extension">, InGroup<GNU>;
def err_flexible_array_empty_struct : Error<
"flexible array %0 not allowed in otherwise empty struct">;
@@ -2164,7 +2193,7 @@ def err_invalid_declarator_global_scope : Error<
def err_invalid_declarator_in_function : Error<
"definition or redeclaration of %0 not allowed inside a function">;
def err_not_tag_in_scope : Error<
- "%0 does not name a tag member in the specified scope">;
+ "no %select{struct|union|class|enum}0 named %1 in %2">;
def err_cannot_form_pointer_to_member_of_reference_type : Error<
"cannot form a pointer-to-member to member %0 of reference type %1">;
@@ -2322,7 +2351,8 @@ def warn_typecheck_cond_pointer_integer_mismatch : ExtWarn<
def err_typecheck_choose_expr_requires_constant : Error<
"'__builtin_choose_expr' requires a constant expression">;
def ext_typecheck_expression_not_constant_but_accepted : Extension<
- "expression is not a constant, but is accepted as one by GNU extensions">;
+ "expression is not a constant, but is accepted as one by GNU extensions">,
+ InGroup<GNU>;
def warn_unused_expr : Warning<"expression result unused">,
InGroup<UnusedValue>;
def warn_unused_property_expr : Warning<
@@ -2334,6 +2364,7 @@ def warn_unused_call : Warning<
def err_incomplete_type_used_in_type_trait_expr : Error<
"incomplete type %0 used in type trait expression">;
+def err_expected_ident_or_lparen : Error<"expected identifier or '('">;
// inline asm.
def err_asm_wide_character : Error<"wide string is invalid in 'asm'">;
@@ -2413,9 +2444,9 @@ def err_in_class_initializer_non_constant : Error<
// C++ anonymous unions and GNU anonymous structs/unions
def ext_anonymous_union : Extension<
- "anonymous unions are a GNU extension in C">;
+ "anonymous unions are a GNU extension in C">, InGroup<GNU>;
def ext_anonymous_struct : Extension<
- "anonymous structs are a GNU extension">;
+ "anonymous structs are a GNU extension">, InGroup<GNU>;
def err_anonymous_union_not_static : Error<
"anonymous unions at namespace or global scope must be declared 'static'">;
def err_anonymous_union_with_storage_spec : Error<
@@ -2584,6 +2615,9 @@ def warn_printf_missing_format_string : Warning<
def warn_printf_conversion_argument_type_mismatch : Warning<
"conversion specifies type %0 but the argument has type %1">,
InGroup<Format>;
+def warn_printf_positional_arg_exceeds_data_args : Warning <
+ "data argument position '%0' exceeds the number of data arguments (%1)">,
+ InGroup<Format>;
def warn_printf_zero_positional_specifier : Warning<
"position arguments in format strings start counting at 1 (not 0)">,
InGroup<Format>;
diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h
index fb861dcf934d..89fae87ae8ef 100644
--- a/include/clang/Basic/PartialDiagnostic.h
+++ b/include/clang/Basic/PartialDiagnostic.h
@@ -15,19 +15,18 @@
#ifndef LLVM_CLANG_PARTIALDIAGNOSTIC_H
#define LLVM_CLANG_PARTIALDIAGNOSTIC_H
-#include "clang/AST/Type.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/System/DataTypes.h"
+#include <cassert>
namespace clang {
-class DeclarationName;
-
class PartialDiagnostic {
+public:
struct Storage {
- Storage() : NumDiagArgs(0), NumDiagRanges(0), NumCodeModificationHints(0) {
- }
+ Storage() : NumDiagArgs(0), NumDiagRanges(0), NumFixItHints(0) { }
enum {
/// MaxArguments - The maximum number of arguments we can hold. We
@@ -44,8 +43,8 @@ class PartialDiagnostic {
unsigned char NumDiagRanges;
/// \brief The number of code modifications hints in the
- /// CodeModificationHints array.
- unsigned char NumCodeModificationHints;
+ /// FixItHints array.
+ unsigned char NumFixItHints;
/// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum
/// values, with one for each argument. This specifies whether the argument
@@ -62,13 +61,49 @@ class PartialDiagnostic {
/// only support 10 ranges, could easily be extended if needed.
SourceRange DiagRanges[10];
- enum { MaxCodeModificationHints = 3 };
+ enum { MaxFixItHints = 3 };
- /// CodeModificationHints - If valid, provides a hint with some code
+ /// FixItHints - If valid, provides a hint with some code
/// to insert, remove, or modify at a particular position.
- CodeModificationHint CodeModificationHints[MaxCodeModificationHints];
+ FixItHint FixItHints[MaxFixItHints];
};
+ /// \brief An allocator for Storage objects, which uses a small cache to
+ /// objects, used to reduce malloc()/free() traffic for partial diagnostics.
+ class StorageAllocator {
+ static const unsigned NumCached = 4;
+ Storage Cached[NumCached];
+ Storage *FreeList[NumCached];
+ unsigned NumFreeListEntries;
+
+ public:
+ StorageAllocator();
+ ~StorageAllocator();
+
+ /// \brief Allocate new storage.
+ Storage *Allocate() {
+ if (NumFreeListEntries == 0)
+ return new Storage;
+
+ Storage *Result = FreeList[--NumFreeListEntries];
+ Result->NumDiagArgs = 0;
+ Result->NumDiagRanges = 0;
+ Result->NumFixItHints = 0;
+ return Result;
+ }
+
+ /// \brief Free the given storage object.
+ void Deallocate(Storage *S) {
+ if (S >= Cached && S <= Cached + NumCached) {
+ FreeList[NumFreeListEntries++] = S;
+ return;
+ }
+
+ delete S;
+ }
+ };
+
+private:
// NOTE: Sema assumes that PartialDiagnostic is location-invariant
// in the sense that its bits can be safely memcpy'ed and destructed
// in the new location.
@@ -76,22 +111,40 @@ class PartialDiagnostic {
/// DiagID - The diagnostic ID.
mutable unsigned DiagID;
- /// DiagStorare - Storge for args and ranges.
+ /// DiagStorage - Storage for args and ranges.
mutable Storage *DiagStorage;
- void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
- if (!DiagStorage)
+ /// \brief Allocator used to allocate storage for this diagnostic.
+ StorageAllocator *Allocator;
+
+ /// \brief Retrieve storage for this particular diagnostic.
+ Storage *getStorage() const {
+ if (DiagStorage)
+ return DiagStorage;
+
+ if (Allocator)
+ DiagStorage = Allocator->Allocate();
+ else {
+ assert(Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)));
DiagStorage = new Storage;
+ }
+ return DiagStorage;
+ }
+
+ void freeStorage() {
+ if (!DiagStorage)
+ return;
- assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
- "Too many arguments to diagnostic!");
- DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
- DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
+ if (Allocator)
+ Allocator->Deallocate(DiagStorage);
+ else if (Allocator != reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+ delete DiagStorage;
+ DiagStorage = 0;
}
-
+
void AddSourceRange(const SourceRange &R) const {
if (!DiagStorage)
- DiagStorage = new Storage;
+ DiagStorage = getStorage();
assert(DiagStorage->NumDiagRanges <
llvm::array_lengthof(DiagStorage->DiagRanges) &&
@@ -99,53 +152,70 @@ class PartialDiagnostic {
DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R;
}
- void AddCodeModificationHint(const CodeModificationHint &Hint) const {
+ void AddFixItHint(const FixItHint &Hint) const {
if (Hint.isNull())
return;
if (!DiagStorage)
- DiagStorage = new Storage;
+ DiagStorage = getStorage();
- assert(DiagStorage->NumCodeModificationHints <
- Storage::MaxCodeModificationHints &&
+ assert(DiagStorage->NumFixItHints < Storage::MaxFixItHints &&
"Too many code modification hints!");
- DiagStorage->CodeModificationHints[DiagStorage->NumCodeModificationHints++]
+ DiagStorage->FixItHints[DiagStorage->NumFixItHints++]
= Hint;
}
public:
- PartialDiagnostic(unsigned DiagID)
- : DiagID(DiagID), DiagStorage(0) { }
-
+ PartialDiagnostic(unsigned DiagID, StorageAllocator &Allocator)
+ : DiagID(DiagID), DiagStorage(0), Allocator(&Allocator) { }
+
PartialDiagnostic(const PartialDiagnostic &Other)
- : DiagID(Other.DiagID), DiagStorage(0)
+ : DiagID(Other.DiagID), DiagStorage(0), Allocator(Other.Allocator)
{
- if (Other.DiagStorage)
- DiagStorage = new Storage(*Other.DiagStorage);
+ if (Other.DiagStorage) {
+ DiagStorage = getStorage();
+ *DiagStorage = *Other.DiagStorage;
+ }
}
+ PartialDiagnostic(const PartialDiagnostic &Other, Storage *DiagStorage)
+ : DiagID(Other.DiagID), DiagStorage(DiagStorage),
+ Allocator(reinterpret_cast<StorageAllocator *>(~uintptr_t(0)))
+ {
+ if (Other.DiagStorage)
+ *this->DiagStorage = *Other.DiagStorage;
+ }
+
PartialDiagnostic &operator=(const PartialDiagnostic &Other) {
DiagID = Other.DiagID;
if (Other.DiagStorage) {
- if (DiagStorage)
- *DiagStorage = *Other.DiagStorage;
- else
- DiagStorage = new Storage(*Other.DiagStorage);
+ if (!DiagStorage)
+ DiagStorage = getStorage();
+
+ *DiagStorage = *Other.DiagStorage;
} else {
- delete DiagStorage;
- DiagStorage = 0;
+ freeStorage();
}
return *this;
}
~PartialDiagnostic() {
- delete DiagStorage;
+ freeStorage();
}
-
unsigned getDiagID() const { return DiagID; }
+ void AddTaggedVal(intptr_t V, Diagnostic::ArgumentKind Kind) const {
+ if (!DiagStorage)
+ DiagStorage = getStorage();
+
+ assert(DiagStorage->NumDiagArgs < Storage::MaxArguments &&
+ "Too many arguments to diagnostic!");
+ DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = Kind;
+ DiagStorage->DiagArgumentsVal[DiagStorage->NumDiagArgs++] = V;
+ }
+
void Emit(const DiagnosticBuilder &DB) const {
if (!DiagStorage)
return;
@@ -161,17 +231,19 @@ public:
DB.AddSourceRange(DiagStorage->DiagRanges[i]);
// Add all code modification hints
- for (unsigned i = 0, e = DiagStorage->NumCodeModificationHints; i != e; ++i)
- DB.AddCodeModificationHint(DiagStorage->CodeModificationHints[i]);
+ for (unsigned i = 0, e = DiagStorage->NumFixItHints; i != e; ++i)
+ DB.AddFixItHint(DiagStorage->FixItHints[i]);
}
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- QualType T) {
- PD.AddTaggedVal(reinterpret_cast<intptr_t>(T.getAsOpaquePtr()),
- Diagnostic::ak_qualtype);
- return PD;
+ /// \brief Clear out this partial diagnostic, giving it a new diagnostic ID
+ /// and removing all of its arguments, ranges, and fix-it hints.
+ void Reset(unsigned DiagID = 0) {
+ this->DiagID = DiagID;
+ freeStorage();
}
-
+
+ bool hasStorage() const { return DiagStorage != 0; }
+
friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
unsigned I) {
PD.AddTaggedVal(I, Diagnostic::ak_uint);
@@ -197,20 +269,13 @@ public:
}
friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- DeclarationName N);
-
- friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
- const CodeModificationHint &Hint) {
- PD.AddCodeModificationHint(Hint);
+ const FixItHint &Hint) {
+ PD.AddFixItHint(Hint);
return PD;
}
};
-inline PartialDiagnostic PDiag(unsigned DiagID = 0) {
- return PartialDiagnostic(DiagID);
-}
-
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
const PartialDiagnostic &PD) {
PD.Emit(DB);
@@ -219,4 +284,4 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
} // end namespace clang
-#endif
+#endif
diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h
index f7ea331e1cc7..555e6f5a919a 100644
--- a/include/clang/Basic/SourceLocation.h
+++ b/include/clang/Basic/SourceLocation.h
@@ -28,7 +28,6 @@ namespace llvm {
namespace clang {
class SourceManager;
-class FileEntry;
/// FileID - This is an opaque identifier used by SourceManager which refers to
/// a source file (MemoryBuffer) along with its #include path and #line data.
diff --git a/include/clang/Checker/BugReporter/BugReporter.h b/include/clang/Checker/BugReporter/BugReporter.h
index 2c15f2a40576..617034292638 100644
--- a/include/clang/Checker/BugReporter/BugReporter.h
+++ b/include/clang/Checker/BugReporter/BugReporter.h
@@ -15,17 +15,12 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGREPORTER
#define LLVM_CLANG_ANALYSIS_BUGREPORTER
-#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Checker/BugReporter/BugType.h"
-#include "clang/Checker/PathSensitive/ExplodedGraph.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableList.h"
#include "llvm/ADT/ImmutableSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallString.h"
#include <list>
namespace clang {
@@ -35,6 +30,8 @@ class PathDiagnosticPiece;
class PathDiagnosticClient;
class ASTContext;
class Diagnostic;
+class ExplodedNode;
+class ExplodedGraph;
class BugReporter;
class BugReporterContext;
class GRExprEngine;
diff --git a/include/clang/Checker/BugReporter/BugType.h b/include/clang/Checker/BugReporter/BugType.h
index 4f1523a5440d..afc07c89e86f 100644
--- a/include/clang/Checker/BugReporter/BugType.h
+++ b/include/clang/Checker/BugReporter/BugType.h
@@ -14,15 +14,12 @@
#ifndef LLVM_CLANG_ANALYSIS_BUGTYPE
#define LLVM_CLANG_ANALYSIS_BUGTYPE
-#include <llvm/ADT/FoldingSet.h>
+#include "clang/Checker/BugReporter/BugReporter.h"
+#include "llvm/ADT/FoldingSet.h"
#include <string>
namespace clang {
-class BugReportEquivClass;
-class BugReporter;
-class BuiltinBugReport;
-class BugReporterContext;
class ExplodedNode;
class GRExprEngine;
diff --git a/include/clang/Checker/BugReporter/PathDiagnostic.h b/include/clang/Checker/BugReporter/PathDiagnostic.h
index d380c45480cb..24c75ce7b228 100644
--- a/include/clang/Checker/BugReporter/PathDiagnostic.h
+++ b/include/clang/Checker/BugReporter/PathDiagnostic.h
@@ -168,7 +168,7 @@ public:
private:
const std::string str;
- std::vector<CodeModificationHint> CodeModificationHints;
+ std::vector<FixItHint> FixItHints;
const Kind kind;
const DisplayHint Hint;
std::vector<SourceRange> ranges;
@@ -203,8 +203,8 @@ public:
ranges.push_back(SourceRange(B,E));
}
- void addCodeModificationHint(const CodeModificationHint& Hint) {
- CodeModificationHints.push_back(Hint);
+ void addFixItHint(const FixItHint& Hint) {
+ FixItHints.push_back(Hint);
}
typedef const SourceRange* range_iterator;
@@ -217,15 +217,15 @@ public:
return ranges_begin() + ranges.size();
}
- typedef const CodeModificationHint *code_modifications_iterator;
+ typedef const FixItHint *fixit_iterator;
- code_modifications_iterator code_modifications_begin() const {
- return CodeModificationHints.empty()? 0 : &CodeModificationHints[0];
+ fixit_iterator fixit_begin() const {
+ return FixItHints.empty()? 0 : &FixItHints[0];
}
- code_modifications_iterator code_modifications_end() const {
- return CodeModificationHints.empty()? 0
- : &CodeModificationHints[0] + CodeModificationHints.size();
+ fixit_iterator fixit_end() const {
+ return FixItHints.empty()? 0
+ : &FixItHints[0] + FixItHints.size();
}
static inline bool classof(const PathDiagnosticPiece* P) {
diff --git a/include/clang/Checker/DomainSpecific/CocoaConventions.h b/include/clang/Checker/DomainSpecific/CocoaConventions.h
index ee3d648b8608..4bbdab0e7fe1 100644
--- a/include/clang/Checker/DomainSpecific/CocoaConventions.h
+++ b/include/clang/Checker/DomainSpecific/CocoaConventions.h
@@ -14,7 +14,6 @@
#ifndef LLVM_CLANG_CHECKER_DS_COCOA
#define LLVM_CLANG_CHECKER_DS_COCOA
-#include "clang/Basic/IdentifierTable.h"
#include "clang/AST/Type.h"
namespace clang {
diff --git a/include/clang/Checker/PathSensitive/BasicValueFactory.h b/include/clang/Checker/PathSensitive/BasicValueFactory.h
index 2f0b6c2a0348..59dd9190d25e 100644
--- a/include/clang/Checker/PathSensitive/BasicValueFactory.h
+++ b/include/clang/Checker/PathSensitive/BasicValueFactory.h
@@ -16,7 +16,6 @@
#ifndef LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
#define LLVM_CLANG_ANALYSIS_BASICVALUEFACTORY_H
-#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ADT/FoldingSet.h"
diff --git a/include/clang/Checker/PathSensitive/Checker.h b/include/clang/Checker/PathSensitive/Checker.h
index 2401a72741b2..8cb9cc8337c6 100644
--- a/include/clang/Checker/PathSensitive/Checker.h
+++ b/include/clang/Checker/PathSensitive/Checker.h
@@ -14,21 +14,15 @@
#ifndef LLVM_CLANG_ANALYSIS_CHECKER
#define LLVM_CLANG_ANALYSIS_CHECKER
+
#include "clang/Analysis/Support/SaveAndRestore.h"
-#include "clang/Checker/PathSensitive/GRCoreEngine.h"
-#include "clang/Checker/PathSensitive/GRState.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/ExprObjC.h"
-#include "clang/AST/StmtCXX.h"
-#include "clang/AST/StmtObjC.h"
//===----------------------------------------------------------------------===//
// Checker interface.
//===----------------------------------------------------------------------===//
namespace clang {
- class GRExprEngine;
class CheckerContext {
ExplodedNodeSet &Dst;
diff --git a/include/clang/Checker/PathSensitive/Environment.h b/include/clang/Checker/PathSensitive/Environment.h
index 6051654f4855..b9bbebc652f2 100644
--- a/include/clang/Checker/PathSensitive/Environment.h
+++ b/include/clang/Checker/PathSensitive/Environment.h
@@ -18,11 +18,8 @@
// typedefs.
#include "clang/Checker/PathSensitive/Store.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/SmallVector.h"
#include "clang/Checker/PathSensitive/SVals.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ImmutableMap.h"
namespace clang {
diff --git a/include/clang/Checker/PathSensitive/ExplodedGraph.h b/include/clang/Checker/PathSensitive/ExplodedGraph.h
index d6c4436c594c..c09c89312e10 100644
--- a/include/clang/Checker/PathSensitive/ExplodedGraph.h
+++ b/include/clang/Checker/PathSensitive/ExplodedGraph.h
@@ -9,6 +9,10 @@
//
// This file defines the template classes ExplodedNode and ExplodedGraph,
// which represent a path-sensitive, intra-procedural "exploded graph."
+// See "Precise interprocedural dataflow analysis via graph reachability"
+// by Reps, Horwitz, and Sagiv
+// (http://portal.acm.org/citation.cfm?id=199462) for the definition of an
+// exploded graph.
//
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Checker/PathSensitive/GRBlockCounter.h b/include/clang/Checker/PathSensitive/GRBlockCounter.h
index 67ed9532db02..b7d0e8ae0c71 100644
--- a/include/clang/Checker/PathSensitive/GRBlockCounter.h
+++ b/include/clang/Checker/PathSensitive/GRBlockCounter.h
@@ -22,6 +22,8 @@ namespace llvm {
namespace clang {
+class StackFrameContext;
+
class GRBlockCounter {
void* Data;
@@ -30,7 +32,8 @@ class GRBlockCounter {
public:
GRBlockCounter() : Data(0) {}
- unsigned getNumVisited(unsigned BlockID) const;
+ unsigned getNumVisited(const StackFrameContext *CallSite,
+ unsigned BlockID) const;
class Factory {
void* F;
@@ -39,7 +42,9 @@ public:
~Factory();
GRBlockCounter GetEmptyCounter();
- GRBlockCounter IncrementCount(GRBlockCounter BC, unsigned BlockID);
+ GRBlockCounter IncrementCount(GRBlockCounter BC,
+ const StackFrameContext *CallSite,
+ unsigned BlockID);
};
friend class Factory;
diff --git a/include/clang/Checker/PathSensitive/GRCoreEngine.h b/include/clang/Checker/PathSensitive/GRCoreEngine.h
index c5bf5138a63f..a3ff0dbedc7b 100644
--- a/include/clang/Checker/PathSensitive/GRCoreEngine.h
+++ b/include/clang/Checker/PathSensitive/GRCoreEngine.h
@@ -82,7 +82,7 @@ class GRCoreEngine {
void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
- bool ProcessBlockEntrance(CFGBlock* Blk, const GRState* State,
+ bool ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
GRBlockCounter BC);
@@ -174,7 +174,9 @@ public:
GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
unsigned getCurrentBlockCount() const {
- return getBlockCounter().getNumVisited(B.getBlockID());
+ return getBlockCounter().getNumVisited(
+ Pred->getLocationContext()->getCurrentStackFrame(),
+ B.getBlockID());
}
ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
@@ -434,7 +436,9 @@ public:
}
unsigned getCurrentBlockCount() const {
- return getBlockCounter().getNumVisited(B.getBlockID());
+ return getBlockCounter().getNumVisited(
+ Pred->getLocationContext()->getCurrentStackFrame(),
+ B.getBlockID());
}
ExplodedNode* generateNode(const GRState* State, const void *tag = 0,
diff --git a/include/clang/Checker/PathSensitive/GRExprEngine.h b/include/clang/Checker/PathSensitive/GRExprEngine.h
index 916511e8bd09..161cb28df033 100644
--- a/include/clang/Checker/PathSensitive/GRExprEngine.h
+++ b/include/clang/Checker/PathSensitive/GRExprEngine.h
@@ -16,7 +16,6 @@
#ifndef LLVM_CLANG_ANALYSIS_GREXPRENGINE
#define LLVM_CLANG_ANALYSIS_GREXPRENGINE
-#include "clang/Checker/PathSensitive/AnalysisManager.h"
#include "clang/Checker/PathSensitive/GRSubEngine.h"
#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
@@ -28,11 +27,9 @@
#include "clang/AST/ExprCXX.h"
namespace clang {
-
- class PathDiagnosticClient;
- class Diagnostic;
- class ObjCForCollectionStmt;
- class Checker;
+class AnalysisManager;
+class Checker;
+class ObjCForCollectionStmt;
class GRExprEngine : public GRSubEngine {
AnalysisManager &AMgr;
@@ -153,7 +150,7 @@ public:
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue
/// exploring the given path, and false otherwise.
- bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
+ bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
GRBlockCounter BC);
/// ProcessBranch - Called by GRCoreEngine. Used to generate successor
@@ -216,7 +213,7 @@ public:
const GRState* St,
ProgramPoint::Kind K = ProgramPoint::PostStmtKind,
const void *tag = 0);
-protected:
+
/// CheckerVisit - Dispatcher for performing checker-specific logic
/// at specific statements.
void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src,
@@ -351,10 +348,21 @@ protected:
void VisitCXXConstructExpr(const CXXConstructExpr *E, SVal Dest,
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
+
+ void VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
+ void VisitAggExpr(const Expr *E, SVal Dest, ExplodedNode *Pred,
+ ExplodedNodeSet &Dst);
+
/// Create a C++ temporary object for an rvalue.
void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred,
ExplodedNodeSet &Dst);
+ /// Synthesize CXXThisRegion.
+ const CXXThisRegion *getCXXThisRegion(const CXXMethodDecl *MD,
+ const StackFrameContext *SFC);
+
/// 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/GRSimpleAPICheck.h b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
index 383463b822cb..6d85e5fe6a90 100644
--- a/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
+++ b/include/clang/Checker/PathSensitive/GRSimpleAPICheck.h
@@ -17,18 +17,9 @@
#define LLVM_CLANG_ANALYSIS_GRAPICHECKS
#include "clang/Checker/PathSensitive/GRAuditor.h"
-#include "clang/Checker/PathSensitive/GRState.h"
namespace clang {
-class Diagnostic;
-class BugReporter;
-class ASTContext;
-class GRExprEngine;
-class PathDiagnosticClient;
-class ExplodedGraph;
-
-
class GRSimpleAPICheck : public GRAuditor {
public:
GRSimpleAPICheck() {}
diff --git a/include/clang/Checker/PathSensitive/GRState.h b/include/clang/Checker/PathSensitive/GRState.h
index 657266b7508d..25ba1f85fdff 100644
--- a/include/clang/Checker/PathSensitive/GRState.h
+++ b/include/clang/Checker/PathSensitive/GRState.h
@@ -14,30 +14,22 @@
#ifndef LLVM_CLANG_ANALYSIS_VALUESTATE_H
#define LLVM_CLANG_ANALYSIS_VALUESTATE_H
-// FIXME: Reduce the number of includes.
-
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
-#include "clang/AST/Expr.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Checker/PathSensitive/ConstraintManager.h"
#include "clang/Checker/PathSensitive/Environment.h"
-#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/Store.h"
#include "clang/Checker/PathSensitive/ValueManager.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/DataTypes.h"
-#include <functional>
-namespace clang {
+namespace llvm {
+class APSInt;
+class BumpPtrAllocator;
+class raw_ostream;
+}
+namespace clang {
+class ASTContext;
class GRStateManager;
class Checker;
@@ -302,6 +294,8 @@ public:
template<typename T>
const GRState *remove(typename GRStateTrait<T>::key_type K,
typename GRStateTrait<T>::context_type C) const;
+ template <typename T>
+ const GRState *remove() const;
template<typename T>
const GRState *set(typename GRStateTrait<T>::data_type D) const;
@@ -464,6 +458,7 @@ public:
// Methods that manipulate the GDM.
const GRState* addGDM(const GRState* St, void* Key, void* Data);
+ const GRState *removeGDM(const GRState *state, void *Key);
// Methods that query & manipulate the Store.
@@ -528,6 +523,10 @@ public:
GRStateTrait<T>::MakeVoidPtr(GRStateTrait<T>::Remove(st->get<T>(), K, C)));
}
+ template <typename T>
+ const GRState *remove(const GRState *st) {
+ return removeGDM(st, GRStateTrait<T>::GDMIndex());
+ }
void* FindGDMContext(void* index,
void* (*CreateContext)(llvm::BumpPtrAllocator&),
@@ -702,6 +701,11 @@ const GRState *GRState::remove(typename GRStateTrait<T>::key_type K,
return getStateManager().remove<T>(this, K, C);
}
+template <typename T>
+const GRState *GRState::remove() const {
+ return getStateManager().remove<T>(this);
+}
+
template<typename T>
const GRState *GRState::set(typename GRStateTrait<T>::data_type D) const {
return getStateManager().set<T>(this, D);
diff --git a/include/clang/Checker/PathSensitive/GRSubEngine.h b/include/clang/Checker/PathSensitive/GRSubEngine.h
index f2cd0486e326..d2e7457ea93d 100644
--- a/include/clang/Checker/PathSensitive/GRSubEngine.h
+++ b/include/clang/Checker/PathSensitive/GRSubEngine.h
@@ -20,6 +20,7 @@ namespace clang {
class Stmt;
class CFGBlock;
class CFGElement;
+class ExplodedNode;
class GRState;
class GRStateManager;
class GRBlockCounter;
@@ -47,7 +48,7 @@ public:
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue
/// exploring the given path, and false otherwise.
- virtual bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
+ virtual bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
GRBlockCounter BC) = 0;
/// ProcessBranch - Called by GRCoreEngine. Used to generate successor
diff --git a/include/clang/Checker/PathSensitive/GRTransferFuncs.h b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
index 04634effd587..13325edea778 100644
--- a/include/clang/Checker/PathSensitive/GRTransferFuncs.h
+++ b/include/clang/Checker/PathSensitive/GRTransferFuncs.h
@@ -15,16 +15,18 @@
#ifndef LLVM_CLANG_ANALYSIS_GRTF
#define LLVM_CLANG_ANALYSIS_GRTF
-#include "clang/Checker/PathSensitive/SVals.h"
-#include "clang/Checker/PathSensitive/GRCoreEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
+#include "clang/Checker/PathSensitive/SVals.h"
#include <vector>
namespace clang {
-
+class ExplodedNode;
+class ExplodedNodeSet;
+class GREndPathNodeBuilder;
class GRExprEngine;
-class ObjCMessageExpr;
+class GRStmtNodeBuilder;
class GRStmtNodeBuilderRef;
+class ObjCMessageExpr;
class GRTransferFuncs {
public:
diff --git a/include/clang/Checker/PathSensitive/MemRegion.h b/include/clang/Checker/PathSensitive/MemRegion.h
index be89d2a3eb88..57ea8a3f6d9d 100644
--- a/include/clang/Checker/PathSensitive/MemRegion.h
+++ b/include/clang/Checker/PathSensitive/MemRegion.h
@@ -18,17 +18,15 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/Checker/PathSensitive/SymbolManager.h"
#include "clang/Checker/PathSensitive/SVals.h"
-#include "clang/AST/ASTContext.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableList.h"
-#include "llvm/ADT/ImmutableMap.h"
-#include "llvm/Support/Allocator.h"
#include <string>
-namespace llvm { class raw_ostream; }
+namespace llvm {
+class BumpPtrAllocator;
+class raw_ostream;
+}
namespace clang {
diff --git a/include/clang/Checker/PathSensitive/Store.h b/include/clang/Checker/PathSensitive/Store.h
index edc338012ada..72565f4d740d 100644
--- a/include/clang/Checker/PathSensitive/Store.h
+++ b/include/clang/Checker/PathSensitive/Store.h
@@ -18,9 +18,6 @@
#include "clang/Checker/PathSensitive/SVals.h"
#include "clang/Checker/PathSensitive/ValueManager.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
namespace clang {
diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h
index b6630c3d97d2..dea877c0657f 100644
--- a/include/clang/Checker/PathSensitive/SymbolManager.h
+++ b/include/clang/Checker/PathSensitive/SymbolManager.h
@@ -17,14 +17,14 @@
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
-#include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/AnalysisContext.h"
#include "llvm/System/DataTypes.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/DenseSet.h"
namespace llvm {
- class raw_ostream;
+class BumpPtrAllocator;
+class raw_ostream;
}
namespace clang {
@@ -34,9 +34,6 @@ namespace clang {
class TypedRegion;
class VarRegion;
class StackFrameContext;
-}
-
-namespace clang {
class SymExpr : public llvm::FoldingSetNode {
public:
@@ -247,6 +244,7 @@ public:
QualType t)
: SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {}
+ BinaryOperator::Opcode getOpcode() const { return Op; }
const SymExpr *getLHS() const { return LHS; }
const SymExpr *getRHS() const { return RHS; }
diff --git a/include/clang/CodeGen/CodeGenOptions.h b/include/clang/CodeGen/CodeGenOptions.h
index 85c6c3e3abcf..638ed516ed0b 100644
--- a/include/clang/CodeGen/CodeGenOptions.h
+++ b/include/clang/CodeGen/CodeGenOptions.h
@@ -15,7 +15,6 @@
#define LLVM_CLANG_CODEGEN_CODEGENOPTIONS_H
#include <string>
-#include <vector>
namespace clang {
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index feebbc78864f..124288a76305 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -156,6 +156,7 @@ def dependency_file : Separate<"-dependency-file">,
HelpText<"Filename (or -) to write dependency output to">;
def sys_header_deps : Flag<"-sys-header-deps">,
HelpText<"Include system headers in dependency output">;
+def MQ : Separate<"-MQ">, HelpText<"Specify target to quote for dependency">;
def MT : Separate<"-MT">, HelpText<"Specify target for dependency">;
def MP : Flag<"-MP">,
HelpText<"Create phony target for each dependency (other than main file)">;
@@ -407,6 +408,8 @@ def fwritable_strings : Flag<"-fwritable-strings">,
def nostdinc : Flag<"-nostdinc">,
HelpText<"Disable standard #include directories">;
+def nostdincxx : Flag<"-nostdinc++">,
+ HelpText<"Disable standard #include directories for the C++ standard library">;
def nobuiltininc : Flag<"-nobuiltininc">,
HelpText<"Disable builtin #include directories">;
def F : JoinedOrSeparate<"-F">, MetaVarName<"<directory>">,
diff --git a/include/clang/Driver/CMakeLists.txt b/include/clang/Driver/CMakeLists.txt
index f720d15d8ccc..ed9825b59df5 100644
--- a/include/clang/Driver/CMakeLists.txt
+++ b/include/clang/Driver/CMakeLists.txt
@@ -2,10 +2,10 @@ set(LLVM_TARGET_DEFINITIONS Options.td)
tablegen(Options.inc
-gen-opt-parser-defs)
add_custom_target(ClangDriverOptions
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Options.inc)
+ DEPENDS Options.inc)
set(LLVM_TARGET_DEFINITIONS CC1Options.td)
tablegen(CC1Options.inc
-gen-opt-parser-defs)
add_custom_target(ClangCC1Options
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CC1Options.inc)
+ DEPENDS CC1Options.inc)
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index f49c3b97c1c4..90c3a0dcdc18 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -64,6 +64,12 @@ public:
/// The path to the compiler resource directory.
std::string ResourceDir;
+ /// A prefix directory used to emulated a limited subset of GCC's '-Bprefix'
+ /// functionality.
+ /// FIXME: This type of customization should be removed in favor of the
+ /// universal driver when it is ready.
+ std::string PrefixDir;
+
/// Default host triple.
std::string DefaultHostTriple;
@@ -133,7 +139,8 @@ public:
Driver(llvm::StringRef _Name, llvm::StringRef _Dir,
llvm::StringRef _DefaultHostTriple,
llvm::StringRef _DefaultImageName,
- bool IsProduction, Diagnostic &_Diags);
+ bool IsProduction, bool CXXIsProduction,
+ Diagnostic &_Diags);
~Driver();
/// @name Accessors
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 71258f9814be..d088be04c03e 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -118,7 +118,7 @@ def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>,
HelpText<"Print the commands to run for this compilation">;
def A : JoinedOrSeparate<"-A">;
-def B : JoinedOrSeparate<"-B">, Flags<[Unsupported]>;
+def B : JoinedOrSeparate<"-B">;
def CC : Flag<"-CC">;
def C : Flag<"-C">;
def D : JoinedOrSeparate<"-D">, Group<CompileOnly_Group>;
@@ -470,6 +470,7 @@ def noprebind : Flag<"-noprebind">;
def noseglinkedit : Flag<"-noseglinkedit">;
def nostartfiles : Flag<"-nostartfiles">;
def nostdinc : Flag<"-nostdinc">;
+def nostdincxx : Flag<"-nostdinc++">;
def nostdlib : Flag<"-nostdlib">;
def object : Flag<"-object">;
def o : JoinedOrSeparate<"-o">, Flags<[DriverOption, RenderAsInput]>,
diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h
index 690408547c0d..c6682451835a 100644
--- a/include/clang/Frontend/HeaderSearchOptions.h
+++ b/include/clang/Frontend/HeaderSearchOptions.h
@@ -71,13 +71,17 @@ public:
/// Include the system standard include search directories.
unsigned UseStandardIncludes : 1;
+ /// Include the system standard C++ library include search directories.
+ unsigned UseStandardCXXIncludes : 1;
+
/// Whether header search information should be output as for -v.
unsigned Verbose : 1;
public:
HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
: Sysroot(_Sysroot), UseBuiltinIncludes(true),
- UseStandardIncludes(true), Verbose(false) {}
+ UseStandardIncludes(true), UseStandardCXXIncludes(true),
+ Verbose(false) {}
/// AddPath - Add the \arg Path path to the specified \arg Group list.
void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h
index d09e51fd0184..157876b59d34 100644
--- a/include/clang/Frontend/TextDiagnosticPrinter.h
+++ b/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -69,7 +69,7 @@ public:
void EmitCaretDiagnostic(SourceLocation Loc,
SourceRange *Ranges, unsigned NumRanges,
SourceManager &SM,
- const CodeModificationHint *Hints,
+ const FixItHint *Hints,
unsigned NumHints,
unsigned Columns);
diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def
index dd5018af82aa..3add99a941c4 100644
--- a/include/clang/Frontend/TypeXML.def
+++ b/include/clang/Frontend/TypeXML.def
@@ -233,7 +233,7 @@ NODE_XML(QualifiedNameType, "QualifiedNameType")
TYPE_ATTRIBUTE_XML(getNamedType())
END_NODE_XML
-NODE_XML(TypenameType, "TypenameType")
+NODE_XML(DependentNameType, "DependentNameType")
ID_ATTRIBUTE_XML
END_NODE_XML
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index dd24fb7d7ba2..e891e94d4cbc 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -44,6 +44,12 @@ public:
SrcMgr::CharacteristicKind FileType) {
}
+
+ /// EndOfMainFile - This callback is invoked when the end of the main file is
+ /// reach, no subsequent callbacks will be made.
+ virtual void EndOfMainFile() {
+ }
+
/// Ident - This callback is invoked when a #ident or #sccs directive is read.
///
virtual void Ident(SourceLocation Loc, const std::string &str) {
@@ -90,6 +96,11 @@ public:
Second->FileChanged(Loc, Reason, FileType);
}
+ virtual void EndOfMainFile() {
+ First->EndOfMainFile();
+ Second->EndOfMainFile();
+ }
+
virtual void Ident(SourceLocation Loc, const std::string &str) {
First->Ident(Loc, str);
Second->Ident(Loc, str);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 23c118d1fc63..312a760e01d3 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -368,6 +368,10 @@ public:
/// which implicitly adds the builtin defines etc.
bool 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.
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 85c44c5a0b80..477a2130cf0e 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -21,6 +21,7 @@
namespace clang {
+class FileEntry;
class Preprocessor;
class PreprocessorLexer {
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index b79e698d50c9..59cc0d218cec 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -1761,7 +1761,8 @@ public:
virtual void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
DeclPtrTy TagDecl,
SourceLocation LBrac,
- SourceLocation RBrac) {
+ SourceLocation RBrac,
+ AttributeList *AttrList) {
}
//===---------------------------C++ Templates----------------------------===//