diff options
author | dim <dim@FreeBSD.org> | 2011-06-12 15:46:16 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-06-12 15:46:16 +0000 |
commit | c49018d9cce52d8c9f34b44865ec3ba8e89a1488 (patch) | |
tree | c5e9e10bc189de0058aa763c47b9920a8351b7df /include/clang | |
parent | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (diff) | |
download | FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.zip FreeBSD-src-c49018d9cce52d8c9f34b44865ec3ba8e89a1488.tar.gz |
Vendor import of clang trunk r132879:
http://llvm.org/svn/llvm-project/cfe/trunk@132879
Diffstat (limited to 'include/clang')
73 files changed, 1758 insertions, 389 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index 5effa90..fec7d29 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -85,10 +85,10 @@ public: APValue(const APValue &RHS) : Kind(Uninitialized) { *this = RHS; } - APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) { + APValue(const Expr* B, const CharUnits &O) : Kind(Uninitialized) { MakeLValue(); setLValue(B, O); } - APValue(Expr* B); + APValue(const Expr* B); ~APValue() { MakeUninit(); @@ -167,7 +167,7 @@ public: return const_cast<APValue*>(this)->getComplexFloatImag(); } - Expr* getLValueBase() const; + const Expr* getLValueBase() const; CharUnits getLValueOffset() const; void setInt(const APSInt &I) { @@ -199,7 +199,7 @@ public: ((ComplexAPFloat*)(char*)Data)->Real = R; ((ComplexAPFloat*)(char*)Data)->Imag = I; } - void setLValue(Expr *B, const CharUnits &O); + void setLValue(const Expr *B, const CharUnits &O); const APValue &operator=(const APValue &RHS); diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 28ec8cf..517c25d 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -406,6 +406,21 @@ public: /// bitfield which follows the bitfield 'LastFD'. bool ZeroBitfieldFollowsBitfield(const FieldDecl *FD, const FieldDecl *LastFD) const; + + /// BitfieldFollowsBitfield - return 'true" if 'FD' is a + /// bitfield which follows the bitfield 'LastFD'. + bool BitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// NoneBitfieldFollowsBitfield - return 'true" if 'FD' is not a + /// bitfield which follows the bitfield 'LastFD'. + bool NoneBitfieldFollowsBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; + + /// BitfieldFollowsNoneBitfield - return 'true" if 'FD' is a + /// bitfield which follows the none bitfield 'LastFD'. + bool BitfieldFollowsNoneBitfield(const FieldDecl *FD, + const FieldDecl *LastFD) const; // Access to the set of methods overridden by the given C++ method. typedef CXXMethodVector::iterator overridden_cxx_method_iterator; @@ -764,6 +779,10 @@ public: /// getDecltypeType - C++0x decltype. QualType getDecltypeType(Expr *e) const; + /// getUnaryTransformType - unary type transforms + QualType getUnaryTransformType(QualType BaseType, QualType UnderlyingType, + UnaryTransformType::UTTKind UKind) const; + /// getAutoType - C++0x deduced auto type. QualType getAutoType(QualType DeducedType) const; @@ -895,12 +914,18 @@ public: std::string &S) const; /// getObjCEncodingForFunctionDecl - Returns the encoded type for this - //function. This is in the same format as Objective-C method encodings. - void getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); + /// function. This is in the same format as Objective-C method encodings. + /// + /// \returns true if an error occurred (e.g., because one of the parameter + /// types is incomplete), false otherwise. + bool getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, std::string& S); /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. - void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S) + /// + /// \returns true if an error occurred (e.g., because one of the parameter + /// types is incomplete), false otherwise. + bool getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S) const; /// getObjCEncodingForBlock - Return the encoded type for this block @@ -1438,7 +1463,8 @@ public: /// MakeIntValue - Make an APSInt of the appropriate width and /// signedness for the given \arg Value and integer \arg Type. llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const { - llvm::APSInt Res(getIntWidth(Type), !Type->isSignedIntegerType()); + llvm::APSInt Res(getIntWidth(Type), + !Type->isSignedIntegerOrEnumerationType()); Res = Value; return Res; } @@ -1526,6 +1552,13 @@ public: /// which declarations were built. static unsigned NumImplicitCopyConstructorsDeclared; + /// \brief The number of implicitly-declared move constructors. + static unsigned NumImplicitMoveConstructors; + + /// \brief The number of implicitly-declared move constructors for + /// which declarations were built. + static unsigned NumImplicitMoveConstructorsDeclared; + /// \brief The number of implicitly-declared copy assignment operators. static unsigned NumImplicitCopyAssignmentOperators; @@ -1533,6 +1566,13 @@ public: /// which declarations were built. static unsigned NumImplicitCopyAssignmentOperatorsDeclared; + /// \brief The number of implicitly-declared move assignment operators. + static unsigned NumImplicitMoveAssignmentOperators; + + /// \brief The number of implicitly-declared move assignment operators for + /// which declarations were built. + static unsigned NumImplicitMoveAssignmentOperatorsDeclared; + /// \brief The number of implicitly-declared destructors. static unsigned NumImplicitDestructors; @@ -1553,7 +1593,13 @@ private: bool ExpandStructures, const FieldDecl *Field, bool OutermostType = false, - bool EncodingProperty = false) const; + bool EncodingProperty = false, + bool StructField = false) const; + + // Adds the encoding of the structure's members. + void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S, + const FieldDecl *Field, + bool includeVBases = true) const; const ASTRecordLayout & getObjCLayout(const ObjCInterfaceDecl *D, diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index b3550f8..2518814 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -291,6 +291,8 @@ public: LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerOrEnumerationType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnsignedIntegerOrEnumerationType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isConstantSizeType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType) @@ -630,6 +632,14 @@ struct CanProxyAdaptor<DecltypeType> : public CanProxyBase<DecltypeType> { LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) }; +template <> +struct CanProxyAdaptor<UnaryTransformType> + : public CanProxyBase<UnaryTransformType> { + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getBaseType) + LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getUnderlyingType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(UnaryTransformType::UTTKind, getUTTKind) +}; + template<> struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> { LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index ef49205..d993d34 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1365,6 +1365,8 @@ private: bool HasWrittenPrototype : 1; bool IsDeleted : 1; bool IsTrivial : 1; // sunk from CXXMethodDecl + bool IsDefaulted : 1; // sunk from CXXMethoDecl + bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl bool HasImplicitReturnZero : 1; bool IsLateTemplateParsed : 1; @@ -1448,6 +1450,7 @@ protected: IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), + IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), @@ -1512,6 +1515,20 @@ public: return hasBody(Definition); } + /// hasTrivialBody - Returns whether the function has a trivial body that does + /// not require any specific codegen. + bool hasTrivialBody() const; + + /// isDefined - Returns true if the function is defined at all, including + /// a deleted definition. Except for the behavior when the function is + /// deleted, behaves like hasBody. + bool isDefined(const FunctionDecl *&Definition) const; + + virtual bool isDefined() const { + const FunctionDecl* Definition; + return isDefined(Definition); + } + /// getBody - Retrieve the body (definition) of the function. The /// function body might be in any of the (re-)declarations of this /// function. The variant that accepts a FunctionDecl pointer will @@ -1529,10 +1546,17 @@ public: /// isThisDeclarationADefinition - Returns whether this specific /// declaration of the function is also a definition. This does not /// determine whether the function has been defined (e.g., in a - /// previous definition); for that information, use getBody. - /// FIXME: Should return true if function is deleted or defaulted. However, - /// CodeGenModule.cpp uses it, and I don't know if this would break it. + /// previous definition); for that information, use isDefined. Note + /// that this returns false for a defaulted function unless that function + /// has been implicitly defined (possibly as deleted). bool isThisDeclarationADefinition() const { + return IsDeleted || Body || IsLateTemplateParsed; + } + + /// doesThisDeclarationHaveABody - Returns whether this specific + /// declaration of the function has a body - that is, if it is a non- + /// deleted definition. + bool doesThisDeclarationHaveABody() const { return Body || IsLateTemplateParsed; } @@ -1566,6 +1590,16 @@ public: bool isTrivial() const { return IsTrivial; } void setTrivial(bool IT) { IsTrivial = IT; } + /// Whether this function is defaulted per C++0x. Only valid for + /// special member functions. + bool isDefaulted() const { return IsDefaulted; } + void setDefaulted(bool D = true) { IsDefaulted = D; } + + /// Whether this function is explicitly defaulted per C++0x. Only valid + /// for special member functions. + bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; } + void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; } + /// Whether falling off this function implicitly returns null/zero. /// If a more specific implicit return value is required, front-ends /// should synthesize the appropriate return statements. @@ -1605,13 +1639,30 @@ public: /// Integer(long double) = delete; // no construction from long double /// }; /// @endcode - bool isDeleted() const { return IsDeleted; } - void setDeleted(bool D = true) { IsDeleted = D; } + // If a function is deleted, its first declaration must be. + bool isDeleted() const { return getCanonicalDecl()->IsDeleted; } + bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; } + void setDeletedAsWritten(bool D = true) { IsDeleted = D; } - /// \brief Determines whether this is a function "main", which is - /// the entry point into an executable program. + /// \brief Determines whether this function is "main", which is the + /// entry point into an executable program. bool isMain() const; + /// \brief Determines whether this operator new or delete is one + /// of the reserved global placement operators: + /// void *operator new(size_t, void *); + /// void *operator new[](size_t, void *); + /// void operator delete(void *, void *); + /// void operator delete[](void *, void *); + /// These functions have special behavior under [new.delete.placement]: + /// These functions are reserved, a C++ program may not define + /// functions that displace the versions in the Standard C++ library. + /// The provisions of [basic.stc.dynamic] do not apply to these + /// reserved placement forms of operator new and operator delete. + /// + /// This function must be an allocation or deallocation function. + bool isReservedGlobalPlacementOperator() const; + /// \brief Determines whether this function is a function with /// external, C linkage. bool isExternC() const; @@ -1902,20 +1953,33 @@ class FieldDecl : public DeclaratorDecl { bool Mutable : 1; mutable unsigned CachedFieldIndex : 31; - Expr *BitWidth; + /// \brief A pointer to either the in-class initializer for this field (if + /// the boolean value is false), or the bit width expression for this bit + /// field (if the boolean value is true). + /// + /// We can safely combine these two because in-class initializers are not + /// permitted for bit-fields. + /// + /// If the boolean is false and the initializer is null, then this field has + /// an in-class initializer which has not yet been parsed and attached. + llvm::PointerIntPair<Expr *, 1, bool> InitializerOrBitWidth; protected: FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable) + QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, + bool HasInit) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), - Mutable(Mutable), CachedFieldIndex(0), BitWidth(BW) { + Mutable(Mutable), CachedFieldIndex(0), + InitializerOrBitWidth(BW, !HasInit) { + assert(!(BW && HasInit) && "got initializer for bitfield"); } public: static FieldDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, Expr *BW, bool Mutable); + TypeSourceInfo *TInfo, Expr *BW, bool Mutable, + bool HasInit); /// getFieldIndex - Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -1928,10 +1992,12 @@ public: void setMutable(bool M) { Mutable = M; } /// isBitfield - Determines whether this field is a bitfield. - bool isBitField() const { return BitWidth != NULL; } + bool isBitField() const { + return InitializerOrBitWidth.getInt() && InitializerOrBitWidth.getPointer(); + } /// @brief Determines whether this is an unnamed bitfield. - bool isUnnamedBitfield() const { return BitWidth != NULL && !getDeclName(); } + bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); } /// isAnonymousStructOrUnion - Determines whether this field is a /// representative for an anonymous struct or union. Such fields are @@ -1939,8 +2005,37 @@ public: /// store the data for the anonymous union or struct. bool isAnonymousStructOrUnion() const; - Expr *getBitWidth() const { return BitWidth; } - void setBitWidth(Expr *BW) { BitWidth = BW; } + Expr *getBitWidth() const { + return isBitField() ? InitializerOrBitWidth.getPointer() : 0; + } + void setBitWidth(Expr *BW) { + assert(!InitializerOrBitWidth.getPointer() && + "bit width or initializer already set"); + InitializerOrBitWidth.setPointer(BW); + InitializerOrBitWidth.setInt(1); + } + + /// hasInClassInitializer - Determine whether this member has a C++0x in-class + /// initializer. + bool hasInClassInitializer() const { + return !InitializerOrBitWidth.getInt(); + } + /// getInClassInitializer - Get the C++0x in-class initializer for this + /// member, or null if one has not been set. If a valid declaration has an + /// in-class initializer, but this returns null, then we have not parsed and + /// attached it yet. + Expr *getInClassInitializer() const { + return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0; + } + /// setInClassInitializer - Set the C++0x in-class initializer for this member. + void setInClassInitializer(Expr *Init); + /// removeInClassInitializer - Remove the C++0x in-class initializer from this + /// member. + void removeInClassInitializer() { + assert(!InitializerOrBitWidth.getInt() && "no initializer to remove"); + InitializerOrBitWidth.setPointer(0); + InitializerOrBitWidth.setInt(1); + } /// getParent - Returns the parent of this field declaration, which /// is the struct in which this method is defined. diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index ce48187..b5047b9 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1355,17 +1355,12 @@ struct cast_convert_decl_context<ToTy, true> { namespace llvm { /// isa<T>(DeclContext*) -template<class ToTy> -struct isa_impl_wrap<ToTy, - const ::clang::DeclContext,const ::clang::DeclContext> { +template <typename To> +struct isa_impl<To, ::clang::DeclContext> { static bool doit(const ::clang::DeclContext &Val) { - return ToTy::classofKind(Val.getDeclKind()); + return To::classofKind(Val.getDeclKind()); } }; -template<class ToTy> -struct isa_impl_wrap<ToTy, ::clang::DeclContext, ::clang::DeclContext> - : public isa_impl_wrap<ToTy, - const ::clang::DeclContext,const ::clang::DeclContext> {}; /// cast<T>(DeclContext*) template<class ToTy> diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 8c819e3..42a12eb 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -278,10 +278,18 @@ class CXXRecordDecl : public RecordDecl { /// user-declared copy constructor. bool UserDeclaredCopyConstructor : 1; + /// UserDeclareMoveConstructor - True when this class has a + /// user-declared move constructor. + bool UserDeclaredMoveConstructor : 1; + /// UserDeclaredCopyAssignment - True when this class has a /// user-declared copy assignment operator. bool UserDeclaredCopyAssignment : 1; + /// UserDeclareMoveAssignment - True when this class has a + /// user-declared move assignment. + bool UserDeclaredMoveAssignment : 1; + /// UserDeclaredDestructor - True when this class has a /// user-declared destructor. bool UserDeclaredDestructor : 1; @@ -337,15 +345,24 @@ class CXXRecordDecl : public RecordDecl { /// HasPublicFields - True when there are private non-static data members. bool HasPublicFields : 1; - /// HasTrivialConstructor - True when this class has a trivial constructor. + /// \brief True if this class (or any subobject) has mutable fields. + bool HasMutableFields : 1; + + /// HasTrivialDefaultConstructor - True when, if this class has a default + /// constructor, this default constructor is trivial. /// - /// C++ [class.ctor]p5. A constructor is trivial if it is an - /// implicitly-declared default constructor and if: - /// * its class has no virtual functions and no virtual base classes, and - /// * all the direct base classes of its class have trivial constructors, and - /// * for all the nonstatic data members of its class that are of class type - /// (or array thereof), each such class has a trivial constructor. - bool HasTrivialConstructor : 1; + /// C++0x [class.ctor]p5 + /// A default constructor is trivial if it is not user-provided and if + /// -- its class has no virtual functions and no virtual base classes, + /// and + /// -- no non-static data member of its class has a + /// brace-or-equal-initializer, and + /// -- all the direct base classes of its class have trivial + /// default constructors, and + /// -- for all the nonstatic data members of its class that are of class + /// type (or array thereof), each such class has a trivial + /// default constructor. + bool HasTrivialDefaultConstructor : 1; /// HasConstExprNonCopyMoveConstructor - True when this class has at least /// one constexpr constructor which is neither the copy nor move @@ -357,7 +374,7 @@ class CXXRecordDecl : public RecordDecl { /// /// C++0x [class.copy]p13: /// A copy/move constructor for class X is trivial if it is neither - /// user-provided nor deleted and if + /// user-provided and if /// -- class X has no virtual functions and no virtual base classes, and /// -- the constructor selected to copy/move each direct base class /// subobject is trivial, and @@ -372,7 +389,7 @@ class CXXRecordDecl : public RecordDecl { /// /// C++0x [class.copy]p13: /// A copy/move constructor for class X is trivial if it is neither - /// user-provided nor deleted and if + /// user-provided and if /// -- class X has no virtual functions and no virtual base classes, and /// -- the constructor selected to copy/move each direct base class /// subobject is trivial, and @@ -430,15 +447,24 @@ class CXXRecordDecl : public RecordDecl { /// already computed and are available. bool ComputedVisibleConversions : 1; - /// \brief Whether we have already declared the default constructor or - /// do not need to have one declared. + /// \brief Whether we have a C++0x user-provided default constructor (not + /// explicitly deleted or defaulted). + bool UserProvidedDefaultConstructor : 1; + + /// \brief Whether we have already declared the default constructor. bool DeclaredDefaultConstructor : 1; /// \brief Whether we have already declared the copy constructor. bool DeclaredCopyConstructor : 1; + + /// \brief Whether we have already declared the move constructor. + bool DeclaredMoveConstructor : 1; /// \brief Whether we have already declared the copy-assignment operator. bool DeclaredCopyAssignment : 1; + + /// \brief Whether we have already declared the move-assignment operator. + bool DeclaredMoveAssignment : 1; /// \brief Whether we have already declared a destructor within the class. bool DeclaredDestructor : 1; @@ -666,21 +692,30 @@ public: return data().FirstFriend != 0; } - /// \brief Determine whether this class has had its default constructor - /// declared implicitly or does not need one declared implicitly. + /// \brief Determine if we need to declare a default constructor for + /// this class. /// /// This value is used for lazy creation of default constructors. + bool needsImplicitDefaultConstructor() const { + return !data().UserDeclaredConstructor && + !data().DeclaredDefaultConstructor; + } + + /// hasDeclaredDefaultConstructor - Whether this class's default constructor + /// has been declared (either explicitly or implicitly). bool hasDeclaredDefaultConstructor() const { return data().DeclaredDefaultConstructor; } - + /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. - bool hasConstCopyConstructor(const ASTContext &Context) const; + bool hasConstCopyConstructor() const; /// getCopyConstructor - Returns the copy constructor for this class - CXXConstructorDecl *getCopyConstructor(const ASTContext &Context, - unsigned TypeQuals) const; + CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const; + + /// getMoveConstructor - Returns the move constructor for this class + CXXConstructorDecl *getMoveConstructor() const; /// \brief Retrieve the copy-assignment operator for this class, if available. /// @@ -693,6 +728,10 @@ public: /// \returns The copy-assignment operator that can be invoked, or NULL if /// a unique copy-assignment operator could not be found. CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const; + + /// getMoveAssignmentOperator - Returns the move assignment operator for this + /// class + CXXMethodDecl *getMoveAssignmentOperator() const; /// hasUserDeclaredConstructor - Whether this class has any /// user-declared constructors. When true, a default constructor @@ -701,6 +740,12 @@ public: return data().UserDeclaredConstructor; } + /// hasUserProvidedDefaultconstructor - Whether this class has a + /// user-provided default constructor per C++0x. + bool hasUserProvidedDefaultConstructor() const { + return data().UserProvidedDefaultConstructor; + } + /// hasUserDeclaredCopyConstructor - Whether this class has a /// user-declared copy constructor. When false, a copy constructor /// will be implicitly declared. @@ -715,7 +760,27 @@ public: bool hasDeclaredCopyConstructor() const { return data().DeclaredCopyConstructor; } - + + /// hasUserDeclaredMoveOperation - Whether this class has a user- + /// declared move constructor or assignment operator. When false, a + /// move constructor and assignment operator may be implicitly declared. + bool hasUserDeclaredMoveOperation() const { + return data().UserDeclaredMoveConstructor || + data().UserDeclaredMoveAssignment; + } + + /// \brief Determine whether this class has had a move constructor + /// declared by the user. + bool hasUserDeclaredMoveConstructor() const { + return data().UserDeclaredMoveConstructor; + } + + /// \brief Determine whether this class has had a move constructor + /// declared. + bool hasDeclaredMoveConstructor() const { + return data().DeclaredMoveConstructor; + } + /// hasUserDeclaredCopyAssignment - Whether this class has a /// user-declared copy assignment operator. When false, a copy /// assigment operator will be implicitly declared. @@ -730,7 +795,19 @@ public: bool hasDeclaredCopyAssignment() const { return data().DeclaredCopyAssignment; } - + + /// \brief Determine whether this class has had a move assignment + /// declared by the user. + bool hasUserDeclaredMoveAssignment() const { + return data().UserDeclaredMoveAssignment; + } + + /// hasDeclaredMoveAssignment - Whether this class has a + /// declared move assignment operator. + bool hasDeclaredMoveAssignment() const { + return data().DeclaredMoveAssignment; + } + /// hasUserDeclaredDestructor - Whether this class has a /// user-declared destructor. When false, a destructor will be /// implicitly declared. @@ -800,9 +877,18 @@ public: /// (C++ [class]p7) bool isStandardLayout() const { return data().IsStandardLayout; } - // hasTrivialConstructor - Whether this class has a trivial constructor - // (C++ [class.ctor]p5) - bool hasTrivialConstructor() const { return data().HasTrivialConstructor; } + /// \brief Whether this class, or any of its class subobjects, contains a + /// mutable field. + bool hasMutableFields() const { return data().HasMutableFields; } + + // hasTrivialDefaultConstructor - Whether this class has a trivial default + // constructor + // (C++0x [class.ctor]p5) + bool hasTrivialDefaultConstructor() const { + return data().HasTrivialDefaultConstructor && + (!data().UserDeclaredConstructor || + data().DeclaredDefaultConstructor); + } // hasConstExprNonCopyMoveConstructor - Whether this class has at least one // constexpr constructor other than the copy or move constructors @@ -845,9 +931,18 @@ public: } // isTriviallyCopyable - Whether this class is considered trivially copyable - // (C++0x [class]p5). + // (C++0x [class]p6). bool isTriviallyCopyable() const; + // isTrivial - Whether this class is considered trivial + // + // C++0x [class]p6 + // A trivial class is a class that has a trivial default constructor and + // is trivially copiable. + bool isTrivial() const { + return isTriviallyCopyable() && hasTrivialDefaultConstructor(); + } + /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// @@ -1182,6 +1277,9 @@ public: /// \brief Determine whether this is a copy-assignment operator, regardless /// of whether it was declared implicitly or explicitly. bool isCopyAssignmentOperator() const; + + /// \brief Determine whether this is a move assignment operator. + bool isMoveAssignmentOperator() const; const CXXMethodDecl *getCanonicalDecl() const { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); @@ -1189,6 +1287,12 @@ public: CXXMethodDecl *getCanonicalDecl() { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); } + + /// isUserProvided - True if it is either an implicit constructor or + /// if it was defaulted or deleted on first declaration. + bool isUserProvided() const { + return !(isDeleted() || getCanonicalDecl()->isDefaulted()); + } /// void addOverriddenMethod(const CXXMethodDecl *MD); @@ -1274,6 +1378,8 @@ class CXXCtorInitializer { /// \brief The argument used to initialize the base or member, which may /// end up constructing an object (when multiple arguments are involved). + /// If 0, this is a field initializer, and the in-class member initializer + /// will be used. Stmt *Init; /// LParenLoc - Location of the left paren of the ctor-initializer. @@ -1348,6 +1454,13 @@ public: return Initializee.is<IndirectFieldDecl*>(); } + /// isInClassMemberInitializer - Returns true when this initializer is an + /// implicit ctor initializer generated for a field with an initializer + /// defined on the member declaration. + bool isInClassMemberInitializer() const { + return !Init; + } + /// isDelegatingInitializer - Returns true when this initializer is creating /// a delegating constructor. bool isDelegatingInitializer() const { @@ -1476,7 +1589,14 @@ public: reinterpret_cast<VarDecl **>(this + 1)[I] = Index; } - Expr *getInit() const { return static_cast<Expr *>(Init); } + /// \brief Get the initializer. This is 0 if this is an in-class initializer + /// for a non-static data member which has not yet been parsed. + Expr *getInit() const { + if (!Init) + return getAnyMember()->getInClassInitializer(); + + return static_cast<Expr*>(Init); + } }; /// CXXConstructorDecl - Represents a C++ constructor within a @@ -1619,10 +1739,9 @@ public: /// getTargetConstructor - When this constructor delegates to /// another, retrieve the target CXXConstructorDecl *getTargetConstructor() const { - if (isDelegatingConstructor()) - return CtorInitializers[0]->getTargetConstructor(); - else - return 0; + assert(isDelegatingConstructor() && + "A non-delegating constructor has no target"); + return CtorInitializers[0]->getTargetConstructor(); } /// isDefaultConstructor - Whether this constructor is a default @@ -1693,6 +1812,13 @@ public: /// \brief Set the constructor that this inheriting constructor is based on. void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); + + const CXXConstructorDecl *getCanonicalDecl() const { + return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); + } + CXXConstructorDecl *getCanonicalDecl() { + return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 0a4d864..74ceb43 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -135,6 +135,9 @@ private: /// in, inout, etc. unsigned objcDeclQualifier : 6; + /// \brief Indicates whether this method has a related result type. + unsigned RelatedResultType : 1; + // Number of args separated by ':' in a method declaration. unsigned NumSelectorArgs; @@ -171,6 +174,7 @@ private: bool isSynthesized = false, bool isDefined = false, ImplementationControl impControl = None, + bool HasRelatedResultType = false, unsigned numSelectorArgs = 0) : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), @@ -178,8 +182,8 @@ private: IsSynthesized(isSynthesized), IsDefined(isDefined), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), - NumSelectorArgs(numSelectorArgs), MethodDeclType(T), - ResultTInfo(ResultTInfo), + RelatedResultType(HasRelatedResultType), NumSelectorArgs(numSelectorArgs), + MethodDeclType(T), ResultTInfo(ResultTInfo), EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {} /// \brief A definition will return its interface declaration. @@ -199,6 +203,7 @@ public: bool isSynthesized = false, bool isDefined = false, ImplementationControl impControl = None, + bool HasRelatedResultType = false, unsigned numSelectorArgs = 0); virtual ObjCMethodDecl *getCanonicalDecl(); @@ -211,6 +216,13 @@ public: } void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } + /// \brief Determine whether this method has a result type that is related + /// to the message receiver's type. + bool hasRelatedResultType() const { return RelatedResultType; } + + /// \brief Note whether this method has a related result type. + void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } + unsigned getNumSelectorArgs() const { return NumSelectorArgs; } void setNumSelectorArgs(unsigned numSelectorArgs) { NumSelectorArgs = numSelectorArgs; @@ -712,7 +724,7 @@ private: QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, bool synthesized) : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, - /*Mutable=*/false), + /*Mutable=*/false, /*HasInit=*/false), NextIvar(0), DeclAccess(ac), Synthesized(synthesized) {} public: @@ -767,7 +779,7 @@ private: QualType T, Expr *BW) : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ? - BW, /*Mutable=*/false) {} + BW, /*Mutable=*/false, /*HasInit=*/false) {} public: static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index ddbe344..dc50d61 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -30,6 +30,7 @@ class ClassTemplatePartialSpecializationDecl; class TemplateTypeParmDecl; class NonTypeTemplateParmDecl; class TemplateTemplateParmDecl; +class TypeAliasTemplateDecl; /// \brief Stores a template parameter of any kind. typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, @@ -230,6 +231,7 @@ public: static bool classof(const FunctionTemplateDecl *D) { return true; } static bool classof(const ClassTemplateDecl *D) { return true; } static bool classof(const TemplateTemplateParmDecl *D) { return true; } + static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstTemplate && K <= lastTemplate; } @@ -672,6 +674,7 @@ public: static bool classof(const RedeclarableTemplateDecl *D) { return true; } static bool classof(const FunctionTemplateDecl *D) { return true; } static bool classof(const ClassTemplateDecl *D) { return true; } + static bool classof(const TypeAliasTemplateDecl *D) { return true; } static bool classofKind(Kind K) { return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; } @@ -2014,6 +2017,78 @@ public: friend class ASTDeclReader; }; +/// Declaration of an alias template. For example: +/// +/// template <typename T> using V = std::map<T*, int, MyCompare<T>>; +class TypeAliasTemplateDecl : public RedeclarableTemplateDecl, + public RedeclarableTemplate<TypeAliasTemplateDecl> { + static void DeallocateCommon(void *Ptr); + +protected: + typedef RedeclarableTemplate<TypeAliasTemplateDecl> redeclarable_base; + + typedef CommonBase Common; + + TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { } + + CommonBase *newCommon(ASTContext &C); + + Common *getCommonPtr() { + return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); + } + +public: + /// Get the underlying function declaration of the template. + TypeAliasDecl *getTemplatedDecl() const { + return static_cast<TypeAliasDecl*>(TemplatedDecl); + } + + + TypeAliasTemplateDecl *getCanonicalDecl() { + return redeclarable_base::getCanonicalDecl(); + } + const TypeAliasTemplateDecl *getCanonicalDecl() const { + return redeclarable_base::getCanonicalDecl(); + } + + /// \brief Retrieve the previous declaration of this function template, or + /// NULL if no such declaration exists. + TypeAliasTemplateDecl *getPreviousDeclaration() { + return redeclarable_base::getPreviousDeclaration(); + } + + /// \brief Retrieve the previous declaration of this function template, or + /// NULL if no such declaration exists. + const TypeAliasTemplateDecl *getPreviousDeclaration() const { + return redeclarable_base::getPreviousDeclaration(); + } + + TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() { + return redeclarable_base::getInstantiatedFromMemberTemplate(); + } + + + /// \brief Create a function template node. + static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + DeclarationName Name, + TemplateParameterList *Params, + NamedDecl *Decl); + + /// \brief Create an empty alias template node. + static TypeAliasTemplateDecl *Create(ASTContext &C, EmptyShell); + + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classof(const TypeAliasTemplateDecl *D) { return true; } + static bool classofKind(Kind K) { return K == TypeAliasTemplate; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + /// Implementation of inline functions that require the template declarations inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) : Function(FTD) { } diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 5f2d144..ce86458e 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -515,6 +515,14 @@ public: /// ParenExpr or ImplicitCastExprs, returning their operand. Expr *IgnoreParenImpCasts(); + /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a + /// call to a conversion operator, return the argument. + Expr *IgnoreConversionOperator(); + + const Expr *IgnoreConversionOperator() const { + return const_cast<Expr*>(this)->IgnoreConversionOperator(); + } + const Expr *IgnoreParenImpCasts() const { return const_cast<Expr*>(this)->IgnoreParenImpCasts(); } @@ -1018,13 +1026,18 @@ public: false), Loc(l) { assert(type->isIntegerType() && "Illegal type in IntegerLiteral"); + assert(V.getBitWidth() == C.getIntWidth(type) && + "Integer type is not the correct size for constant."); setValue(C, V); } - // type should be IntTy, LongTy, LongLongTy, UnsignedIntTy, UnsignedLongTy, - // or UnsignedLongLongTy + /// \brief Returns a new integer literal with value 'V' and type 'type'. + /// \param type - either IntTy, LongTy, LongLongTy, UnsignedIntTy, + /// UnsignedLongTy, or UnsignedLongLongTy which should match the size of V + /// \param V - the value that the returned integer literal contains. static IntegerLiteral *Create(ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l); + /// \brief Returns a new empty integer literal. static IntegerLiteral *Create(ASTContext &C, EmptyShell Empty); llvm::APInt getValue() const { return Num.getValue(); } @@ -1555,9 +1568,9 @@ public: TSInfo = tsi; } - const OffsetOfNode &getComponent(unsigned Idx) { + const OffsetOfNode &getComponent(unsigned Idx) const { assert(Idx < NumComps && "Subscript out of range"); - return reinterpret_cast<OffsetOfNode *> (this + 1)[Idx]; + return reinterpret_cast<const OffsetOfNode *> (this + 1)[Idx]; } void setComponent(unsigned Idx, OffsetOfNode ON) { @@ -1574,6 +1587,9 @@ public: return reinterpret_cast<Expr **>( reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx]; } + const Expr *getIndexExpr(unsigned Idx) const { + return const_cast<OffsetOfExpr*>(this)->getIndexExpr(Idx); + } void setIndexExpr(unsigned Idx, Expr* E) { assert(Idx < NumComps && "Subscript out of range"); @@ -3299,6 +3315,9 @@ public: Expr *getArrayFiller() { return ArrayFillerOrUnionFieldInit.dyn_cast<Expr *>(); } + const Expr *getArrayFiller() const { + return const_cast<InitListExpr *>(this)->getArrayFiller(); + } void setArrayFiller(Expr *filler); /// \brief If this initializes a union, specifies which field in the @@ -3310,6 +3329,9 @@ public: FieldDecl *getInitializedFieldInUnion() { return ArrayFillerOrUnionFieldInit.dyn_cast<FieldDecl *>(); } + const FieldDecl *getInitializedFieldInUnion() const { + return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion(); + } void setInitializedFieldInUnion(FieldDecl *FD) { ArrayFillerOrUnionFieldInit = FD; } @@ -4012,6 +4034,42 @@ public: child_range children() { return child_range(); } }; +/// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] +/// This AST node provides support for reinterpreting a type to another +/// type of the same size. +class AsTypeExpr : public Expr { +private: + Expr* SrcExpr; + QualType DstType; + SourceLocation BuiltinLoc, RParenLoc; + +public: + AsTypeExpr(Expr* SrcExpr, QualType DstType, + ExprValueKind VK, ExprObjectKind OK, + SourceLocation BuiltinLoc, SourceLocation RParenLoc) + : Expr(AsTypeExprClass, DstType, VK, OK, false, false, false), + SrcExpr(SrcExpr), DstType(DstType), + BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + + /// \brief Build an empty __builtin_astype + explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {} + + /// getSrcExpr - Return the Expr to be converted. + Expr *getSrcExpr() const { return SrcExpr; } + QualType getDstType() const { return DstType; } + + SourceRange getSourceRange() const { + return SourceRange(BuiltinLoc, RParenLoc); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == AsTypeExprClass; + } + static bool classof(const AsTypeExpr *) { return true; } + + // Iterators + child_range children() { return child_range(); } +}; } // end namespace clang #endif diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index 6db2336..846813a 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -211,7 +211,7 @@ public: return sizes; } - virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const = 0; + virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const; protected: static DeclContextLookupResult diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 930d193..a8f182a 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -750,6 +750,11 @@ DEF_TRAVERSE_TYPE(DecltypeType, { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPE(UnaryTransformType, { + TRY_TO(TraverseType(T->getBaseType())); + TRY_TO(TraverseType(T->getUnderlyingType())); + }) + DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); }) @@ -966,6 +971,10 @@ DEF_TRAVERSE_TYPELOC(DecltypeType, { TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); }) +DEF_TRAVERSE_TYPELOC(UnaryTransformType, { + TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); + }) + DEF_TRAVERSE_TYPELOC(AutoType, { TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); }) @@ -1368,6 +1377,11 @@ DEF_TRAVERSE_DECL(TypeAliasDecl, { // source. }) +DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { + TRY_TO(TraverseDecl(D->getTemplatedDecl())); + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); + }) + DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { // A dependent using declaration which was marked with 'typename'. // template<class T> class A : public B<T> { using typename B<T>::foo; }; @@ -1967,6 +1981,9 @@ DEF_TRAVERSE_STMT(FloatingLiteral, { }) DEF_TRAVERSE_STMT(ImaginaryLiteral, { }) DEF_TRAVERSE_STMT(StringLiteral, { }) DEF_TRAVERSE_STMT(ObjCStringLiteral, { }) + +// Traverse OpenCL: AsType, Convert. +DEF_TRAVERSE_STMT(AsTypeExpr, { }) // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h index b8c141d..29d2347 100644 --- a/include/clang/AST/StmtVisitor.h +++ b/include/clang/AST/StmtVisitor.h @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines the StmtVisitor interface. +// This file defines the StmtVisitor and ConstStmtVisitor interfaces. // //===----------------------------------------------------------------------===// @@ -21,20 +21,26 @@ namespace clang { -#define DISPATCH(NAME, CLASS) \ - return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<CLASS*>(S)) +template <typename T> struct make_ptr { typedef T *type; }; +template <typename T> struct make_const_ptr { typedef const T *type; }; -/// StmtVisitor - This class implements a simple visitor for Stmt subclasses. -/// Since Expr derives from Stmt, this also includes support for visiting Exprs. -template<typename ImplClass, typename RetTy=void> -class StmtVisitor { +/// StmtVisitorBase - This class implements a simple visitor for Stmt +/// subclasses. Since Expr derives from Stmt, this also includes support for +/// visiting Exprs. +template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> +class StmtVisitorBase { public: - RetTy Visit(Stmt *S) { + +#define PTR(CLASS) typename Ptr<CLASS>::type +#define DISPATCH(NAME, CLASS) \ + return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S)) + + RetTy Visit(PTR(Stmt) S) { // If we have a binary expr, dispatch to the subcode of the binop. A smart // optimizer (e.g. LLVM) will fold this comparison into the switch stmt // below. - if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { + if (PTR(BinaryOperator) BinOp = dyn_cast<BinaryOperator>(S)) { switch (BinOp->getOpcode()) { default: assert(0 && "Unknown binary operator!"); case BO_PtrMemD: DISPATCH(BinPtrMemD, BinaryOperator); @@ -72,7 +78,7 @@ public: case BO_XorAssign: DISPATCH(BinXorAssign, CompoundAssignOperator); case BO_Comma: DISPATCH(BinComma, BinaryOperator); } - } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { + } else if (PTR(UnaryOperator) UnOp = dyn_cast<UnaryOperator>(S)) { switch (UnOp->getOpcode()) { default: assert(0 && "Unknown unary operator!"); case UO_PostInc: DISPATCH(UnaryPostInc, UnaryOperator); @@ -104,13 +110,13 @@ public: // If the implementation chooses not to implement a certain visit method, fall // back on VisitExpr or whatever else is the superclass. #define STMT(CLASS, PARENT) \ - RetTy Visit ## CLASS(CLASS *S) { DISPATCH(PARENT, PARENT); } + RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); } #include "clang/AST/StmtNodes.inc" // If the implementation doesn't implement binary operator methods, fall back // on VisitBinaryOperator. #define BINOP_FALLBACK(NAME) \ - RetTy VisitBin ## NAME(BinaryOperator *S) { \ + RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \ DISPATCH(BinaryOperator, BinaryOperator); \ } BINOP_FALLBACK(PtrMemD) BINOP_FALLBACK(PtrMemI) @@ -130,7 +136,7 @@ public: // If the implementation doesn't implement compound assignment operator // methods, fall back on VisitCompoundAssignOperator. #define CAO_FALLBACK(NAME) \ - RetTy VisitBin ## NAME(CompoundAssignOperator *S) { \ + RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \ DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \ } CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign) @@ -142,7 +148,7 @@ public: // If the implementation doesn't implement unary operator methods, fall back // on VisitUnaryOperator. #define UNARYOP_FALLBACK(NAME) \ - RetTy VisitUnary ## NAME(UnaryOperator *S) { \ + RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \ DISPATCH(UnaryOperator, UnaryOperator); \ } UNARYOP_FALLBACK(PostInc) UNARYOP_FALLBACK(PostDec) @@ -156,10 +162,29 @@ public: #undef UNARYOP_FALLBACK // Base case, ignore it. :) - RetTy VisitStmt(Stmt *Node) { return RetTy(); } -}; + RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); } +#undef PTR #undef DISPATCH +}; + +/// StmtVisitor - This class implements a simple visitor for Stmt subclasses. +/// Since Expr derives from Stmt, this also includes support for visiting Exprs. +/// +/// This class does not preserve constness of Stmt pointers (see also +/// ConstStmtVisitor). +template<typename ImplClass, typename RetTy=void> +class StmtVisitor + : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {}; + +/// ConstStmtVisitor - This class implements a simple visitor for Stmt +/// subclasses. Since Expr derives from Stmt, this also includes support for +/// visiting Exprs. +/// +/// This class preserves constness of Stmt pointers (see also StmtVisitor). +template<typename ImplClass, typename RetTy=void> +class ConstStmtVisitor + : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {}; } // end namespace clang diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 975a66f..7763383 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -294,9 +294,15 @@ public: /// Generally this answers the question of whether an object with the other /// qualifiers can be safely used as an object with these qualifiers. bool compatiblyIncludes(Qualifiers other) const { - // Non-CVR qualifiers must match exactly. CVR qualifiers may subset. - return ((Mask & ~CVRMask) == (other.Mask & ~CVRMask)) && - (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); + return + // Address spaces must match exactly. + getAddressSpace() == other.getAddressSpace() && + // ObjC GC qualifiers can match, be added, or be removed, but can't be + // changed. + (getObjCGCAttr() == other.getObjCGCAttr() || + !hasObjCGCAttr() || !other.hasObjCGCAttr()) && + // CVR qualifiers may subset. + (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); } /// \brief Determine whether this set of qualifiers is a strict superset of @@ -532,6 +538,14 @@ public: return withFastQualifiers(Qualifiers::Const); } + /// addVolatile - add the specified type qualifier to this QualType. + void addVolatile() { + addFastQualifiers(Qualifiers::Volatile); + } + QualType withVolatile() const { + return withFastQualifiers(Qualifiers::Volatile); + } + void addFastQualifiers(unsigned TQs) { assert(!(TQs & ~Qualifiers::FastMask) && "non-fast qualifier bits set in mask!"); @@ -1183,6 +1197,10 @@ public: /// (C++0x [basic.types]p9) bool isTrivialType() const; + /// isTriviallyCopyableType - Return true if this is a trivially copyable type + /// (C++0x [basic.types]p9 + bool isTriviallyCopyableType() const; + /// \brief Test if this type is a standard-layout type. /// (C++0x [basic.type]p9) bool isStandardLayoutType() const; @@ -1418,16 +1436,22 @@ public: /// isSignedIntegerType - Return true if this is an integer type that is /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], - /// an enum decl which has a signed representation, or a vector of signed - /// integer element type. + /// or an enum decl which has a signed representation. bool isSignedIntegerType() const; /// isUnsignedIntegerType - Return true if this is an integer type that is - /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum - /// decl which has an unsigned representation, or a vector of unsigned integer - /// element type. + /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], + /// or an enum decl which has an unsigned representation. bool isUnsignedIntegerType() const; + /// Determines whether this is an integer type that is signed or an + /// enumeration types whose underlying type is a signed integer type. + bool isSignedIntegerOrEnumerationType() const; + + /// Determines whether this is an integer type that is unsigned or an + /// enumeration types whose underlying type is a unsigned integer type. + bool isUnsignedIntegerOrEnumerationType() const; + /// isConstantSizeType - Return true if this is not a variable sized type, /// according to the rules of C99 6.7.5p3. It is not legal to call this on /// incomplete types. @@ -2580,6 +2604,7 @@ public: } bool isNothrow(ASTContext &Ctx) const { ExceptionSpecificationType EST = getExceptionSpecType(); + assert(EST != EST_Delayed); if (EST == EST_DynamicNone || EST == EST_BasicNoexcept) return true; if (EST != EST_ComputedNoexcept) @@ -2809,6 +2834,39 @@ public: Expr *E); }; +/// \brief A unary type transform, which is a type constructed from another +class UnaryTransformType : public Type { +public: + enum UTTKind { + EnumUnderlyingType + }; + +private: + /// The untransformed type. + QualType BaseType; + /// The transformed type if not dependent, otherwise the same as BaseType. + QualType UnderlyingType; + + UTTKind UKind; +protected: + UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, + QualType CanonicalTy); + friend class ASTContext; +public: + bool isSugared() const { return !isDependentType(); } + QualType desugar() const { return UnderlyingType; } + + QualType getUnderlyingType() const { return UnderlyingType; } + QualType getBaseType() const { return BaseType; } + + UTTKind getUTTKind() const { return UKind; } + + static bool classof(const Type *T) { + return T->getTypeClass() == UnaryTransform; + } + static bool classof(const UnaryTransformType *) { return true; } +}; + class TagType : public Type { /// Stores the TagDecl associated with this type. The decl may point to any /// TagDecl that declares the entity. @@ -3201,6 +3259,10 @@ public: /// Other template specialization types, for which the template name /// is dependent, may be canonical types. These types are always /// dependent. +/// +/// An instance of this type is followed by an array of TemplateArgument*s, +/// then, if the template specialization type is for a type alias template, +/// a QualType representing the non-canonical aliased type. class TemplateSpecializationType : public Type, public llvm::FoldingSetNode { /// \brief The name of the template being specialized. @@ -3212,7 +3274,8 @@ class TemplateSpecializationType TemplateSpecializationType(TemplateName T, const TemplateArgument *Args, - unsigned NumArgs, QualType Canon); + unsigned NumArgs, QualType Canon, + QualType Aliased); friend class ASTContext; // ASTContext creates these @@ -3247,6 +3310,16 @@ public: return isa<InjectedClassNameType>(getCanonicalTypeInternal()); } + /// True if this template specialization type is for a type alias + /// template. + bool isTypeAlias() const; + /// Get the aliased type, if this is a specialization of a type alias + /// template. + QualType getAliasedType() const { + assert(isTypeAlias() && "not a type alias template specialization"); + return *reinterpret_cast<const QualType*>(end()); + } + typedef const TemplateArgument * iterator; iterator begin() const { return getArgs(); } @@ -3268,12 +3341,14 @@ public: const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h bool isSugared() const { - return !isDependentType() || isCurrentInstantiation(); + return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); } QualType desugar() const { return getCanonicalTypeInternal(); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { Profile(ID, Template, getArgs(), NumArgs, Ctx); + if (isTypeAlias()) + getAliasedType().Profile(ID); } static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index a1df744..f5669f7 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -1410,6 +1410,53 @@ class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DecltypeType> { }; +struct UnaryTransformTypeLocInfo { + // FIXME: While there's only one unary transform right now, future ones may + // need different representations + SourceLocation KWLoc, LParenLoc, RParenLoc; + TypeSourceInfo *UnderlyingTInfo; +}; + +class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, + UnaryTransformTypeLoc, + UnaryTransformType, + UnaryTransformTypeLocInfo> { +public: + SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } + void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } + + SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } + void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } + + SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } + void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } + + TypeSourceInfo* getUnderlyingTInfo() const { + return getLocalData()->UnderlyingTInfo; + } + void setUnderlyingTInfo(TypeSourceInfo *TInfo) { + getLocalData()->UnderlyingTInfo = TInfo; + } + + SourceRange getLocalSourceRange() const { + return SourceRange(getKWLoc(), getRParenLoc()); + } + + SourceRange getParensRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + void setParensRange(SourceRange Range) { + setLParenLoc(Range.getBegin()); + setRParenLoc(Range.getEnd()); + } + + void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setKWLoc(Loc); + setRParenLoc(Loc); + setLParenLoc(Loc); + } +}; + class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, AutoTypeLoc, AutoType> { diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index b2591cc..0792d0d 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -84,6 +84,7 @@ NON_CANONICAL_TYPE(Typedef, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOf, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Decltype, Type) +NON_CANONICAL_UNLESS_DEPENDENT_TYPE(UnaryTransform, Type) ABSTRACT_TYPE(Tag, Type) TYPE(Record, TagType) TYPE(Enum, TagType) diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index 080d17f..888e529 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -24,12 +24,26 @@ BUILTIN(__builtin_arm_qsub, "iii", "nc") BUILTIN(__builtin_arm_ssat, "iiUi", "nc") BUILTIN(__builtin_arm_usat, "UiUiUi", "nc") +// Store and load exclusive doubleword +BUILTIN(__builtin_arm_ldrexd, "LLUiv*", "") +BUILTIN(__builtin_arm_strexd, "iLLUiv*", "") + // VFP BUILTIN(__builtin_arm_get_fpscr, "Ui", "nc") BUILTIN(__builtin_arm_set_fpscr, "vUi", "nc") BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc") BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc") +// Coprocessor +BUILTIN(__builtin_arm_mcr, "vUiUiUiUiUiUi", "") +BUILTIN(__builtin_arm_mcr2, "vUiUiUiUiUiUi", "") +BUILTIN(__builtin_arm_mrc, "UiUiUiUiUiUi", "") +BUILTIN(__builtin_arm_mrc2, "UiUiUiUiUiUi", "") +BUILTIN(__builtin_arm_cdp, "vUiUiUiUiUiUi", "") +BUILTIN(__builtin_arm_cdp2, "vUiUiUiUiUiUi", "") +BUILTIN(__builtin_arm_mcrr, "vUiUiUiUiUi", "") +BUILTIN(__builtin_arm_mcrr2, "vUiUiUiUiUi", "") + // NEON #define GET_NEON_BUILTINS #include "clang/Basic/arm_neon.inc" diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index 2c2a84a..6ef667d 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -278,7 +278,6 @@ BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "") BUILTIN(__builtin_ia32_clflush, "vvC*", "") BUILTIN(__builtin_ia32_lfence, "v", "") BUILTIN(__builtin_ia32_mfence, "v", "") -BUILTIN(__builtin_ia32_loaddqu, "V16ccC*", "") BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "") BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "") BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "") diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index 9e69492..ddd0827 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -50,6 +50,7 @@ def Named : Decl<1>; def RedeclarableTemplate : DDecl<Template, 1>; def FunctionTemplate : DDecl<RedeclarableTemplate>; def ClassTemplate : DDecl<RedeclarableTemplate>; + def TypeAliasTemplate : DDecl<RedeclarableTemplate>; def TemplateTemplateParm : DDecl<Template>; def Using : DDecl<Named>; def UsingShadow : DDecl<Named>; diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 7fc400f..fa76324 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -32,6 +32,7 @@ namespace clang { class LangOptions; class Preprocessor; class DiagnosticErrorTrap; + class StoredDiagnostic; /// \brief Annotates a diagnostic with some code that should be /// inserted, removed, or replaced to fix the problem. @@ -400,6 +401,7 @@ public: void setExtensionHandlingBehavior(ExtensionHandling H) { ExtBehavior = H; } + ExtensionHandling getExtensionHandlingBehavior() const { return ExtBehavior; } /// AllExtensionsSilenced - This is a counter bumped when an __extension__ /// block is encountered. When non-zero, all extension diagnostics are @@ -423,7 +425,7 @@ public: /// /// 'Loc' is the source location that this change of diagnostic state should /// take affect. It can be null if we are setting the state from command-line. - bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map, + bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, SourceLocation Loc = SourceLocation()) { return Diags->setDiagnosticGroupMapping(Group, Map, Loc, *this); } @@ -487,6 +489,8 @@ public: inline DiagnosticBuilder Report(SourceLocation Pos, unsigned DiagID); inline DiagnosticBuilder Report(unsigned DiagID); + void Report(const StoredDiagnostic &storedDiag); + /// \brief Determine whethere there is already a diagnostic in flight. bool isDiagnosticInFlight() const { return CurDiagID != ~0U; } @@ -839,8 +843,11 @@ inline DiagnosticBuilder Diagnostic::Report(unsigned DiagID) { /// about the currently in-flight diagnostic. class DiagnosticInfo { const Diagnostic *DiagObj; + llvm::StringRef StoredDiagMessage; public: explicit DiagnosticInfo(const Diagnostic *DO) : DiagObj(DO) {} + DiagnosticInfo(const Diagnostic *DO, llvm::StringRef storedDiagMessage) + : DiagObj(DO), StoredDiagMessage(storedDiagMessage) {} const Diagnostic *getDiags() const { return DiagObj; } unsigned getID() const { return DiagObj->CurDiagID; } diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 0b0bca0..50110fb 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -52,6 +52,12 @@ def err_invalid_storage_class_in_func_decl : Error< def err_expected_namespace_name : Error<"expected namespace name">; def ext_variadic_templates : ExtWarn< "variadic templates are a C++0x extension">, InGroup<CXX0x>; +def err_default_special_members : Error< + "only special member functions may be defaulted">; +def err_friends_define_only_namespace_scope : Error< + "cannot define a function with non-namespace scope in a friend declaration">; +def err_deleted_non_function : Error< + "only functions can have deleted definitions">; // Sema && Lex def ext_longlong : Extension< diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 67fc22e..4aa8513 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -281,6 +281,9 @@ def err_not_a_pch_file : Error< def warn_unknown_warning_option : Warning< "unknown warning option '%0'">, InGroup<DiagGroup<"unknown-warning-option"> >; +def warn_unknown_negative_warning_option : Warning< + "unknown warning option '%0'">, + InGroup<DiagGroup<"unknown-warning-option"> >, DefaultIgnore; def warn_unknown_warning_specifier : Warning< "unknown %0 warning specifier: '%1'">, InGroup<DiagGroup<"unknown-warning-option"> >; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c85acc5..9abd6d3 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -33,8 +33,11 @@ def : DiagGroup<"char-align">; def Comment : DiagGroup<"comment">; def : DiagGroup<"ctor-dtor-privacy">; def : DiagGroup<"declaration-after-statement">; +def DefaultArgSpecialMember : DiagGroup<"default-arg-special-member">; def GNUDesignator : DiagGroup<"gnu-designator">; +def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; + def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings">; def Deprecated : DiagGroup<"deprecated", [ DeprecatedDeclarations] >, @@ -144,7 +147,7 @@ def : DiagGroup<"type-limits">; def Uninitialized : DiagGroup<"uninitialized">; def UninitializedMaybe : DiagGroup<"conditional-uninitialized">; def UnknownPragmas : DiagGroup<"unknown-pragmas">; -def UnknownAttributes : DiagGroup<"unknown-attributes">; +def UnknownAttributes : DiagGroup<"attributes">; def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">; def UnusedArgument : DiagGroup<"unused-argument">; def UnusedExceptionParameter : DiagGroup<"unused-exception-parameter">; @@ -235,6 +238,7 @@ def Extra : DiagGroup<"extra", [ def Most : DiagGroup<"most", [ CharSubscript, Comment, + DeleteNonVirtualDtor, Format, Implicit, MismatchedTags, @@ -271,6 +275,8 @@ def NonGCC : DiagGroup<"non-gcc", def CXX0xStaticNonIntegralInitializer : DiagGroup<"c++0x-static-nonintegral-init">; def CXX0x : DiagGroup<"c++0x-extensions", [CXX0xStaticNonIntegralInitializer]>; +def DelegatingCtorCycles : + DiagGroup<"delegating-ctor-cycles">; // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>; diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 0296b96..fa816de 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -101,7 +101,7 @@ public: /// getDescription - Given a diagnostic ID, return a description of the /// issue. - const char *getDescription(unsigned DiagID) const; + llvm::StringRef getDescription(unsigned DiagID) const; /// isBuiltinWarningOrExtension - Return true if the unmapped diagnostic /// level of the specified diagnostic ID is a Warning or Extension. @@ -132,15 +132,18 @@ public: /// getWarningOptionForDiag - Return the lowest-level warning option that /// enables the specified diagnostic. If there is no -Wfoo flag that controls /// the diagnostic, this returns null. - static const char *getWarningOptionForDiag(unsigned DiagID); - + static llvm::StringRef getWarningOptionForDiag(unsigned DiagID); + /// getCategoryNumberForDiag - Return the category number that a specified /// DiagID belongs to, or 0 if no category. static unsigned getCategoryNumberForDiag(unsigned DiagID); + /// getNumberOfCategories - Return the number of categories + static unsigned getNumberOfCategories(); + /// getCategoryNameFromID - Given a category ID, return the name of the /// category. - static const char *getCategoryNameFromID(unsigned CategoryID); + static llvm::StringRef getCategoryNameFromID(unsigned CategoryID); /// \brief Enumeration describing how the the emission of a diagnostic should /// be treated when it occurs during C++ template argument deduction. @@ -179,24 +182,24 @@ public: static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID); /// getName - Given a diagnostic ID, return its name - static const char *getName(unsigned DiagID); + static llvm::StringRef getName(unsigned DiagID); /// getIdFromName - Given a diagnostic name, return its ID, or 0 - static unsigned getIdFromName(char const *Name); + static unsigned getIdFromName(llvm::StringRef Name); /// getBriefExplanation - Given a diagnostic ID, return a brief explanation /// of the issue - static const char *getBriefExplanation(unsigned DiagID); + static llvm::StringRef getBriefExplanation(unsigned DiagID); /// getFullExplanation - Given a diagnostic ID, return a full explanation /// of the issue - static const char *getFullExplanation(unsigned DiagID); + static llvm::StringRef getFullExplanation(unsigned DiagID); private: /// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g. /// "unknown-pragmas" to have the specified mapping. This returns true and /// ignores the request if "Group" was unknown, false otherwise. - bool setDiagnosticGroupMapping(const char *Group, diag::Mapping Map, + bool setDiagnosticGroupMapping(llvm::StringRef Group, diag::Mapping Map, SourceLocation Loc, Diagnostic &Diag) const; /// \brief Based on the way the client configured the Diagnostic diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index c37e510..fb1c909 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -108,6 +108,7 @@ def err_expected_ident_lparen : Error<"expected identifier or '('">; def err_expected_ident_lbrace : Error<"expected identifier or '{'">; def err_expected_lbrace : Error<"expected '{'">; def err_expected_lparen : Error<"expected '('">; +def err_expected_lparen_or_lbrace : Error<"expected '('or '{'">; def err_expected_rparen : Error<"expected ')'">; def err_expected_lsquare : Error<"expected '['">; def err_expected_rsquare : Error<"expected ']'">; @@ -161,6 +162,8 @@ def err_unexpected_namespace_attributes_alias : Error< def err_inline_namespace_alias : Error<"namespace alias cannot be inline">; def err_namespace_nonnamespace_scope : Error< "namespaces can only be defined in global or namespace scope">; +def err_nested_namespaces_with_double_colon : Error< + "nested namespace definition must define each namespace separately">; def err_expected_semi_after_attribute_list : Error< "expected ';' after attribute list">; def err_expected_semi_after_static_assert : Error< @@ -190,6 +193,8 @@ def ext_ref_qualifier : ExtWarn< "reference qualifiers on functions are a C++0x extension">, InGroup<CXX0x>; def ext_inline_namespace : ExtWarn< "inline namespaces are a C++0x feature">, InGroup<CXX0x>; +def err_generalized_initializer_lists : Error< + "generalized initializer lists are a C++0x extension unsupported in Clang">; def ext_generalized_initializer_lists : ExtWarn< "generalized initializer lists are a C++0x extension unsupported in Clang">, InGroup<CXX0x>; @@ -343,6 +348,9 @@ def err_operator_string_not_empty : Error< // Classes. def err_anon_type_definition : Error< "declaration of anonymous %0 must be a definition">; +def err_default_delete_in_multiple_declaration : Error< + "'= %select{default|delete}0' is a function definition and must occur in a " + "standalone declaration">; def err_cxx0x_attribute_forbids_arguments : Error< "C++0x attribute '%0' cannot have an argument list">; @@ -434,12 +442,26 @@ def err_missing_whitespace_digraph : Error< def warn_deleted_function_accepted_as_extension: ExtWarn< "deleted function definition accepted as a C++0x extension">, InGroup<CXX0x>; +def warn_defaulted_function_accepted_as_extension: ExtWarn< + "defaulted function definition accepted as a C++0x extension">, + InGroup<CXX0x>; + +// C++0x in-class member initialization +def warn_nonstatic_member_init_accepted_as_extension: ExtWarn< + "in-class initialization of non-static data member accepted as a C++0x extension">, + InGroup<CXX0x>; +def err_bitfield_member_init: Error< + "bitfield member cannot have an in-class initializer">; +def err_incomplete_array_member_init: Error< + "array bound cannot be deduced from an in-class initializer">; // C++0x alias-declaration def ext_alias_declaration : ExtWarn< "alias declarations accepted as a C++0x extension">, InGroup<CXX0x>; def err_alias_declaration_not_identifier : Error< "name defined in alias declaration must be an identifier">; +def err_alias_declaration_specialization : Error< + "%select{partial specialization|explicit specialization|explicit instantiation}0 of alias templates is not permitted">; // C++0x override control def ext_override_control_keyword : Extension< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 0a0c91a..5cfa61b 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -261,10 +261,11 @@ def err_builtin_definition : Error<"definition of builtin function %0">; def err_types_compatible_p_in_cplusplus : Error< "__builtin_types_compatible_p is not valid in C++">; def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError; -def warn_non_pod_memset : Warning< - "destination for this memset call is a pointer to a non-POD type %0">, - InGroup<DiagGroup<"non-pod-memset">>, DefaultIgnore; -def note_non_pod_memset_silence : Note< +def warn_dyn_class_memaccess : Warning< + "%select{destination for|source of}0 this %1 call is a pointer to dynamic " + "class %2; vtable pointer will be overwritten">, + InGroup<DiagGroup<"dynamic-class-memaccess">>; +def note_bad_memaccess_silence : Note< "explicitly cast the pointer to silence this warning">; /// main() @@ -371,7 +372,8 @@ def warn_conflicting_ret_types : Warning< "conflicting return type in implementation of %0: %1 vs %2">; def warn_conflicting_ret_type_modifiers : Warning< "conflicting distributed object modifiers on return type " - "in implementation of %0">; + "in implementation of %0">, + InGroup<DiagGroup<"distributed-object-modifiers">>; def warn_non_covariant_ret_types : Warning< "conflicting return type in implementation of %0: %1 vs %2">, InGroup<DiagGroup<"method-signatures">>, DefaultIgnore; @@ -380,7 +382,8 @@ def warn_conflicting_param_types : Warning< "conflicting parameter types in implementation of %0: %1 vs %2">; def warn_conflicting_param_modifiers : Warning< "conflicting distributed object modifiers on parameter type " - "in implementation of %0">; + "in implementation of %0">, + InGroup<DiagGroup<"distributed-object-modifiers">>; def warn_non_contravariant_param_types : Warning< "conflicting parameter types in implementation of %0: %1 vs %2">, InGroup<DiagGroup<"method-signatures">>, DefaultIgnore; @@ -495,6 +498,8 @@ def err_static_assert_expression_is_not_constant : Error< "static_assert expression is not an integral constant expression">; def err_static_assert_failed : Error<"static_assert failed \"%0\"">; +def warn_inline_namespace_reopened_noninline : Warning< + "inline namespace cannot be re-opened as a non-inline namespace">; def err_inline_namespace_mismatch : Error< "%select{|non-}0inline namespace " "cannot be reopened as %select{non-|}0inline">; @@ -504,11 +509,12 @@ def err_unexpected_friend : Error< def ext_enum_friend : ExtWarn< "enumeration type %0 cannot be a friend">; def ext_nonclass_type_friend : ExtWarn< - "non-class type %0 cannot be a friend">; + "non-class friend type %0 is a C++0x extension">, InGroup<CXX0x>; def err_friend_is_member : Error< "friends cannot be members of the declaring class">; def ext_unelaborated_friend_type : ExtWarn< - "must specify '%select{struct|union|class|enum}0' to befriend %1">; + "specify '%select{struct|union|class|enum}0' to befriend %1; accepted " + "as a C++0x extension">, InGroup<CXX0x>; def err_qualified_friend_not_found : Error< "no function named %0 with type %1 was found in the specified scope">; def err_introducing_special_friend : Error< @@ -539,12 +545,12 @@ def err_type_defined_in_result_type : Error< "%0 can not be defined in the result type of a function">; def err_type_defined_in_param_type : Error< "%0 can not be defined in a parameter type">; +def err_type_defined_in_alias_template : Error< + "%0 can not be defined in a type alias template">; def note_pure_virtual_function : Note< "unimplemented pure virtual method %0 in %1">; -def err_deleted_non_function : Error< - "only functions can have deleted definitions">; def err_deleted_decl_not_first : Error< "deleted definition must be first declaration">; @@ -572,6 +578,9 @@ def warn_mismatched_exception_spec : ExtWarn< def err_override_exception_spec : Error< "exception specification of overriding function is more lax than " "base version">; +def warn_override_exception_spec : ExtWarn< + "exception specification of overriding function is more lax than " + "base version">, InGroup<Microsoft>; def err_incompatible_exception_specs : Error< "target exception specification is not superset of source">; def err_deep_exception_specs_differ : Error< @@ -580,12 +589,18 @@ def warn_missing_exception_specification : Warning< "%0 is missing exception specification '%1'">; def err_noexcept_needs_constant_expression : Error< "argument to noexcept specifier must be a constant expression">; +def err_exception_spec_unknown : Error< + "exception specification is not available until end of class definition">; // C++ access checking def err_class_redeclared_with_different_access : Error< "%0 redeclared with '%1' access">; def err_access : Error< "%1 is a %select{private|protected}0 member of %3">, AccessControl; +def war_ms_using_declaration_inaccessible : ExtWarn< + "using declaration refers to inaccessible member '%0', which refers " + "to accessible member '%1', accepted for Microsoft compatibility">, + AccessControl, InGroup<Microsoft>; def err_access_ctor : Error< "calling a %select{private|protected}0 constructor of class %2">, AccessControl; @@ -593,13 +608,18 @@ def ext_rvalue_to_reference_access_ctor : ExtWarn< "C++98 requires an accessible copy constructor for class %2 when binding " "a reference to a temporary; was %select{private|protected}0">, AccessControl, InGroup<BindToTemporaryCopy>; -def err_access_base : Error< +def err_access_base_ctor : Error< + // The ERRORs represent other special members that aren't constructors, in + // hopes that someone will bother noticing and reporting if they appear "%select{base class|inherited virtual base class}0 %1 has %select{private|" - "protected}3 %select{constructor|copy constructor|copy assignment operator|" - "destructor}2">, AccessControl; -def err_access_field: Error< - "field of type %0 has %select{private|protected}2 %select{constructor|copy " - "constructor|copy assignment operator|destructor}1">, AccessControl; + "protected}3 %select{default |copy |move |*ERROR* |*ERROR* " + "|*ERROR*|}2constructor">, AccessControl; +def err_access_field_ctor : Error< + // The ERRORs represent other special members that aren't constructors, in + // hopes that someone will bother noticing and reporting if they appear + "field of type %0 has %select{private|protected}2 " + "%select{default |copy |move |*ERROR* |*ERROR* |*ERROR* |}1constructor">, + AccessControl; def err_access_ctor_field : Error<"field of type %1 has %select{private|protected}2 constructor">, @@ -715,39 +735,52 @@ def err_member_function_initialization : Error< "initializer on function does not look like a pure-specifier">; def err_non_virtual_pure : Error< "%0 is not virtual and cannot be declared pure">; +def warn_pure_function_definition : ExtWarn< + "function definition with pure-specifier is a Microsoft extension">, + InGroup<Microsoft>; def err_implicit_object_parameter_init : Error< "cannot initialize object parameter of type %0 with an expression " "of type %1">; def err_qualified_member_of_unrelated : Error< "%q0 is not a member of class %1">; +def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning< + "call to pure virtual member function %0; overrides of %0 in subclasses are " + "not available in the %select{constructor|destructor}1 of %2">; + 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< - "implicit default %select{constructor|copy constructor|" - "copy assignment operator|destructor}0 for %1 first required here">; + "implicit default %select{constructor|copy constructor|move constructor|copy " + "assignment operator|move assignment operator|destructor}0 for %1 first " + "required here">; def err_missing_default_ctor : Error< "%select{|implicit default }0constructor for %1 must explicitly initialize " "the %select{base class|member}2 %3 which does not have a default " "constructor">; def err_illegal_union_or_anon_struct_member : Error< "%select{anonymous struct|union}0 member %1 has a non-trivial " - "%select{constructor|copy constructor|copy assignment operator|destructor}2">; + "%select{constructor|copy constructor|move constructor|copy assignment " + "operator|move assignment operator|destructor}2">; def note_nontrivial_has_virtual : Note< "because type %0 has a virtual %select{member function|base class}1">; def note_nontrivial_has_nontrivial : Note< "because type %0 has a %select{member|base class}1 with a non-trivial " - "%select{constructor|copy constructor|copy assignment operator|destructor}2">; + "%select{constructor|copy constructor|move constructor|copy assignment " + "operator|move assignment operator|destructor}2">; def note_nontrivial_user_defined : Note< "because type %0 has a user-declared %select{constructor|copy constructor|" - "copy assignment operator|destructor}1">; + "move constructor|copy assignment operator|move assignment operator|" + "destructor}1">; def err_static_data_member_not_allowed_in_union_or_anon_struct : Error< "static data member %0 not allowed in %select{anonymous struct|union}1">; def err_union_member_of_reference_type : Error< "union member %0 has reference type %1">; - +def ext_anonymous_struct_union_qualified : Extension< + "anonymous %select{struct|union}0 cannot be '%select{const|volatile|" + "restrict}1'">; def err_different_return_type_for_overriding_virtual_function : Error< "virtual function %0 has a different return type (%1) than the " "function it overrides (which has return type %2)">; @@ -942,8 +975,8 @@ def err_illegal_decl_array_of_auto : Error< def err_new_array_of_auto : Error< "cannot allocate array of 'auto'">; def err_auto_not_allowed : Error< - "'auto' not allowed %select{in function prototype|in struct member" - "|in union member|in class member|in exception declaration" + "'auto' not allowed %select{in function prototype|in non-static struct member" + "|in non-static union member|in non-static class member|in exception declaration" "|in template parameter|in block literal|in template argument" "|in typedef|in type alias|in function return type|here}0">; def err_auto_var_requires_init : Error< @@ -1000,16 +1033,23 @@ def err_enum_redeclare_fixed_mismatch : Error< "enumeration previously declared with %select{non|}0fixed underlying type">; def err_enum_redeclare_scoped_mismatch : Error< "enumeration previously declared as %select{un|}0scoped">; +def err_only_enums_have_underlying_types : Error< + "only enumeration types have underlying types">; +def err_incomplete_type_no_underlying_type : Error< + "an incomplete enumeration type has no underlying type yet">; // C++0x delegating constructors def err_delegation_0x_only : Error< "delegating constructors are permitted only in C++0x">; -def err_delegation_unimplemented : Error< - "delegating constructors are not fully implemented">; def err_delegating_initializer_alone : Error< "an initializer for a delegating constructor must appear alone">; -def err_delegating_ctor_loop : Error< - "constructor %0 delegates to itself (possibly indirectly)">; +def warn_delegating_ctor_cycle : Warning< + "constructor for %0 creates a delegation cycle">, DefaultError, + InGroup<DelegatingCtorCycles>; +def note_it_delegates_to : Note< + "it delegates to">, InGroup<DelegatingCtorCycles>; +def note_which_delegates_to : Note< + "which delegates to">, InGroup<DelegatingCtorCycles>; def err_delegating_codegen_not_implemented : Error< "code generation for delegating constructors not implemented">; @@ -1140,6 +1180,8 @@ def warn_attribute_void_function_method : Warning< "%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_gc_attribute_weak_on_local : Warning< + "Objective-C GC does not allow weak variables on the stack">; def warn_attribute_weak_on_local : Warning< "__weak attribute cannot be specified on an automatic variable">; def warn_weak_identifier_undeclared : Warning< @@ -1242,7 +1284,9 @@ def warn_impcast_different_enum_types : Warning< def warn_impcast_bool_to_null_pointer : Warning< "initialization of pointer of type %0 to NULL from a constant boolean " "expression">, InGroup<BoolConversions>; - +def warn_impcast_null_pointer_to_integer : Warning< + "implicit conversion of NULL constant to integer">, + InGroup<DiagGroup<"conversion">>, DefaultIgnore; def warn_cast_align : Warning< "cast from %0 to %1 increases required alignment from %2 to %3">, @@ -1374,6 +1418,13 @@ def note_first_required_here : Note< def err_uninitialized_member_in_ctor : Error< "%select{|implicit default }0constructor for %1 must explicitly initialize " "the %select{reference|const}2 member %3">; +def warn_default_arg_makes_ctor_special : Warning< + "addition of default argument on redeclaration makes this constructor a " + "%select{default|copy|move}0 constructor">, InGroup<DefaultArgSpecialMember>; +def note_previous_declaration_special : Note< + // The ERRORs are in hopes that if they occur, they'll get reported. + "previous declaration was %select{*ERROR*|a copy constructor|a move " + "constructor|*ERROR*|*ERROR*|*ERROR*|not a special member function}0">; def err_use_of_default_argument_to_function_declared_later : Error< "use of default argument to function %0 that is declared later in class %1">; @@ -1412,7 +1463,9 @@ def note_ovl_candidate : Note<"candidate " "function |function |constructor |" "is the implicit default constructor|" "is the implicit copy constructor|" + "is the implicit move constructor|" "is the implicit copy assignment operator|" + "is the implicit move assignment operator|" "is an inherited constructor}0%1">; def note_ovl_candidate_inherited_constructor : Note<"inherited from here">; @@ -1443,7 +1496,9 @@ def note_ovl_candidate_arity : Note<"candidate " "%select{function|function|constructor|function|function|constructor|" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0 %select{|template }1" "not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 " "%plural{1:was|:were}4 provided">; @@ -1463,7 +1518,9 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 " "not viable: cannot convert argument of incomplete type %2 to %3">; def note_ovl_candidate_bad_overload : Note<"candidate " @@ -1471,7 +1528,9 @@ def note_ovl_candidate_bad_overload : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1" " not viable: no overload of %3 matching %2 for %ordinal4 argument">; def note_ovl_candidate_bad_conv : Note<"candidate " @@ -1479,7 +1538,9 @@ def note_ovl_candidate_bad_conv : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1" " not viable: no known conversion from %2 to %3 for " "%select{%ordinal5 argument|object argument}4">; @@ -1488,7 +1549,9 @@ def note_ovl_candidate_bad_addrspace : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) is in " "address space %3, but parameter must be in address space %4">; @@ -1497,7 +1560,9 @@ def note_ovl_candidate_bad_gc : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 " "lifetime, but parameter has %select{no|__weak|__strong}4 lifetime">; @@ -1512,7 +1577,9 @@ def note_ovl_candidate_bad_cvr : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1 not viable: " "%ordinal4 argument (%2) would lose " "%select{const|restrict|const and restrict|volatile|const and volatile|" @@ -1523,7 +1590,9 @@ def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate " "function |function |constructor |" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" "constructor (inherited)}0%1" " not viable: cannot %select{convert from|convert from|bind}2 " "%select{base class pointer|superclass|base class object of type}2 %3 to " @@ -1666,7 +1735,7 @@ def err_template_arg_must_be_expr : Error< def err_template_arg_nontype_ambig : Error< "template argument for non-type template parameter is treated as type %0">; def err_template_arg_must_be_template : Error< - "template argument for template template parameter must be a class template">; + "template argument for template template parameter must be a class template%select{| or type alias template}0">; def ext_template_arg_local_type : ExtWarn< "template argument uses local type %0">, InGroup<LocalTypeTemplateArgs>; def ext_template_arg_unnamed_type : ExtWarn< @@ -1802,6 +1871,8 @@ def err_not_class_template_specialization : Error< "parameter}0">; def err_function_specialization_in_class : Error< "cannot specialize a function %0 within class scope">; +def err_explicit_specialization_storage_class : Error< + "explicit specialization cannot have a storage class">; // C++ class template specializations and out-of-line definitions def err_template_spec_needs_header : Error< @@ -1812,6 +1883,8 @@ def err_template_spec_needs_template_parameters : Error< def err_template_param_list_matches_nontemplate : Error< "template parameter list matching the non-templated nested type %0 should " "be empty ('template<>')">; +def err_alias_template_extra_headers : Error< + "extraneous template parameter list in alias template declaration">; def err_template_spec_extra_headers : Error< "extraneous template parameter list in template specialization or " "out-of-line template definition">; @@ -1823,6 +1896,9 @@ def note_explicit_template_spec_does_not_need_header : Note< def err_template_qualified_declarator_no_match : Error< "nested name specifier '%0' for declaration does not refer into a class, " "class template or class template partial specialization">; +def err_specialize_member_of_template : Error< + "cannot specialize (with 'template<>') a member of an unspecialized " + "template">; // C++ Class Template Partial Specialization def err_default_arg_in_partial_spec : Error< @@ -1889,6 +1965,8 @@ def note_function_template_spec_here : Note< "in instantiation of function template specialization %q0 requested here">; def note_template_static_data_member_def_here : Note< "in instantiation of static data member %q0 requested here">; +def note_template_type_alias_instantiation_here : Note< + "in instantiation of template type alias %0 requested here">; def note_default_arg_instantiation_here : Note< "in instantiation of default argument for '%0' required here">; @@ -1954,6 +2032,8 @@ def err_explicit_instantiation_requires_name : Error< "explicit instantiation declaration requires a name">; def err_explicit_instantiation_of_typedef : Error< "explicit instantiation of typedef %0">; +def err_explicit_instantiation_storage_class : Error< + "explicit instantiation cannot have a storage class">; def err_explicit_instantiation_not_known : Error< "explicit instantiation of %0 does not refer to a function template, member " "function, member class, or static data member">; @@ -1971,7 +2051,7 @@ def note_explicit_instantiation_candidate : Note< "explicit instantiation candidate function template here %0">; def err_explicit_instantiation_inline : Error< "explicit instantiation cannot be 'inline'">; -def ext_explicit_instantiation_without_qualified_id : ExtWarn< +def ext_explicit_instantiation_without_qualified_id : Extension< "qualifier in explicit instantiation of %q0 requires a template-id " "(a typedef is not permitted)">; def err_explicit_instantiation_unqualified_wrong_namespace : Error< @@ -2026,7 +2106,7 @@ def err_non_type_template_in_nested_name_specifier : Error< def err_template_id_not_a_type : Error< "template name refers to non-type template '%0'">; def note_template_declared_here : Note< - "%select{function template|class template|template template parameter}0 " + "%select{function template|class template|type alias template|template template parameter}0 " "%1 declared here">; // C++0x Variadic Templates @@ -2099,6 +2179,10 @@ def err_unexpected_namespace : Error< def err_undeclared_var_use : Error<"use of undeclared identifier %0">; def note_dependent_var_use : Note<"must qualify identifier to find this " "declaration in dependent base class">; +def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither " + "visible in the template definition nor found by argument dependent lookup">; +def note_not_found_by_two_phase_lookup : Note<"%0 should be declared prior to the " + "call site%select{| or in %2| or in an associated namespace of one of its arguments}1">; def err_undeclared_use : Error<"use of undeclared %0">; def warn_deprecated : Warning<"%0 is deprecated">, InGroup<DeprecatedDeclarations>; @@ -2115,7 +2199,8 @@ def err_unavailable_message : Error<"%0 is unavailable: %1">; def warn_unavailable_fwdclass_message : Warning< "%0 maybe unavailable because receiver type is unknown">; def note_unavailable_here : Note< - "function has been explicitly marked %select{unavailable|deleted|deprecated}0 here">; + "function has been explicitly marked " + "%select{unavailable|deleted|deprecated}0 here">; def warn_not_enough_argument : Warning< "not enough variable arguments in %0 declaration to fit a sentinel">; def warn_missing_sentinel : Warning < @@ -2127,8 +2212,13 @@ def warn_missing_prototype : Warning< InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore; def err_redefinition : Error<"redefinition of %0">; def err_definition_of_implicitly_declared_member : Error< - "definition of implicitly declared %select{constructor|copy constructor|" - "copy assignment operator|destructor}1">; + "definition of implicitly declared %select{default constructor|copy " + "constructor|move constructor|copy assignment operator|move assignment " + "operator|destructor}1">; +def err_definition_of_explicitly_defaulted_member : Error< + "definition of explicitly defaulted %select{default constructor|copy " + "constructor|move constructor|copy assignment operator|move assignment " + "operator|destructor}0">; def err_redefinition_extern_inline : Error< "redefinition of a 'extern inline' function %0 is not supported in " "%select{C99 mode|C++}1">; @@ -2164,9 +2254,9 @@ def err_redefinition_different_type : Error< def err_redefinition_different_kind : Error< "redefinition of %0 as different kind of symbol">; def err_redefinition_different_typedef : Error< - "%select{typedef|type alias}0 redefinition with different types (%1 vs %2)">; + "%select{typedef|type alias|type alias template}0 redefinition with different types (%1 vs %2)">; def err_tag_reference_non_tag : Error< - "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template}0">; + "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0">; def err_tag_reference_conflict : Error< "implicit declaration introduced by elaborated type conflicts with " "%select{a declaration|a typedef|a type alias|a template}0 of the same name">; @@ -2180,9 +2270,15 @@ def err_nested_redefinition : Error<"nested redefinition of %0">; def err_use_with_wrong_tag : Error< "use of %0 with tag type that does not match previous declaration">; def warn_struct_class_tag_mismatch : Warning< - "%select{struct|class}0 %select{|template}1 %2 was previously declared " - "as a %select{class|struct}0 %select{|template}1">, + "%select{struct|class}0%select{| template}1 %2 was previously declared " + "as a %select{class|struct}0%select{| template}1">, InGroup<MismatchedTags>, DefaultIgnore; +def warn_struct_class_previous_tag_mismatch : Warning< + "%2 defined as a %select{struct|class}0%select{| template}1 here but " + "previously declared as a %select{class|struct}0%select{| template}1">, + InGroup<MismatchedTags>, DefaultIgnore; +def note_struct_class_suggestion : Note< + "did you mean %select{struct|class}0 here?">; def ext_forward_ref_enum : Extension< "ISO C forbids forward references to 'enum' types">; def err_forward_ref_enum : Error< @@ -2482,6 +2578,14 @@ def note_precedence_bitwise_first : Note< def note_precedence_bitwise_silence : Note< "place parentheses around the %0 expression to silence this warning">; +def warn_precedence_conditional : Warning< + "?: has lower precedence than %0; %0 will be evaluated first">, + InGroup<Parentheses>; +def note_precedence_conditional_first : Note< + "place parentheses around the ?: expression to evaluate it first">; +def note_precedence_conditional_silence : Note< + "place parentheses around the %0 expression to silence this warning">; + def warn_logical_instead_of_bitwise : Warning< "use of logical %0 with constant operand; switch to bitwise %1 or " "remove constant">, InGroup<DiagGroup<"constant-logical-operand">>; @@ -2641,6 +2745,10 @@ def warn_indirection_through_null : Warning< "indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>; def note_indirection_through_null : Note< "consider using __builtin_trap() or qualifying pointer with 'volatile'">; +def warn_pointer_indirection_from_incompatible_type : Warning< + "dereference of type %1 that was reinterpret_cast from type %0 has undefined " + "behavior.">, + InGroup<DiagGroup<"undefined-reinterpret-cast">>, DefaultIgnore; def err_assignment_requires_nonfragile_object : Error< "cannot assign to class object in non-fragile ABI (%0 invalid)">; @@ -2839,6 +2947,8 @@ def err_objc_pointer_cxx_catch_fragile : Error< "exception model">; def err_objc_object_catch : Error< "can't catch an Objective C object by value">; +def err_incomplete_type_objc_at_encode : Error< + "'@encode' of incomplete type %0">; def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " @@ -2904,6 +3014,9 @@ def err_bad_cxx_cast_member_pointer_size : Error< def err_bad_static_cast_incomplete : Error<"%0 is an incomplete type">; def err_bad_reinterpret_cast_reference : Error< "reinterpret_cast of a %0 to %1 needs its address which is not allowed">; +def warn_undefined_reinterpret_cast : Warning< + "reinterpret_cast from %0 to %1 has undefined behavior.">, + InGroup<DiagGroup<"undefined-reinterpret-cast">>, DefaultIgnore; // These messages don't adhere to the pattern. // FIXME: Display the path somehow better. @@ -3016,6 +3129,9 @@ def err_objc_exceptions_disabled : Error< def warn_non_virtual_dtor : Warning< "%0 has virtual functions but non-virtual destructor">, InGroup<NonVirtualDtor>, DefaultIgnore; +def warn_delete_non_virtual_dtor : Warning< + "delete called on %0 that has virtual functions but non-virtual destructor">, + InGroup<DeleteNonVirtualDtor>, DefaultIgnore; def warn_overloaded_virtual : Warning< "%q0 hides overloaded virtual %select{function|functions}1">, InGroup<OverloadedVirtual>, DefaultIgnore; @@ -3170,7 +3286,8 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " "%select{from|to parameter of type|from a function with result type|to type|" - "with an expression of type|to parameter of type|to type}2 %1">; + "with an expression of type|to parameter of type|to type}2 %1">, + InGroup<DiagGroup<"incompatible-pointer-types">>; def ext_typecheck_convert_discards_qualifiers : ExtWarn< "%select{assigning to|passing|returning|converting|initializing|sending|casting}2" " %0 " @@ -3281,8 +3398,8 @@ def err_cannot_pass_objc_interface_to_vararg : Error< "%select{function|block|method}1">; def warn_cannot_pass_non_pod_arg_to_vararg : Warning< - "cannot pass object of non-POD type %0 through variadic " - "%select{function|block|method|constructor}1; call will abort at runtime">, + "cannot pass object of %select{non-POD|non-trivial}0 type %1 through variadic" + " %select{function|block|method|constructor}2; call will abort at runtime">, InGroup<DiagGroup<"non-pod-varargs">>, DefaultError; def err_typecheck_call_invalid_ordered_compare : Error< @@ -3591,6 +3708,47 @@ def warn_not_compound_assign : Warning< def warn_explicit_conversion_functions : Warning< "explicit conversion functions are a C++0x extension">, InGroup<CXX0x>; +// C++0x defaulted functions +def err_defaulted_default_ctor_params : Error< + "an explicitly-defaulted default constructor must have no parameters">; +def err_defaulted_copy_ctor_params : Error< + "an explicitly-defaulted copy constructor must have exactly one parameter">; +def err_defaulted_copy_ctor_volatile_param : Error< + "the parameter for an explicitly-defaulted copy constructor may not be " + "volatile">; +def err_defaulted_copy_ctor_const_param : Error< + "the parameter for this explicitly-defaulted copy constructor is const, but " + "a member or base requires it to be non-const">; +def err_defaulted_copy_assign_params : Error< + "an explicitly-defaulted copy assignment operator must have exactly one " + "parameter">; +def err_defaulted_copy_assign_return_type : Error< + "an explicitly-defaulted copy assignment operator must return an unqualified " + "lvalue reference to its class type">; +def err_defaulted_copy_assign_not_ref : Error< + "the parameter for an explicitly-defaulted copy assignment operator must be an " + "lvalue reference type">; +def err_defaulted_copy_assign_volatile_param : Error< + "the parameter for an explicitly-defaulted copy assignment operator may not " + "be volatile">; +def err_defaulted_copy_assign_const_param : Error< + "the parameter for this explicitly-defaulted copy assignment operator is " + "const, but a member or base requires it to be non-const">; +def err_defaulted_copy_assign_quals : Error< + "an explicitly-defaulted copy assignment operator may not have 'const' " + "or 'volatile' qualifiers">; +def err_incorrect_defaulted_exception_spec : Error< + "exception specification of explicitly defaulted %select{default constructor|" + "copy constructor|move constructor|copy assignment operator|move assignment " + "operator|destructor}0 does not match the " + "calculated one">; +def err_out_of_line_default_deletes : Error< + "defaulting this %select{default constructor|copy constructor|move " + "constructor|copy assignment operator|move assignment operator|destructor}0 " + "would delete it after its first declaration">; +def err_defaulted_move_unsupported : Error< + "defaulting move functions not yet supported">; + def warn_array_index_precedes_bounds : Warning< "array index of '%0' indexes before the beginning of the array">, InGroup<DiagGroup<"array-bounds">>; @@ -3955,7 +4113,28 @@ def err_unknown_any_var_function_type : Error< def err_filter_expression_integral : Error< "filter expression type should be an integral value not %0">; +// OpenCL warnings and errors. +def err_invalid_astype_of_different_size : Error< + "invalid reinterpretation: sizes of %0 and %1 must match">; + } // end of sema category +let CategoryName = "Related Result Type Issue" in { +// Objective-C related result type compatibility +def warn_related_result_type_compatibility_class : Warning< + "method is expected to return an instance of its class type %0, but " + "is declared to return %1">; +def warn_related_result_type_compatibility_protocol : Warning< + "protocol method is expected to return an instance of the implementing " + "class, but is declared to return %0">; +def note_related_result_type_overridden : Note< + "overridden method is part of the '%select{|alloc|copy|init|mutableCopy|" + "new|autorelease|dealloc|release|retain|retainCount|self}0' method family">; +def note_related_result_type_inferred : Note< + "%select{class|instance}0 method %1 is assumed to return an instance of " + "its receiver type (%2)">; + +} + } // end of sema component. diff --git a/include/clang/Basic/ExceptionSpecificationType.h b/include/clang/Basic/ExceptionSpecificationType.h index aecf6eb..98cfd29 100644 --- a/include/clang/Basic/ExceptionSpecificationType.h +++ b/include/clang/Basic/ExceptionSpecificationType.h @@ -18,12 +18,13 @@ namespace clang { /// \brief The various types of exception specifications that exist in C++0x. enum ExceptionSpecificationType { - EST_None, ///< no exception specification - EST_DynamicNone, ///< throw() - EST_Dynamic, ///< throw(T1, T2) - EST_MSAny, ///< Microsoft throw(...) extension - EST_BasicNoexcept, ///< noexcept - EST_ComputedNoexcept ///< noexcept(expression) + EST_None, ///< no exception specification + EST_DynamicNone, ///< throw() + EST_Dynamic, ///< throw(T1, T2) + EST_MSAny, ///< Microsoft throw(...) extension + EST_BasicNoexcept, ///< noexcept + EST_ComputedNoexcept, ///< noexcept(expression) + EST_Delayed ///< not known yet }; inline bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType) { diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 683ec83..b4eca6d 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -498,7 +498,8 @@ enum ObjCMethodFamily { OMF_dealloc, OMF_release, OMF_retain, - OMF_retainCount + OMF_retainCount, + OMF_self }; /// Enough bits to store any enumerator in ObjCMethodFamily or diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index a5f6789..f0f1432 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -46,6 +46,8 @@ public: unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled unsigned ObjCNonFragileABI2 : 1; // Objective-C enhanced modern abi enabled unsigned ObjCDefaultSynthProperties : 1; // Objective-C auto-synthesized properties. + unsigned ObjCInferRelatedResultType : 1; // Infer Objective-C related return + // types unsigned AppleKext : 1; // Allow apple kext features. unsigned PascalStrings : 1; // Allow Pascal strings @@ -173,6 +175,7 @@ public: GC = ObjC1 = ObjC2 = ObjCNonFragileABI = ObjCNonFragileABI2 = 0; AppleKext = 0; ObjCDefaultSynthProperties = 0; + ObjCInferRelatedResultType = 0; NoConstantCFStrings = 0; InlineVisibilityHidden = 0; C99 = C1X = Microsoft = Borland = CPlusPlus = CPlusPlus0x = 0; CXXOperatorNames = PascalStrings = WritableStrings = ConstStrings = 0; diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index 14bb2b7..ee5f96f 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -54,6 +54,9 @@ public: private: friend class SourceManager; + friend class ASTWriter; + friend class ASTReader; + static FileID get(unsigned V) { FileID F; F.ID = V; diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index c121bbb..df5074c 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -831,6 +831,14 @@ public: return getFileCharacteristic(Loc) == SrcMgr::C_ExternCSystem; } + /// \brief Returns true if the given MacroID location points at the first + /// token of the macro instantiation. + bool isAtStartOfMacroInstantiation(SourceLocation Loc) const; + + /// \brief Returns true if the given MacroID location points at the last + /// token of the macro instantiation. + bool isAtEndOfMacroInstantiation(SourceLocation Loc) const; + //===--------------------------------------------------------------------===// // Line Table Manipulation Routines //===--------------------------------------------------------------------===// diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index 2f0ad9f..d21bda7 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -54,6 +54,7 @@ namespace clang { TST_typeofType, TST_typeofExpr, TST_decltype, // C++0x decltype + TST_underlyingType, // __underlying_type for C++0x TST_auto, // C++0x auto TST_unknown_anytype, // __unknown_anytype extension TST_error // erroneous type diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 15ac760..03f4cc3 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -146,3 +146,5 @@ def SEHTryStmt : Stmt; def SEHExceptStmt : Stmt; def SEHFinallyStmt : Stmt; +// OpenCL Extensions. +def AsTypeExpr : DStmt<Expr>; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index b830bf2..76006d4 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -368,11 +368,14 @@ public: ConstraintInfo *OutputConstraints, unsigned NumOutputs, unsigned &Index) const; - virtual std::string convertConstraint(const char Constraint) const { + // Constraint parm will be left pointing at the last character of + // the constraint. In practice, it won't be changed unless the + // constraint is longer than one character. + virtual std::string convertConstraint(const char *&Constraint) const { // 'p' defaults to 'r', but can be overridden by targets. - if (Constraint == 'p') + if (*Constraint == 'p') return std::string("r"); - return std::string(1, Constraint); + return std::string(1, *Constraint); } // Returns a string of target-specific clobbers, in LLVM format. diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index f9d1f4e..dfba7ee 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -346,6 +346,10 @@ KEYWORD(__is_polymorphic , KEYCXX) KEYWORD(__is_trivial , KEYCXX) KEYWORD(__is_union , KEYCXX) +// Clang-only C++ Type Traits +KEYWORD(__is_trivially_copyable , KEYCXX) +KEYWORD(__underlying_type , KEYCXX) + // Embarcadero Expression Traits KEYWORD(__is_lvalue_expr , KEYCXX) KEYWORD(__is_rvalue_expr , KEYCXX) @@ -409,6 +413,7 @@ KEYWORD(__read_write , KEYOPENCL) ALIAS("read_only", __read_only , KEYOPENCL) ALIAS("write_only", __write_only , KEYOPENCL) ALIAS("read_write", __read_write , KEYOPENCL) +KEYWORD(__builtin_astype , KEYOPENCL) // Borland Extensions. KEYWORD(__pascal , KEYALL) @@ -451,6 +456,8 @@ KEYWORD(__except , KEYMS | KEYBORLAND) KEYWORD(__finally , KEYMS | KEYBORLAND) KEYWORD(__leave , KEYMS | KEYBORLAND) KEYWORD(__int64 , KEYMS) +KEYWORD(__if_exists , KEYMS) +KEYWORD(__if_not_exists , KEYMS) ALIAS("__int8" , char , KEYMS) ALIAS("__int16" , short , KEYMS) ALIAS("__int32" , int , KEYMS) diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h index 4a2a2c6..a7a45bd 100644 --- a/include/clang/Basic/TypeTraits.h +++ b/include/clang/Basic/TypeTraits.h @@ -23,7 +23,7 @@ namespace clang { UTT_HasNothrowConstructor, UTT_HasTrivialAssign, UTT_HasTrivialCopy, - UTT_HasTrivialConstructor, + UTT_HasTrivialDefaultConstructor, UTT_HasTrivialDestructor, UTT_HasVirtualDestructor, UTT_IsAbstract, @@ -54,6 +54,7 @@ namespace clang { UTT_IsSigned, UTT_IsStandardLayout, UTT_IsTrivial, + UTT_IsTriviallyCopyable, UTT_IsUnion, UTT_IsUnsigned, UTT_IsVoid, diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index 6d6c7c7..b3da122 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -75,6 +75,7 @@ class Inst <string n, string p, string t, Op o> { string Types = t; Op Operand = o; bit isShift = 0; + bit isVCVT_N = 0; } // Used to generate Builtins.def: @@ -297,11 +298,13 @@ def VGET_LOW : Inst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; def VCVT_S32 : SInst<"vcvt_s32", "xd", "fQf">; def VCVT_U32 : SInst<"vcvt_u32", "ud", "fQf">; def VCVT_F16 : SInst<"vcvt_f16", "hk", "f">; -def VCVT_N_S32 : SInst<"vcvt_n_s32", "xdi", "fQf">; -def VCVT_N_U32 : SInst<"vcvt_n_u32", "udi", "fQf">; def VCVT_F32 : SInst<"vcvt_f32", "fd", "iUiQiQUi">; def VCVT_F32_F16 : SInst<"vcvt_f32_f16", "fd", "h">; +let isVCVT_N = 1 in { +def VCVT_N_S32 : SInst<"vcvt_n_s32", "xdi", "fQf">; +def VCVT_N_U32 : SInst<"vcvt_n_u32", "udi", "fQf">; def VCVT_N_F32 : SInst<"vcvt_n_f32", "fdi", "iUiQiQUi">; +} def VMOVN : IInst<"vmovn", "hk", "silUsUiUl">; def VMOVL : SInst<"vmovl", "wd", "csiUcUsUi">; def VQMOVN : SInst<"vqmovn", "hk", "silUsUiUl">; diff --git a/include/clang/Driver/CC1AsOptions.td b/include/clang/Driver/CC1AsOptions.td index 2643c4f..b1067b7 100644 --- a/include/clang/Driver/CC1AsOptions.td +++ b/include/clang/Driver/CC1AsOptions.td @@ -77,3 +77,6 @@ def relax_all : Flag<"-relax-all">, def no_exec_stack : Flag<"--noexecstack">, HelpText<"Mark the file as not needing an executable stack">; + +def fatal_warnings : Flag<"--fatal-warnings">, + HelpText<"Consider warnings as errors">; diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index d243bf9..14d8f67 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -140,6 +140,9 @@ def femit_coverage_notes : Flag<"-femit-coverage-notes">, HelpText<"Emit a gcov coverage notes file when compiling.">; def femit_coverage_data: Flag<"-femit-coverage-data">, HelpText<"Instrument the program to emit gcov coverage data when run.">; +def coverage_file : Separate<"-coverage-file">, + HelpText<"Emit coverage data to this filename. The extension will be replaced.">; +def coverage_file_EQ : Joined<"-coverage-file=">, Alias<coverage_file>; def relaxed_aliasing : Flag<"-relaxed-aliasing">, HelpText<"Turn off Type Based Alias Analysis">; def masm_verbose : Flag<"-masm-verbose">, @@ -178,6 +181,8 @@ def mconstructor_aliases : Flag<"-mconstructor-aliases">, HelpText<"Emit complete constructors and destructors as aliases when possible">; def mms_bitfields : Flag<"-mms-bitfields">, HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard.">; +def mstackrealign : Flag<"-mstackrealign">, + HelpText<"Force realign the stack at entry to every function.">; def O : Joined<"-O">, HelpText<"Optimization level">; def Os : Flag<"-Os">, HelpText<"Optimize for size">; def Oz : Flag<"-Oz">, HelpText<"Optimize for size, regardless of performance">; @@ -211,6 +216,8 @@ def diagnostic_log_file : Separate<"-diagnostic-log-file">, HelpText<"Filename (or -) to log diagnostics to">; def fno_show_column : Flag<"-fno-show-column">, HelpText<"Do not include column number on diagnostics">; +def fshow_column : Flag<"-fshow-column">, + HelpText<"Include column number on diagnostics">; def fno_show_source_location : Flag<"-fno-show-source-location">, HelpText<"Do not include source location information with diagnostics">; def fshow_overloads_EQ : Joined<"-fshow-overloads=">, @@ -240,6 +247,8 @@ def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">, HelpText<"Print diagnostic name">; def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, HelpText<"Print option name with mappable diagnostics">; +def fdiagnostics_format : Separate<"-fdiagnostics-format">, + HelpText<"Change diagnostic formatting to match IDE and command line tools">; def fdiagnostics_show_category : Separate<"-fdiagnostics-show-category">, HelpText<"Print diagnostic category">; def fdiagnostics_show_note_include_stack : @@ -414,6 +423,8 @@ def fno_assume_sane_operator_new : Flag<"-fno-assume-sane-operator-new">, HelpText<"Don't assume that C++'s global operator new can't alias any pointer">; def fgnu_keywords : Flag<"-fgnu-keywords">, HelpText<"Allow GNU-extension keywords regardless of language standard">; +def fgnu89_inline : Flag<"-fgnu89-inline">, + HelpText<"Use the gnu89 inline semantics">; def fno_gnu_keywords : Flag<"-fno-gnu-keywords">, HelpText<"Disallow GNU-extension keywords regardless of language standard">; def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, @@ -482,6 +493,8 @@ def print_ivar_layout : Flag<"-print-ivar-layout">, HelpText<"Enable Objective-C Ivar layout bitmap print trace">; def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, HelpText<"enable objective-c's nonfragile abi">; +def fobjc_infer_related_result_type : Flag<"-fobjc-infer-related-result-type">, + HelpText<"infer Objective-C related result type based on method family">; def ftrapv : Flag<"-ftrapv">, HelpText<"Trap on integer overflow">; def ftrapv_handler : Separate<"-ftrapv-handler">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 38f0c57..7203976 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -238,8 +238,8 @@ def emit_llvm : Flag<"-emit-llvm">, def exported__symbols__list : Separate<"-exported_symbols_list">; def e : JoinedOrSeparate<"-e">; def fPIC : Flag<"-fPIC">, Group<f_Group>; -def fPIE : Flag<"-fPIE">, Group<f_Group>; -def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>; +def fPIE : Flag<"-fPIE">, Group<f_Group>, Flags<[NoArgumentUnused]>; +def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>, Flags<[NoArgumentUnused]>; def faccess_control : Flag<"-faccess-control">, Group<f_Group>; def fallow_unsupported : Flag<"-fallow-unsupported">, Group<f_Group>; def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>; @@ -278,6 +278,7 @@ def fdiagnostics_parseable_fixits : Flag<"-fdiagnostics-parseable-fixits">, Grou def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>; def fdiagnostics_show_name : Flag<"-fdiagnostics-show-name">, Group<f_Group>; def fdiagnostics_show_note_include_stack : Flag<"-fdiagnostics-show-note-include-stack">, Group<f_Group>; +def fdiagnostics_format_EQ : Joined<"-fdiagnostics-format=">, Group<f_clang_Group>; def fdiagnostics_show_category_EQ : Joined<"-fdiagnostics-show-category=">, Group<f_clang_Group>; def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>; def fdwarf2_cfi_asm : Flag<"-fdwarf2-cfi-asm">, Group<f_Group>; @@ -298,6 +299,8 @@ def fno_for_scope : Flag<"-fno-for-scope">, Group<f_Group>; def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>; def fgnu_keywords : Flag<"-fgnu-keywords">, Group<f_Group>; +def fgnu89_inline : Flag<"-fgnu89-inline">, Group<f_Group>; +def fno_gnu89_inline : Flag<"-fno-gnu89-inline">, Group<f_Group>; def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>; def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">; def filelist : Separate<"-filelist">, Flags<[LinkerInput]>; @@ -389,6 +392,10 @@ def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>; def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>; def fobjc_legacy_dispatch : Flag<"-fobjc-legacy-dispatch">, Group<f_Group>; def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>; +def fobjc_infer_related_result_type : Flag<"-fobjc-infer-related-result-type">, + Group<f_Group>; +def fno_objc_infer_related_result_type : Flag< + "-fno-objc-infer-related-result-type">, Group<f_Group>; // Objective-C ABI options. def fobjc_abi_version_EQ : Joined<"-fobjc-abi-version=">, Group<f_Group>; @@ -406,8 +413,8 @@ def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>; def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>; def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>; def fpic : Flag<"-fpic">, Group<f_Group>; -def fpie : Flag<"-fpie">, Group<f_Group>; -def fno_pie : Flag<"-fno-pie">, Group<f_Group>; +def fpie : Flag<"-fpie">, Group<f_Group>, Flags<[NoArgumentUnused]>; +def fno_pie : Flag<"-fno-pie">, Group<f_Group>, Flags<[NoArgumentUnused]>; def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>; def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>; def framework : Separate<"-framework">, Flags<[LinkerInput]>; @@ -418,6 +425,7 @@ def fshort_enums : Flag<"-fshort-enums">, Group<f_Group>; def freorder_blocks : Flag<"-freorder-blocks">, Group<clang_ignored_f_Group>; def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>; def fshow_overloads_EQ : Joined<"-fshow-overloads=">, Group<f_Group>; +def fshow_column : Flag<"-fshow-column">, Group<f_Group>; def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>; def fspell_checking : Flag<"-fspell-checking">, Group<f_Group>; def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>; @@ -513,6 +521,7 @@ def mlinker_version_EQ : Joined<"-mlinker-version=">, Flags<[NoForward]>; def mllvm : Separate<"-mllvm">; def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>; def mms_bitfields : Flag<"-mms-bitfields">, Group<m_Group>; +def mstackrealign : Flag<"-mstackrealign">, Group<m_Group>; def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>; def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>; def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>; diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index da6949f..626d54c 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -157,7 +157,7 @@ public: virtual bool SupportsProfiling() const { return true; } /// Does this tool chain support Objective-C garbage collection. - virtual bool SupportsObjCGC() const { return false; } + virtual bool SupportsObjCGC() const { return true; } /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf /// compile unit information. diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 57c59d9..339297e 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -51,6 +51,7 @@ class HeaderSearch; class Preprocessor; class SourceManager; class TargetInfo; +class ASTFrontendAction; using namespace idx; @@ -248,6 +249,10 @@ private: /// \brief Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults; + /// \brief Whether we want to include nested macro instantiations in the + /// detailed preprocessing record. + bool NestedMacroInstantiations; + static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, const char **ArgBegin, const char **ArgEnd, ASTUnit &AST, bool CaptureDiagnostics); @@ -574,6 +579,21 @@ private: public: + /// \brief Create an ASTUnit from a source file, via a CompilerInvocation + /// object, by invoking the optionally provided ASTFrontendAction. + /// + /// \param CI - The compiler invocation to use; it must have exactly one input + /// source file. The ASTUnit takes ownership of the CompilerInvocation object. + /// + /// \param Diags - The diagnostics engine to use for reporting errors; its + /// lifetime is expected to extend past that of the returned ASTUnit. + /// + /// \param Action - The ASTFrontendAction to invoke. Its ownership is not + /// transfered. + static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI, + llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + ASTFrontendAction *Action = 0); + /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a /// CompilerInvocation object. /// @@ -591,7 +611,8 @@ public: bool CaptureDiagnostics = false, bool PrecompilePreamble = false, bool CompleteTranslationUnit = true, - bool CacheCodeCompletionResults = false); + bool CacheCodeCompletionResults = false, + bool NestedMacroInstantiations = true); /// LoadFromCommandLine - Create an ASTUnit from a vector of command line /// arguments, which must specify exactly one source file. @@ -620,7 +641,8 @@ public: bool CompleteTranslationUnit = true, bool CacheCodeCompletionResults = false, bool CXXPrecompilePreamble = false, - bool CXXChainedPCH = false); + bool CXXChainedPCH = false, + bool NestedMacroInstantiations = true); /// \brief Reparse the source files using the same command-line options that /// were originally used to produce this translation unit. diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 8bef6a3..1c686c7 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -95,6 +95,10 @@ public: /// The code model to use (-mcmodel). std::string CodeModel; + /// The filename with path we use for coverage files. The extension will be + /// replaced. + std::string CoverageFile; + /// Enable additional debugging information. std::string DebugPass; diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index ff92058..56093c3 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -37,6 +37,10 @@ public: unsigned ShowNoteIncludeStack : 1; /// Show include stacks for notes. unsigned ShowCategories : 2; /// Show categories: 0 -> none, 1 -> Number, /// 2 -> Full Name. + + unsigned Format : 2; /// Format for diagnostics: + enum TextDiagnosticFormat { Clang, Msvc, Vi }; + unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences. unsigned ShowOverloads : 1; /// Overload candidates to show. Values from /// Diagnostic::OverloadsShown @@ -86,6 +90,7 @@ public: ShowNames = 0; ShowOptionNames = 0; ShowCategories = 0; + Format = Clang; ShowSourceRanges = 0; ShowParseableFixits = 0; VerifyDiagnostics = 0; diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h index 74ca519..ea37bdd 100644 --- a/include/clang/Frontend/LangStandard.h +++ b/include/clang/Frontend/LangStandard.h @@ -18,14 +18,15 @@ namespace frontend { enum LangFeatures { BCPLComment = (1 << 0), - C99 = (1 << 1), - C1X = (1 << 2), - CPlusPlus = (1 << 3), - CPlusPlus0x = (1 << 4), - Digraphs = (1 << 5), - GNUMode = (1 << 6), - HexFloat = (1 << 7), - ImplicitInt = (1 << 8) + C89 = (1 << 1), + C99 = (1 << 2), + C1X = (1 << 3), + CPlusPlus = (1 << 4), + CPlusPlus0x = (1 << 5), + Digraphs = (1 << 6), + GNUMode = (1 << 7), + HexFloat = (1 << 8), + ImplicitInt = (1 << 9) }; } @@ -54,6 +55,9 @@ public: /// hasBCPLComments - Language supports '//' comments. bool hasBCPLComments() const { return Flags & frontend::BCPLComment; } + /// isC89 - Language is a superset of C89. + bool isC89() const { return Flags & frontend::C89; } + /// isC99 - Language is a superset of C99. bool isC99() const { return Flags & frontend::C99; } diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def index 586e5c8..6055ad5 100644 --- a/include/clang/Frontend/LangStandards.def +++ b/include/clang/Frontend/LangStandards.def @@ -22,21 +22,21 @@ // C89-ish modes. LANGSTANDARD(c89, "c89", "ISO C 1990", - ImplicitInt) + C89 | ImplicitInt) LANGSTANDARD(c90, "c90", "ISO C 1990", - ImplicitInt) + C89 | ImplicitInt) LANGSTANDARD(iso9899_1990, "iso9899:1990", "ISO C 1990", - ImplicitInt) + C89 | ImplicitInt) LANGSTANDARD(c94, "iso9899:199409", "ISO C 1990 with amendment 1", - Digraphs | ImplicitInt) + C89 | Digraphs | ImplicitInt) LANGSTANDARD(gnu89, "gnu89", "ISO C 1990 with GNU extensions", - BCPLComment | Digraphs | GNUMode | ImplicitInt) + BCPLComment | C89 | Digraphs | GNUMode | ImplicitInt) // C99-ish modes LANGSTANDARD(c99, "c99", @@ -87,7 +87,6 @@ LANGSTANDARD(gnucxx0x, "gnu++0x", BCPLComment | CPlusPlus | CPlusPlus0x | Digraphs | GNUMode) // OpenCL - LANGSTANDARD(opencl, "cl", "OpenCL 1.0", BCPLComment | C99 | Digraphs | HexFloat) diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h index e875ec1..e471c5c 100644 --- a/include/clang/Frontend/PreprocessorOptions.h +++ b/include/clang/Frontend/PreprocessorOptions.h @@ -41,6 +41,10 @@ public: /// record of all macro definitions and /// instantiations. + /// \brief Whether the detailed preprocessing record includes nested macro + /// instantiations. + unsigned DetailedRecordIncludesNestedMacroInstantiations : 1; + /// The implicit PCH included at the start of the translation unit, or empty. std::string ImplicitPCHInclude; @@ -136,6 +140,7 @@ public: public: PreprocessorOptions() : UsePredefines(true), DetailedRecord(false), + DetailedRecordIncludesNestedMacroInstantiations(true), DisablePCHValidation(false), DisableStatCache(false), DumpDeserializedPCHDecls(false), PrecompiledPreambleBytes(0, true), diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index e499716..3c34c2d 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -71,9 +71,6 @@ void ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts); void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS, const PreprocessorOutputOptions &Opts); -/// CheckDiagnostics - Gather the expected diagnostics and check them. -bool CheckDiagnostics(Preprocessor &PP); - /// AttachDependencyFileGen - Create a dependency file generator, and attach /// it to the given preprocessor. This takes ownership of the output stream. void AttachDependencyFileGen(Preprocessor &PP, diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index fec4dad..5e36d8e 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -31,6 +31,9 @@ struct HeaderFileInfo { /// isImport - True if this is a #import'd or #pragma once file. unsigned isImport : 1; + /// isPragmaOnce - True if this is #pragma once file. + unsigned isPragmaOnce : 1; + /// DirInfo - Keep track of whether this is a system header, and if so, /// whether it is C++ clean or not. This can be set by the include paths or /// by #pragma gcc system_header. This is an instance of @@ -66,8 +69,8 @@ struct HeaderFileInfo { const IdentifierInfo *ControllingMacro; HeaderFileInfo() - : isImport(false), DirInfo(SrcMgr::C_User), External(false), - Resolved(false), NumIncludes(0), ControllingMacroID(0), + : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), + External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0), ControllingMacro(0) {} /// \brief Retrieve the controlling macro for this header file, if @@ -77,7 +80,8 @@ struct HeaderFileInfo { /// \brief Determine whether this is a non-default header file info, e.g., /// it corresponds to an actual header we've included or tried to include. bool isNonDefault() const { - return isImport || NumIncludes || ControllingMacro || ControllingMacroID; + return isImport || isPragmaOnce || NumIncludes || ControllingMacro || + ControllingMacroID; } }; @@ -101,11 +105,12 @@ class HeaderSearch { FileManager &FileMgr; /// #include search path information. Requests for #include "x" search the /// directory of the #including file first, then each directory in SearchDirs - /// consequtively. Requests for <x> search the current dir first, then each - /// directory in SearchDirs, starting at SystemDirIdx, consequtively. If + /// consecutively. Requests for <x> search the current dir first, then each + /// directory in SearchDirs, starting at AngledDirIdx, consecutively. If /// NoCurDirSearch is true, then the check for the file in the current /// directory is suppressed. std::vector<DirectoryLookup> SearchDirs; + unsigned AngledDirIdx; unsigned SystemDirIdx; bool NoCurDirSearch; @@ -156,8 +161,12 @@ public: /// SetSearchPaths - Interface for setting the file search paths. /// void SetSearchPaths(const std::vector<DirectoryLookup> &dirs, - unsigned systemDirIdx, bool noCurDirSearch) { + unsigned angledDirIdx, unsigned systemDirIdx, + bool noCurDirSearch) { + assert(angledDirIdx <= systemDirIdx && systemDirIdx <= dirs.size() && + "Directory indicies are unordered"); SearchDirs = dirs; + AngledDirIdx = angledDirIdx; SystemDirIdx = systemDirIdx; NoCurDirSearch = noCurDirSearch; //LookupFileCache.clear(); @@ -242,7 +251,9 @@ public: /// MarkFileIncludeOnce - Mark the specified file as a "once only" file, e.g. /// due to #pragma once. void MarkFileIncludeOnce(const FileEntry *File) { - getFileInfo(File).isImport = true; + HeaderFileInfo &FI = getFileInfo(File); + FI.isImport = true; + FI.isPragmaOnce = true; } /// MarkFileSystemHeader - Mark the specified file as a system header, e.g. @@ -265,6 +276,13 @@ public: getFileInfo(File).ControllingMacro = ControllingMacro; } + /// \brief Determine whether this file is intended to be safe from + /// multiple inclusions, e.g., it has #pragma once or a controlling + /// macro. + /// + /// This routine does not consider the effect of #import + bool isFileMultipleIncludeGuarded(const FileEntry *File); + /// CreateHeaderMap - This method returns a HeaderMap for the specified /// FileEntry, uniquing them through the the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); @@ -285,6 +303,20 @@ public: search_dir_iterator search_dir_end() const { return SearchDirs.end(); } unsigned search_dir_size() const { return SearchDirs.size(); } + search_dir_iterator quoted_dir_begin() const { + return SearchDirs.begin(); + } + search_dir_iterator quoted_dir_end() const { + return SearchDirs.begin() + AngledDirIdx; + } + + search_dir_iterator angled_dir_begin() const { + return SearchDirs.begin() + AngledDirIdx; + } + search_dir_iterator angled_dir_end() const { + return SearchDirs.begin() + SystemDirIdx; + } + search_dir_iterator system_dir_begin() const { return SearchDirs.begin() + SystemDirIdx; } diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index dcaf445..ec3d9c5 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -156,7 +156,9 @@ public: StringLiteralParser(const Token *StringToks, unsigned NumStringToks, const SourceManager &sm, const LangOptions &features, const TargetInfo &target, Diagnostic *diags = 0) - : SM(sm), Features(features), Target(target), Diags(diags) { + : SM(sm), Features(features), Target(target), Diags(diags), + MaxTokenLength(0), SizeBound(0), wchar_tByteWidth(0), + ResultPtr(ResultBuf.data()), hadError(false), AnyWide(false), Pascal(false) { init(StringToks, NumStringToks); } @@ -165,8 +167,8 @@ public: bool AnyWide; bool Pascal; - const char *GetString() { return &ResultBuf[0]; } - unsigned GetStringLength() const { return ResultPtr-&ResultBuf[0]; } + const char *GetString() { return ResultBuf.data(); } + unsigned GetStringLength() const { return ResultPtr-ResultBuf.data(); } unsigned GetNumStringChars() const { if (AnyWide) diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index 7be8455..e498e9d 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -258,6 +258,10 @@ namespace clang { /// including the various preprocessing directives processed, macros /// instantiated, etc. class PreprocessingRecord : public PPCallbacks { + /// \brief Whether we should include nested macro instantiations in + /// the preprocessing record. + bool IncludeNestedMacroInstantiations; + /// \brief Allocator used to store preprocessing objects. llvm::BumpPtrAllocator BumpAlloc; @@ -281,7 +285,8 @@ namespace clang { void MaybeLoadPreallocatedEntities() const ; public: - PreprocessingRecord(); + /// \brief Construct + explicit PreprocessingRecord(bool IncludeNestedMacroInstantiations); /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { @@ -291,6 +296,10 @@ namespace clang { /// \brief Deallocate memory in the preprocessing record. void Deallocate(void *Ptr) { } + size_t getTotalMemory() const { + return BumpAlloc.getTotalMemory(); + } + // Iteration over the preprocessed entities. typedef std::vector<PreprocessedEntity *>::iterator iterator; typedef std::vector<PreprocessedEntity *>::const_iterator const_iterator; diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 616507a..76e3f59 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -84,6 +84,7 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> { IdentifierInfo *Ident_Pragma, *Ident__pragma; // _Pragma, __pragma IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__ IdentifierInfo *Ident__has_feature; // __has_feature + IdentifierInfo *Ident__has_extension; // __has_extension IdentifierInfo *Ident__has_builtin; // __has_builtin IdentifierInfo *Ident__has_attribute; // __has_attribute IdentifierInfo *Ident__has_include; // __has_include @@ -441,7 +442,7 @@ public: /// \brief Create a new preprocessing record, which will keep track of /// all macro expansions, macro definitions, etc. - void createPreprocessingRecord(); + void createPreprocessingRecord(bool IncludeNestedMacroInstantiations); /// EnterMainSourceFile - Enter the specified FileID as the main source file, /// which implicitly adds the builtin defines etc. diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 3fd9844..e4cdc27 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -580,6 +580,18 @@ private: /// ExitScope - Pop a scope off the scope stack. void ExitScope(); + /// \brief RAII object used to modify the scope flags for the current scope. + class ParseScopeFlags { + Scope *CurScope; + unsigned OldFlags; + ParseScopeFlags(const ParseScopeFlags &); // do not implement + void operator=(const ParseScopeFlags &); // do not implement + + public: + ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true); + ~ParseScopeFlags(); + }; + //===--------------------------------------------------------------------===// // Diagnostic Emission and Error recovery. @@ -621,8 +633,8 @@ private: /// - function bodies /// - default arguments /// - exception-specifications (TODO: C++0x) - /// - and brace-or-equal-initializers (TODO: C++0x) - /// for non-static data members (including such things in nested classes)." + /// - and brace-or-equal-initializers for non-static data members + /// (including such things in nested classes)." /// LateParsedDeclarations build the tree of those elements so they can /// be parsed after parsing the top-level class. class LateParsedDeclaration { @@ -630,6 +642,7 @@ private: virtual ~LateParsedDeclaration(); virtual void ParseLexedMethodDeclarations(); + virtual void ParseLexedMemberInitializers(); virtual void ParseLexedMethodDefs(); }; @@ -641,6 +654,7 @@ private: virtual ~LateParsedClass(); virtual void ParseLexedMethodDeclarations(); + virtual void ParseLexedMemberInitializers(); virtual void ParseLexedMethodDefs(); private: @@ -714,6 +728,25 @@ private: llvm::SmallVector<LateParsedDefaultArgument, 8> DefaultArgs; }; + /// LateParsedMemberInitializer - An initializer for a non-static class data + /// member whose parsing must to be delayed until the class is completely + /// defined (C++11 [class.mem]p2). + struct LateParsedMemberInitializer : public LateParsedDeclaration { + LateParsedMemberInitializer(Parser *P, Decl *FD) + : Self(P), Field(FD) { } + + virtual void ParseLexedMemberInitializers(); + + Parser *Self; + + /// Field - The field declaration. + Decl *Field; + + /// CachedTokens - The sequence of tokens that comprises the initializer, + /// including any leading '='. + CachedTokens Toks; + }; + /// LateParsedDeclarationsContainer - During parsing of a top (non-nested) /// C++ class, its method declarations that contain parts that won't be /// parsed until after the definition is completed (C++ [class.mem]p2), @@ -973,11 +1006,14 @@ private: Decl *ParseCXXInlineMethodDef(AccessSpecifier AS, ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, - const VirtSpecifiers& VS); + const VirtSpecifiers& VS, ExprResult& Init); + void ParseCXXNonStaticMemberInitializer(Decl *VarD); void ParseLexedMethodDeclarations(ParsingClass &Class); void ParseLexedMethodDeclaration(LateParsedMethodDeclaration &LM); void ParseLexedMethodDefs(ParsingClass &Class); void ParseLexedMethodDef(LexedMethod &LM); + void ParseLexedMemberInitializers(ParsingClass &Class); + void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI); bool ConsumeAndStoreUntil(tok::TokenKind T1, CachedTokens &Toks, bool StopAtSemi = true, @@ -1000,7 +1036,7 @@ private: DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs, ParsingDeclSpec *DS = 0); - bool isDeclarationAfterDeclarator() const; + bool isDeclarationAfterDeclarator(); bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator); DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs, AccessSpecifier AS = AS_none); @@ -1308,7 +1344,12 @@ private: StmtResult ParseReturnStatement(ParsedAttributes &Attr); StmtResult ParseAsmStatement(bool &msAsm); StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc); - bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, + bool ParseMicrosoftIfExistsCondition(bool& Result); + void ParseMicrosoftIfExistsStatement(StmtVector &Stmts); + void ParseMicrosoftIfExistsExternalDeclaration(); + void ParseMicrosoftIfExistsClassDeclaration(DeclSpec::TST TagType, + AccessSpecifier& CurAS); +bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, llvm::SmallVectorImpl<ExprTy *> &Constraints, llvm::SmallVectorImpl<ExprTy *> &Exprs); @@ -1645,6 +1686,7 @@ private: void ParseTypeofSpecifier(DeclSpec &DS); void ParseDecltypeSpecifier(DeclSpec &DS); + void ParseUnderlyingTypeSpecifier(DeclSpec &DS); ExprResult ParseCXX0XAlignArgument(SourceLocation Start); @@ -1714,6 +1756,12 @@ private: Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd, SourceLocation InlineLoc = SourceLocation()); + void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, + std::vector<IdentifierInfo*>& Ident, + std::vector<SourceLocation>& NamespaceLoc, + unsigned int index, SourceLocation& InlineLoc, + SourceLocation& LBrace, ParsedAttributes& attrs, + SourceLocation& RBraceLoc); Decl *ParseLinkage(ParsingDeclSpec &DS, unsigned Context); Decl *ParseUsingDirectiveOrDeclaration(unsigned Context, const ParsedTemplateInfo &TemplateInfo, @@ -1743,6 +1791,8 @@ private: bool SuppressDeclarations = false); void ParseCXXMemberSpecification(SourceLocation StartLoc, unsigned TagType, Decl *TagDecl); + ExprResult ParseCXXMemberInitializer(bool IsFunction, + SourceLocation &EqualLoc); void ParseCXXClassMemberDeclaration(AccessSpecifier AS, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), ParsingDeclRAIIObject *DiagsFromTParams = 0); diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 882440b..d322180 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -88,7 +88,10 @@ enum { /// \brief Adjustment for KVC code pattern priorities when it doesn't look /// like the - CCD_ProbablyNotObjCCollection = 15 + CCD_ProbablyNotObjCCollection = 15, + + /// \brief An Objective-C method being used as a property. + CCD_MethodAsProperty = 2 }; /// \brief Priority value factors by which we will divide or multiply the diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 708c9b2..7ce4e00 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -249,6 +249,7 @@ public: static const TST TST_typeofType = clang::TST_typeofType; static const TST TST_typeofExpr = clang::TST_typeofExpr; static const TST TST_decltype = clang::TST_decltype; + static const TST TST_underlyingType = clang::TST_underlyingType; static const TST TST_auto = clang::TST_auto; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; static const TST TST_error = clang::TST_error; @@ -344,7 +345,8 @@ private: void SaveStorageSpecifierAsWritten(); static bool isTypeRep(TST T) { - return (T == TST_typename || T == TST_typeofType); + return (T == TST_typename || T == TST_typeofType || + T == TST_underlyingType); } static bool isExprRep(TST T) { return (T == TST_typeofExpr || T == TST_decltype); @@ -462,6 +464,14 @@ public: SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } + /// \brief Clear out all of the type qualifiers. + void ClearTypeQualifiers() { + TypeQualifiers = 0; + TQ_constLoc = SourceLocation(); + TQ_restrictLoc = SourceLocation(); + TQ_volatileLoc = SourceLocation(); + } + // function-specifier bool isInlineSpecified() const { return FS_inline_specified; } SourceLocation getInlineSpecLoc() const { return FS_inlineLoc; } @@ -1068,8 +1078,8 @@ struct DeclaratorChunk { /// If this is an invalid location, there is no ref-qualifier. unsigned RefQualifierLoc; - /// \brief When ExceptionSpecType isn't EST_None, the location of the - /// keyword introducing the spec. + /// \brief When ExceptionSpecType isn't EST_None or EST_Delayed, the + /// location of the keyword introducing the spec. unsigned ExceptionSpecLoc; /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that @@ -1332,7 +1342,8 @@ public: CXXCatchContext, // C++ catch exception-declaration BlockLiteralContext, // Block literal declarator. TemplateTypeArgContext, // Template type argument. - AliasDeclContext // C++0x alias-declaration. + AliasDeclContext, // C++0x alias-declaration. + AliasTemplateContext // C++0x alias-declaration template. }; private: @@ -1474,6 +1485,7 @@ public: case TypeNameContext: case AliasDeclContext: + case AliasTemplateContext: case PrototypeContext: case ObjCPrototypeContext: case TemplateParamContext: @@ -1503,6 +1515,7 @@ public: case TypeNameContext: case AliasDeclContext: + case AliasTemplateContext: case ObjCPrototypeContext: case BlockLiteralContext: case TemplateTypeArgContext: @@ -1531,6 +1544,7 @@ public: case CXXCatchContext: case TypeNameContext: case AliasDeclContext: + case AliasTemplateContext: case BlockLiteralContext: case TemplateTypeArgContext: return false; @@ -1602,6 +1616,29 @@ public: DeclTypeInfo.erase(DeclTypeInfo.begin()); } + /// isArrayOfUnknownBound - This method returns true if the declarator + /// is a declarator for an array of unknown bound (looking through + /// parentheses). + bool isArrayOfUnknownBound() const { + for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { + switch (DeclTypeInfo[i].Kind) { + case DeclaratorChunk::Paren: + continue; + case DeclaratorChunk::Function: + case DeclaratorChunk::Pointer: + case DeclaratorChunk::Reference: + case DeclaratorChunk::BlockPointer: + case DeclaratorChunk::MemberPointer: + return false; + case DeclaratorChunk::Array: + return !DeclTypeInfo[i].Arr.NumElts; + } + llvm_unreachable("Invalid type chunk"); + return false; + } + return false; + } + /// isFunctionDeclarator - This method returns true if the declarator /// is a function declarator (looking through parentheses). /// If true is returned, then the reference type parameter idx is diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index e83e5c0..5dc4438 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -101,7 +101,8 @@ private: /// the temporary is being created. unsigned Location; - /// \brief Whether the + /// \brief Whether the entity being initialized may end up using the + /// named return value optimization (NRVO). bool NRVO; } LocAndNRVO; @@ -436,48 +437,21 @@ public: class InitializationSequence { public: /// \brief Describes the kind of initialization sequence computed. - /// - /// FIXME: Much of this information is in the initialization steps... why is - /// it duplicated here? enum SequenceKind { /// \brief A failed initialization sequence. The failure kind tells what /// happened. FailedSequence = 0, - + /// \brief A dependent initialization, which could not be /// type-checked due to the presence of dependent types or - /// dependently-type expressions. + /// dependently-typed expressions. DependentSequence, - /// \brief A user-defined conversion sequence. - UserDefinedConversion, - - /// \brief A constructor call. - ConstructorInitialization, - - /// \brief A reference binding. - ReferenceBinding, - - /// \brief List initialization - ListInitialization, - - /// \brief Zero-initialization. - ZeroInitialization, - - /// \brief No initialization required. - NoInitialization, - - /// \brief Standard conversion sequence. - StandardConversion, - - /// \brief C conversion sequence. - CAssignment, + /// \brief A normal sequence. + NormalSequence, - /// \brief String initialization - StringInit, - - /// \brief Array initialization from another array (GNU C extension). - ArrayInit + /// \brief A reference binding. + ReferenceBinding // FIXME: Still looks redundant, but complicated. }; /// \brief Describes the kind of a particular step in an initialization @@ -697,7 +671,10 @@ public: void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } /// \brief Determine whether the initialization sequence is valid. - operator bool() const { return SequenceKind != FailedSequence; } + operator bool() const { return !Failed(); } + + /// \brief Determine whether the initialization sequence is invalid. + bool Failed() const { return SequenceKind == FailedSequence; } typedef llvm::SmallVector<Step, 4>::const_iterator step_iterator; step_iterator step_begin() const { return Steps.begin(); } @@ -821,7 +798,7 @@ public: /// \brief Determine why initialization failed. FailureKind getFailureKind() const { - assert(getKind() == FailedSequence && "Not an initialization failure!"); + assert(Failed() && "Not an initialization failure!"); return Failure; } diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 400a7cc..dceed4e 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -282,6 +282,18 @@ public: return NamingClass != 0; } + /// \brief Set whether the name lookup is triggered by a + /// using declaration. + void setUsingDeclaration(bool U) { + UsingDeclaration = U; + } + + /// \brief Returns whether the name lookup is triggered by a + /// using declaration. + bool isUsingDeclaration() const { + return UsingDeclaration; + } + /// \brief Returns the 'naming class' for this lookup, i.e. the /// class which was looked into to find these results. /// @@ -603,6 +615,10 @@ private: bool HideTags; bool Diagnose; + + /// \brief True if the lookup is triggered by a using declaration. + /// Necessary to handle a MSVC bug. + bool UsingDeclaration; }; /// \brief Consumes visible declarations found when searching for diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index e196e83..55931f2 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -202,8 +202,7 @@ namespace clang { void setAsIdentityConversion(); bool isIdentityConversion() const { - return First == ICK_Identity && Second == ICK_Identity && - Third == ICK_Identity; + return Second == ICK_Identity && Third == ICK_Identity; } ImplicitConversionRank getRank() const; diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 6588a1d..7514633 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -79,7 +79,12 @@ public: ObjCMethodScope = 0x400, /// SwitchScope - This is a scope that corresponds to a switch statement. - SwitchScope = 0x800 + SwitchScope = 0x800, + + /// ThisScope - This is the scope of a struct/union/class definition, + /// outside of any member function definition, where 'this' is nonetheless + /// usable. + ThisScope = 0x1000 }; private: /// The parent scope for this scope. This is null for the translation-unit diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 07a14d2..6dd0d3c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -312,6 +312,17 @@ public: /// and must warn if not used. Only contains the first declaration. llvm::SmallVector<const DeclaratorDecl*, 4> UnusedFileScopedDecls; + /// \brief All the delegating constructors seen so far in the file, used for + /// cycle detection at the end of the TU. + llvm::SmallVector<CXXConstructorDecl*, 4> DelegatingCtorDecls; + + /// \brief All the overriding destructors seen during a class definition + /// (there could be multiple due to nested classes) that had their exception + /// spec checks delayed, plus the overridden destructor. + llvm::SmallVector<std::pair<const CXXDestructorDecl*, + const CXXDestructorDecl*>, 2> + DelayedDestructorExceptionSpecChecks; + /// \brief Callback to the parser to parse templated functions when needed. typedef void LateTemplateParserCB(void *P, const FunctionDecl *FD); LateTemplateParserCB *LateTemplateParser; @@ -589,6 +600,44 @@ public: /// A stack of expression evaluation contexts. llvm::SmallVector<ExpressionEvaluationContextRecord, 8> ExprEvalContexts; + /// SpecialMemberOverloadResult - The overloading result for a special member + /// function. + /// + /// This is basically a wrapper around PointerIntPair. The lowest bit of the + /// integer is used to determine whether we have a parameter qualification + /// match, the second-lowest is whether we had success in resolving the + /// overload to a unique non-deleted function. + /// + /// The ConstParamMatch bit represents whether, when looking up a copy + /// constructor or assignment operator, we found a potential copy + /// constructor/assignment operator whose first parameter is const-qualified. + /// This is used for determining parameter types of other objects and is + /// utterly meaningless on other types of special members. + class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode { + llvm::PointerIntPair<CXXMethodDecl*, 2> Pair; + public: + SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID) + : FastFoldingSetNode(ID) + {} + + CXXMethodDecl *getMethod() const { return Pair.getPointer(); } + void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); } + + bool hasSuccess() const { return Pair.getInt() & 0x1; } + void setSuccess(bool B) { + Pair.setInt(unsigned(B) | hasConstParamMatch() << 1); + } + + bool hasConstParamMatch() const { return Pair.getInt() & 0x2; } + void setConstParamMatch(bool B) { + Pair.setInt(B << 1 | unsigned(hasSuccess())); + } + }; + + /// \brief A cache of special member function overload resolution results + /// for C++ records. + llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; + /// \brief Whether the code handled by Sema should be considered a /// complete translation unit or not. /// @@ -704,6 +753,8 @@ public: void ActOnEndOfTranslationUnit(); + void CheckDelegatingCtorCycles(); + Scope *getScopeForContext(DeclContext *Ctx); void PushFunctionScope(); @@ -795,12 +846,19 @@ public: const PartialDiagnostic &PD); bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID); + bool RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD, + std::pair<SourceLocation, + PartialDiagnostic> Note); + QualType getElaboratedType(ElaboratedTypeKeyword Keyword, const CXXScopeSpec &SS, QualType T); QualType BuildTypeofExprType(Expr *E, SourceLocation Loc); QualType BuildDecltypeType(Expr *E, SourceLocation Loc); + QualType BuildUnaryTransformType(QualType BaseType, + UnaryTransformType::UTTKind UKind, + SourceLocation Loc); //===--------------------------------------------------------------------===// // Symbol table / Decl tracking callbacks: SemaDecl.cpp. @@ -925,7 +983,8 @@ public: SourceLocation NameLoc, const Token &NextToken); - Decl *ActOnDeclarator(Scope *S, Declarator &D); + Decl *ActOnDeclarator(Scope *S, Declarator &D, + bool IsFunctionDefintion = false); Decl *HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, @@ -938,6 +997,7 @@ public: void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); void CheckShadow(Scope *S, VarDecl *D); void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); + void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D); NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, QualType R, TypeSourceInfo *TInfo, LookupResult &Previous, bool &Redeclaration); @@ -988,6 +1048,7 @@ public: void ActOnInitializerError(Decl *Dcl); void ActOnCXXForRangeDecl(Decl *D); void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc); + void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc); void FinalizeDeclaration(Decl *D); DeclGroupPtrTy FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, Decl **Group, @@ -1026,10 +1087,11 @@ public: void ActOnPopScope(SourceLocation Loc, Scope *S); void ActOnTranslationUnitScope(Scope *S); - /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with - /// no declarator (e.g. "struct foo;") is parsed. Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS); + Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, + DeclSpec &DS, + MultiTemplateParamsArg TemplateParams); StmtResult ActOnVlaStmt(const DeclSpec &DS); @@ -1041,7 +1103,7 @@ public: RecordDecl *Record); bool isAcceptableTagRedeclaration(const TagDecl *Previous, - TagTypeKind NewTag, + TagTypeKind NewTag, bool isDefinition, SourceLocation NewTagLoc, const IdentifierInfo &Name); @@ -1082,23 +1144,25 @@ public: Declarator &D, Expr *BitfieldWidth); FieldDecl *HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, - Declarator &D, Expr *BitfieldWidth, + Declarator &D, Expr *BitfieldWidth, bool HasInit, AccessSpecifier AS); FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, TypeSourceInfo *TInfo, RecordDecl *Record, SourceLocation Loc, - bool Mutable, Expr *BitfieldWidth, + bool Mutable, Expr *BitfieldWidth, bool HasInit, SourceLocation TSSL, AccessSpecifier AS, NamedDecl *PrevDecl, Declarator *D = 0); enum CXXSpecialMember { - CXXInvalid = -1, - CXXConstructor = 0, - CXXCopyConstructor = 1, - CXXCopyAssignment = 2, - CXXDestructor = 3 + CXXDefaultConstructor, + CXXCopyConstructor, + CXXMoveConstructor, + CXXCopyAssignment, + CXXMoveAssignment, + CXXDestructor, + CXXInvalid }; bool CheckNontrivialField(FieldDecl *FD); void DiagnoseNontrivial(const RecordType* Record, CXXSpecialMember mem); @@ -1283,6 +1347,8 @@ public: QualType ResultType, Expr *Value); + bool CanPerformCopyInitialization(const InitializedEntity &Entity, + ExprResult Init); ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init); @@ -1566,6 +1632,14 @@ public: private: bool CppLookupName(LookupResult &R, Scope *S); + SpecialMemberOverloadResult *LookupSpecialMember(CXXRecordDecl *D, + CXXSpecialMember SM, + bool ConstArg, + bool VolatileArg, + bool RValueThis, + bool ConstThis, + bool VolatileThis); + public: /// \brief Look up a name, looking for a single declaration. Return /// null if the results were absent, ambiguous, or overloaded. @@ -1594,6 +1668,10 @@ public: SourceLocation GnuLabelLoc = SourceLocation()); DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class); + CXXConstructorDecl *LookupDefaultConstructor(CXXRecordDecl *Class); + CXXConstructorDecl *LookupCopyConstructor(CXXRecordDecl *Class, + unsigned Quals, + bool *ConstParam = 0); CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class); void ArgumentDependentLookup(DeclarationName Name, bool Operator, @@ -1645,6 +1723,10 @@ public: AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses); + void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, + bool ConsiderLinkage, + bool ExplicitInstantiationOrSpecialization); + bool DiagnoseAmbiguousLookup(LookupResult &Result); //@} @@ -2067,7 +2149,14 @@ public: void MarkDeclarationReferenced(SourceLocation Loc, Decl *D); void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T); void MarkDeclarationsReferencedInExpr(Expr *E); - + + /// \brief Figure out if an expression could be turned into a call. + bool isExprCallable(const Expr &E, QualType &ZeroArgCallReturnTy, + UnresolvedSetImpl &NonTemplateOverloads); + /// \brief Give notes for a set of overloads. + void NoteOverloads(const UnresolvedSetImpl &Overloads, + const SourceLocation FinalNoteLoc); + /// \brief Conditionally issue a diagnostic based on the current /// evaluation context. /// @@ -2177,8 +2266,7 @@ public: UnaryExprOrTypeTrait ExprKind, SourceRange R); ExprResult CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, - UnaryExprOrTypeTrait ExprKind, - SourceRange R); + UnaryExprOrTypeTrait ExprKind); ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, @@ -2186,8 +2274,9 @@ public: const SourceRange &ArgRange); ExprResult CheckPlaceholderExpr(Expr *E); - bool CheckVecStepExpr(Expr *E, SourceLocation OpLoc, SourceRange R); + bool CheckVecStepExpr(Expr *E); + bool CheckUnaryExprOrTypeTraitOperand(Expr *E, UnaryExprOrTypeTrait ExprKind); bool CheckUnaryExprOrTypeTraitOperand(QualType type, SourceLocation OpLoc, SourceRange R, UnaryExprOrTypeTrait ExprKind); @@ -2364,6 +2453,8 @@ public: bool CheckCaseExpression(Expr *expr); + bool CheckMicrosoftIfExistsSymbol(CXXScopeSpec &SS, UnqualifiedId &Name); + //===------------------------- "Block" Extension ------------------------===// /// ActOnBlockStart - This callback is invoked when a block literal is @@ -2383,6 +2474,13 @@ public: ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, Scope *CurScope); + //===---------------------------- OpenCL Features -----------------------===// + + /// __builtin_astype(...) + ExprResult ActOnAsTypeExpr(Expr *expr, ParsedType DestTy, + SourceLocation BuiltinLoc, + SourceLocation RParenLoc); + //===---------------------------- C++ Features --------------------------===// // Act on C++ namespaces @@ -2454,6 +2552,7 @@ public: SourceLocation TypenameLoc); Decl *ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, + MultiTemplateParamsArg TemplateParams, SourceLocation UsingLoc, UnqualifiedId &Name, TypeResult Type); @@ -2502,6 +2601,111 @@ public: /// constructed variable. void FinalizeVarWithDestructor(VarDecl *VD, const RecordType *DeclInitType); + /// \brief Helper class that collects exception specifications for + /// implicitly-declared special member functions. + class ImplicitExceptionSpecification { + // Pointer to allow copying + ASTContext *Context; + // We order exception specifications thus: + // noexcept is the most restrictive, but is only used in C++0x. + // throw() comes next. + // Then a throw(collected exceptions) + // Finally no specification. + // throw(...) is used instead if any called function uses it. + // + // If this exception specification cannot be known yet (for instance, + // because this is the exception specification for a defaulted default + // constructor and we haven't finished parsing the deferred parts of the + // class yet), the C++0x standard does not specify how to behave. We + // record this as an 'unknown' exception specification, which overrules + // any other specification (even 'none', to keep this rule simple). + ExceptionSpecificationType ComputedEST; + llvm::SmallPtrSet<CanQualType, 4> ExceptionsSeen; + llvm::SmallVector<QualType, 4> Exceptions; + + void ClearExceptions() { + ExceptionsSeen.clear(); + Exceptions.clear(); + } + + public: + explicit ImplicitExceptionSpecification(ASTContext &Context) + : Context(&Context), ComputedEST(EST_BasicNoexcept) { + if (!Context.getLangOptions().CPlusPlus0x) + ComputedEST = EST_DynamicNone; + } + + /// \brief Get the computed exception specification type. + ExceptionSpecificationType getExceptionSpecType() const { + assert(ComputedEST != EST_ComputedNoexcept && + "noexcept(expr) should not be a possible result"); + return ComputedEST; + } + + /// \brief The number of exceptions in the exception specification. + unsigned size() const { return Exceptions.size(); } + + /// \brief The set of exceptions in the exception specification. + const QualType *data() const { return Exceptions.data(); } + + /// \brief Integrate another called method into the collected data. + void CalledDecl(CXXMethodDecl *Method); + + /// \brief Integrate an invoked expression into the collected data. + void CalledExpr(Expr *E); + + /// \brief Specify that the exception specification can't be detemined yet. + void SetDelayed() { + ClearExceptions(); + ComputedEST = EST_Delayed; + } + + FunctionProtoType::ExtProtoInfo getEPI() const { + FunctionProtoType::ExtProtoInfo EPI; + EPI.ExceptionSpecType = getExceptionSpecType(); + EPI.NumExceptions = size(); + EPI.Exceptions = data(); + return EPI; + } + }; + + /// \brief Determine what sort of exception specification a defaulted + /// copy constructor of a class will have. + ImplicitExceptionSpecification + ComputeDefaultedDefaultCtorExceptionSpec(CXXRecordDecl *ClassDecl); + + /// \brief Determine what sort of exception specification a defaulted + /// default constructor of a class will have, and whether the parameter + /// will be const. + std::pair<ImplicitExceptionSpecification, bool> + ComputeDefaultedCopyCtorExceptionSpecAndConst(CXXRecordDecl *ClassDecl); + + /// \brief Determine what sort of exception specification a defautled + /// copy assignment operator of a class will have, and whether the + /// parameter will be const. + std::pair<ImplicitExceptionSpecification, bool> + ComputeDefaultedCopyAssignmentExceptionSpecAndConst(CXXRecordDecl *ClassDecl); + + /// \brief Determine what sort of exception specification a defaulted + /// destructor of a class will have. + ImplicitExceptionSpecification + ComputeDefaultedDtorExceptionSpec(CXXRecordDecl *ClassDecl); + + /// \brief Determine if a defaulted default constructor ought to be + /// deleted. + bool ShouldDeleteDefaultConstructor(CXXConstructorDecl *CD); + + /// \brief Determine if a defaulted copy constructor ought to be + /// deleted. + bool ShouldDeleteCopyConstructor(CXXConstructorDecl *CD); + + /// \brief Determine if a defaulted copy assignment operator ought to be + /// deleted. + bool ShouldDeleteCopyAssignmentOperator(CXXMethodDecl *MD); + + /// \brief Determine if a defaulted destructor ought to be deleted. + bool ShouldDeleteDestructor(CXXDestructorDecl *DD); + /// \brief Declare the implicit default constructor for the given class. /// /// \param ClassDecl The class declaration into which the implicit @@ -2529,6 +2733,13 @@ public: void DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor); + /// \brief Build an exception spec for destructors that don't have one. + /// + /// C++11 says that user-defined destructors with no exception spec get one + /// that looks as if the destructor was implicitly declared. + void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, + CXXDestructorDecl *Destructor); + /// \brief Declare all inherited constructors for the given class. /// /// \param ClassDecl The class declaration into which the inherited @@ -2549,8 +2760,7 @@ public: /// DefineImplicitCopyConstructor - Checks for feasibility of /// defining this constructor as the copy constructor. void DefineImplicitCopyConstructor(SourceLocation CurrentLocation, - CXXConstructorDecl *Constructor, - unsigned TypeQuals); + CXXConstructorDecl *Constructor); /// \brief Declare the implicit copy assignment operator for the given class. /// @@ -2587,6 +2797,10 @@ public: ParsedType ObjectType, bool EnteringContext); + // Checks that reinterpret casts don't have undefined behavior. + void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, + bool IsDereference, SourceRange Range); + /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, @@ -2638,10 +2852,9 @@ public: //// ActOnCXXThis - Parse 'this' pointer. ExprResult ActOnCXXThis(SourceLocation loc); - /// tryCaptureCXXThis - Try to capture a 'this' pointer. Returns a - /// pointer to an instance method whose 'this' pointer is - /// capturable, or null if this is not possible. - CXXMethodDecl *tryCaptureCXXThis(); + /// getAndCaptureCurrentThisType - Try to capture a 'this' pointer. Returns + /// the type of the 'this' pointer, or a null type if this is not possible. + QualType getAndCaptureCurrentThisType(); /// ActOnCXXBoolLiteral - Parse {true,false} literals. ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); @@ -2699,14 +2912,16 @@ public: bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, DeclarationName Name, Expr** Args, unsigned NumArgs, DeclContext *Ctx, - bool AllowMissing, FunctionDecl *&Operator); + bool AllowMissing, FunctionDecl *&Operator, + bool Diagnose = true); void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, QualType Argument, bool addMallocAttr = false); bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, - DeclarationName Name, FunctionDecl* &Operator); + DeclarationName Name, FunctionDecl* &Operator, + bool Diagnose = true); /// ActOnCXXDelete - Parsed a C++ 'delete' expression ExprResult ActOnCXXDelete(SourceLocation StartLoc, @@ -2985,7 +3200,7 @@ public: Expr **Strings, unsigned NumStrings); - Expr *BuildObjCEncodeExpression(SourceLocation AtLoc, + ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc); ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, @@ -3038,8 +3253,10 @@ public: Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, - Expr *Init, bool IsDefinition, - bool Deleted = false); + Expr *Init, bool HasDeferredInit, + bool IsDefinition); + void ActOnCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, + Expr *Init); MemInitResult ActOnMemInitializer(Decl *ConstructorD, Scope *S, @@ -3143,8 +3360,9 @@ public: void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); - void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record); + void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method); + void ActOnFinishDelayedMemberInitializers(Decl *Record); void MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag = true); bool IsInsideALocalClassWithinATemplateFunction(); @@ -3170,6 +3388,12 @@ public: StorageClass& SC); Decl *ActOnConversionDeclarator(CXXConversionDecl *Conversion); + void CheckExplicitlyDefaultedMethods(CXXRecordDecl *Record); + void CheckExplicitlyDefaultedDefaultConstructor(CXXConstructorDecl *Ctor); + void CheckExplicitlyDefaultedCopyConstructor(CXXConstructorDecl *Ctor); + void CheckExplicitlyDefaultedCopyAssignment(CXXMethodDecl *Method); + void CheckExplicitlyDefaultedDestructor(CXXDestructorDecl *Dtor); + //===--------------------------------------------------------------------===// // C++ Derived Classes // @@ -3257,12 +3481,17 @@ public: AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, - DeclAccessPair FoundDecl); + DeclAccessPair FoundDecl, + bool Diagnose = true); AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, const InitializedEntity &Entity, AccessSpecifier Access, bool IsCopyBindingRefToTemp = false); + AccessResult CheckConstructorAccess(SourceLocation Loc, + CXXConstructorDecl *D, + AccessSpecifier Access, + PartialDiagnostic PD); AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag); @@ -3394,7 +3623,8 @@ public: TPC_FunctionTemplate, TPC_ClassTemplateMember, TPC_FriendFunctionTemplate, - TPC_FriendFunctionTemplateDefinition + TPC_FriendFunctionTemplateDefinition, + TPC_TypeAliasTemplate }; bool CheckTemplateParameterList(TemplateParameterList *NewParams, @@ -3402,6 +3632,7 @@ public: TemplateParamListContext TPC); TemplateParameterList * MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, + SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateParameterList **ParamLists, unsigned NumParamLists, @@ -4507,7 +4738,7 @@ public: /// types, static variables, enumerators, etc. std::deque<PendingImplicitInstantiation> PendingLocalImplicitInstantiations; - bool PerformPendingInstantiations(bool LocalOnly = false); + void PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, const MultiLevelTemplateArgumentList &TemplateArgs, @@ -4644,7 +4875,7 @@ public: IdentifierInfo *AliasName, SourceLocation AliasLocation, IdentifierInfo *ClassName, SourceLocation ClassLocation); - void CheckForwardProtocolDeclarationForCircularDependency( + bool CheckForwardProtocolDeclarationForCircularDependency( IdentifierInfo *PName, SourceLocation &PLoc, SourceLocation PrevLoc, const ObjCList<ObjCProtocolDecl> &PList); @@ -4769,7 +5000,7 @@ public: SourceLocation EndLoc, // location of the ; or {. tok::TokenKind MethodType, Decl *ClassDecl, ObjCDeclSpec &ReturnQT, ParsedType ReturnType, - Selector Sel, + SourceLocation SelectorStartLoc, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). ObjCArgInfo *ArgInfo, @@ -4867,7 +5098,18 @@ public: SourceLocation RBracLoc, MultiExprArg Args); - + /// \brief Check whether the given new method is a valid override of the + /// given overridden method, and set any properties that should be inherited. + /// + /// \returns True if an error occurred. + bool CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, + const ObjCMethodDecl *Overridden, + bool IsImplementation); + + /// \brief Check whether the given method overrides any methods in its class, + /// calling \c CheckObjCMethodOverride for each overridden method. + bool CheckObjCMethodOverrides(ObjCMethodDecl *NewMethod, DeclContext *DC); + enum PragmaOptionsAlignKind { POAK_Native, // #pragma options align=native POAK_Natural, // #pragma options align=natural @@ -5289,11 +5531,24 @@ public: /// \param Method - May be null. /// \param [out] ReturnType - The return type of the send. /// \return true iff there were any incompatible types. - bool CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel, + bool CheckMessageArgumentTypes(QualType ReceiverType, + Expr **Args, unsigned NumArgs, Selector Sel, ObjCMethodDecl *Method, bool isClassMessage, + bool isSuperMessage, SourceLocation lbrac, SourceLocation rbrac, QualType &ReturnType, ExprValueKind &VK); + /// \brief Determine the result of a message send expression based on + /// the type of the receiver, the method expected to receive the message, + /// and the form of the message send. + QualType getMessageSendResultType(QualType ReceiverType, + ObjCMethodDecl *Method, + bool isClassMessage, bool isSuperMessage); + + /// \brief If the given expression involves a message send to a method + /// with a related result type, emit a note describing what happened. + void EmitRelatedResultTypeNote(const Expr *E); + /// CheckBooleanCondition - Diagnose problems involving the use of /// the given expression as a boolean condition (e.g. in an if /// statement). Also performs the standard function and array @@ -5547,7 +5802,8 @@ private: unsigned format_idx, unsigned firstDataArg, bool isPrintf); - void CheckMemsetArguments(const CallExpr *Call); + void CheckMemsetcpymoveArguments(const CallExpr *Call, + const IdentifierInfo *FnName); void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType, SourceLocation ReturnLoc); diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 4d97f9b..a257772 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -335,9 +335,9 @@ namespace clang { Decl *VisitLabelDecl(LabelDecl *D); Decl *VisitNamespaceDecl(NamespaceDecl *D); Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D); - Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); Decl *VisitTypedefDecl(TypedefDecl *D); Decl *VisitTypeAliasDecl(TypeAliasDecl *D); + Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); Decl *VisitVarDecl(VarDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitFieldDecl(FieldDecl *D); @@ -415,6 +415,7 @@ namespace clang { bool SubstQualifier(const TagDecl *OldDecl, TagDecl *NewDecl); + Decl *InstantiateTypedefNameDecl(TypedefNameDecl *D, bool IsTypeAlias); ClassTemplatePartialSpecializationDecl * InstantiateClassTemplatePartialSpecialization( ClassTemplateDecl *ClassTemplate, diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 1cfd458..c881b23 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -279,7 +279,9 @@ namespace clang { /// generate the AST file. ORIGINAL_FILE_NAME = 19, - /// Record #20 intentionally left blank. + /// \brief Record code for the file ID of the original file used to + /// generate the AST file. + ORIGINAL_FILE_ID = 20, /// \brief Record code for the version control branch and revision /// information of the compiler used to build this AST file. @@ -362,7 +364,15 @@ namespace clang { FP_PRAGMA_OPTIONS = 42, /// \brief Record code for enabled OpenCL extensions. - OPENCL_EXTENSIONS = 43 + OPENCL_EXTENSIONS = 43, + + /// \brief The list of delegating constructor declarations. + DELEGATING_CTORS = 44, + + /// \brief Record code for the table of offsets into the block + /// of file source-location information. + FILE_SOURCE_LOCATION_OFFSETS = 45 + }; /// \brief Record types used within a source manager block. @@ -504,6 +514,9 @@ namespace clang { /// NUM_PREDEF_TYPE_IDs. const unsigned NUM_PREDEF_TYPE_IDS = 100; + /// \brief The number of allowed abbreviations in bits + const unsigned NUM_ALLOWED_ABBREVS_SIZE = 4; + /// \brief Record codes for each kind of type. /// /// These constants describe the type records that can occur within a @@ -584,7 +597,9 @@ namespace clang { /// \brief A SubstTemplateTypeParmPackType record. TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37, /// \brief A AutoType record. - TYPE_AUTO = 38 + TYPE_AUTO = 38, + /// \brief A UnaryTransformType record. + TYPE_UNARY_TRANSFORM = 39 }; /// \brief The type IDs for special types constructed by semantic @@ -758,6 +773,8 @@ namespace clang { DECL_NON_TYPE_TEMPLATE_PARM, /// \brief A TemplateTemplateParmDecl record. DECL_TEMPLATE_TEMPLATE_PARM, + /// \brief A TypeAliasTemplateDecl record. + DECL_TYPE_ALIAS_TEMPLATE, /// \brief A StaticAssertDecl record. DECL_STATIC_ASSERT, /// \brief A record containing CXXBaseSpecifiers. @@ -986,7 +1003,10 @@ namespace clang { // CUDA - EXPR_CUDA_KERNEL_CALL // CUDAKernelCallExpr + EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr + + // OpenCL + EXPR_ASTYPE // An AsTypeExpr record. }; /// \brief The kinds of designators that can occur in a @@ -1003,6 +1023,15 @@ namespace clang { DESIG_ARRAY_RANGE = 3 }; + /// \brief The different kinds of data that can occur in a + /// CtorInitializer. + enum CtorInitializerType { + CTOR_INITIALIZER_BASE, + CTOR_INITIALIZER_DELEGATING, + CTOR_INITIALIZER_MEMBER, + CTOR_INITIALIZER_INDIRECT_MEMBER + }; + /// @} } } // end namespace clang diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index da018ab..8923e2a 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -54,6 +54,7 @@ class Decl; class DeclContext; class NestedNameSpecifier; class CXXBaseSpecifier; +class CXXConstructorDecl; class CXXCtorInitializer; class GotoStmt; class MacroDefinition; @@ -256,6 +257,13 @@ private: /// AST file. const uint32_t *SLocOffsets; + /// \brief The number of source location file entries in this AST file. + unsigned LocalNumSLocFileEntries; + + /// \brief Offsets for all of the source location file entries in the + /// AST file. + const uint32_t *SLocFileOffsets; + /// \brief The entire size of this module's source location offset range. unsigned LocalSLocSize; @@ -564,6 +572,10 @@ private: /// generating warnings. llvm::SmallVector<uint64_t, 16> UnusedFileScopedDecls; + /// \brief A list of all the delegating constructors we've seen, to diagnose + /// cycles. + llvm::SmallVector<uint64_t, 4> DelegatingCtorDecls; + /// \brief A snapshot of Sema's weak undeclared identifier tracking, for /// generating warnings. llvm::SmallVector<uint64_t, 64> WeakUndeclaredIdentifiers; @@ -626,6 +638,10 @@ private: /// AST file. std::string ActualOriginalFileName; + /// \brief The file ID for the original file that was used to build the + /// primary AST file. + FileID OriginalFileID; + /// \brief The directory that the PCH was originally created in. Used to /// allow resolving headers even after headers+PCH was moved to a new path. std::string OriginalDir; @@ -780,6 +796,10 @@ private: /// \brief Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(PerFileData &F); + /// \brief Get a FileEntry out of stored-in-PCH filename, making sure we take + /// into account all the necessary relocations. + const FileEntry *getFileEntry(llvm::StringRef filename); + void MaybeAddSystemRootToFilename(std::string &Filename); ASTReadResult ReadASTCore(llvm::StringRef FileName, ASTFileType Type); @@ -879,6 +899,10 @@ public: /// name. ASTReadResult ReadAST(const std::string &FileName, ASTFileType Type); + /// \brief Checks that no file that is stored in PCH is out-of-sync with + /// the actual file in the file system. + ASTReadResult validateFileEntries(); + /// \brief Set the AST callbacks listener. void setListener(ASTReaderListener *listener) { Listener.reset(listener); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 1a79b31..78a63ab 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -338,10 +338,20 @@ private: void WriteFPPragmaOptions(const FPOptions &Opts); void WriteOpenCLExtensions(Sema &SemaRef); - unsigned ParmVarDeclAbbrev; + unsigned DeclParmVarAbbrev; unsigned DeclContextLexicalAbbrev; unsigned DeclContextVisibleLookupAbbrev; unsigned UpdateVisibleAbbrev; + unsigned DeclRefExprAbbrev; + unsigned CharacterLiteralAbbrev; + unsigned DeclRecordAbbrev; + unsigned IntegerLiteralAbbrev; + unsigned DeclTypedefAbbrev; + unsigned DeclVarAbbrev; + unsigned DeclFieldAbbrev; + unsigned DeclEnumAbbrev; + unsigned DeclObjCIvarAbbrev; + void WriteDeclsBlockAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); @@ -568,7 +578,16 @@ public: /// \brief Retrieve the ID for the given opaque value expression. unsigned getOpaqueValueID(OpaqueValueExpr *e); - unsigned getParmVarDeclAbbrev() const { return ParmVarDeclAbbrev; } + unsigned getDeclParmVarAbbrev() const { return DeclParmVarAbbrev; } + unsigned getDeclRefExprAbbrev() const { return DeclRefExprAbbrev; } + unsigned getCharacterLiteralAbbrev() const { return CharacterLiteralAbbrev; } + unsigned getDeclRecordAbbrev() const { return DeclRecordAbbrev; } + unsigned getIntegerLiteralAbbrev() const { return IntegerLiteralAbbrev; } + unsigned getDeclTypedefAbbrev() const { return DeclTypedefAbbrev; } + unsigned getDeclVarAbbrev() const { return DeclVarAbbrev; } + unsigned getDeclFieldAbbrev() const { return DeclFieldAbbrev; } + unsigned getDeclEnumAbbrev() const { return DeclEnumAbbrev; } + unsigned getDeclObjCIvarAbbrev() const { return DeclObjCIvarAbbrev; } bool hasChain() const { return Chain; } diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 8c2ffc6..eb38bd8 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -63,6 +63,24 @@ public: } }; +class EndOfTranslationUnit { + template <typename CHECKER> + static void _checkEndOfTranslationUnit(void *checker, + const TranslationUnitDecl *TU, + AnalysisManager& mgr, + BugReporter &BR) { + ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR); + } + +public: + template <typename CHECKER> + static void _register(CHECKER *checker, CheckerManager &mgr){ + mgr._registerForEndOfTranslationUnit( + CheckerManager::CheckEndOfTranslationUnit(checker, + _checkEndOfTranslationUnit<CHECKER>)); + } +}; + template <typename STMT> class PreStmt { template <typename CHECKER> @@ -240,9 +258,11 @@ public: class RegionChanges { template <typename CHECKER> static const GRState *_checkRegionChanges(void *checker, const GRState *state, + const StoreManager::InvalidatedSymbols *invalidated, const MemRegion * const *Begin, const MemRegion * const *End) { - return ((const CHECKER *)checker)->checkRegionChanges(state, Begin, End); + return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated, + Begin, End); } template <typename CHECKER> static bool _wantsRegionChangeUpdate(void *checker, const GRState *state) { diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 92ec038..45d38fb 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include <vector> namespace clang { @@ -49,6 +50,18 @@ public: template <typename T> class CheckerFn; +template <typename RET, typename P1, typename P2, typename P3, typename P4> +class CheckerFn<RET(P1, P2, P3, P4)> { + typedef RET (*Func)(void *, P1, P2, P3, P4); + Func Fn; +public: + void *Checker; + CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } + RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { + return Fn(Checker, p1, p2, p3, p4); + } +}; + template <typename RET, typename P1, typename P2, typename P3> class CheckerFn<RET(P1, P2, P3)> { typedef RET (*Func)(void *, P1, P2, P3); @@ -224,9 +237,11 @@ public: bool wantsRegionChangeUpdate(const GRState *state); /// \brief Run checkers for region changes. - const GRState *runCheckersForRegionChanges(const GRState *state, - const MemRegion * const *Begin, - const MemRegion * const *End); + const GRState * + runCheckersForRegionChanges(const GRState *state, + const StoreManager::InvalidatedSymbols *invalidated, + const MemRegion * const *Begin, + const MemRegion * const *End); /// \brief Run checkers for handling assumptions on symbolic values. const GRState *runCheckersForEvalAssume(const GRState *state, @@ -237,6 +252,11 @@ public: const ExplodedNodeSet &Src, const CallExpr *CE, ExprEngine &Eng, GraphExpander *defaultEval = 0); + + /// \brief Run checkers for the entire Translation Unit. + void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl* TU, + AnalysisManager &mgr, + BugReporter &BR); //===----------------------------------------------------------------------===// // Internal registration functions for AST traversing. @@ -283,6 +303,7 @@ public: typedef CheckerFn<void (const GRState *,SymbolReaper &)> CheckLiveSymbolsFunc; typedef CheckerFn<const GRState * (const GRState *, + const StoreManager::InvalidatedSymbols *symbols, const MemRegion * const *begin, const MemRegion * const *end)> CheckRegionChangesFunc; @@ -296,6 +317,10 @@ public: typedef CheckerFn<bool (const CallExpr *, CheckerContext &)> EvalCallFunc; + typedef CheckerFn<void (const TranslationUnitDecl *, + AnalysisManager&, BugReporter &)> + CheckEndOfTranslationUnit; + typedef bool (*HandlesStmtFunc)(const Stmt *D); void _registerForPreStmt(CheckStmtFunc checkfn, HandlesStmtFunc isForStmtFn); @@ -326,6 +351,8 @@ public: void _registerForEvalCall(EvalCallFunc checkfn); + void _registerForEndOfTranslationUnit(CheckEndOfTranslationUnit checkfn); + //===----------------------------------------------------------------------===// // Internal registration functions for events. //===----------------------------------------------------------------------===// @@ -446,6 +473,8 @@ private: std::vector<EvalCallFunc> EvalCallCheckers; + std::vector<CheckEndOfTranslationUnit> EndOfTranslationUnitCheckers; + struct EventInfo { llvm::SmallVector<CheckEventFunc, 4> Checkers; bool HasDispatcher; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index 65fbfcc..69495be 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -108,7 +108,8 @@ public: const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { assert(T->isIntegerType() || Loc::isLocType(T)); unsigned bitwidth = Ctx.getTypeSize(T); - bool isUnsigned = T->isUnsignedIntegerType() || Loc::isLocType(T); + bool isUnsigned + = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth()) return From; @@ -131,13 +132,15 @@ public: inline const llvm::APSInt& getMaxValue(QualType T) { assert(T->isIntegerType() || Loc::isLocType(T)); - bool isUnsigned = T->isUnsignedIntegerType() || Loc::isLocType(T); + bool isUnsigned + = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); return getValue(llvm::APSInt::getMaxValue(Ctx.getTypeSize(T), isUnsigned)); } inline const llvm::APSInt& getMinValue(QualType T) { assert(T->isIntegerType() || Loc::isLocType(T)); - bool isUnsigned = T->isUnsignedIntegerType() || Loc::isLocType(T); + bool isUnsigned + = T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T); return getValue(llvm::APSInt::getMinValue(Ctx.getTypeSize(T), isUnsigned)); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 8cd743f..d24036c 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -21,6 +21,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/TransferFuncs.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/AST/Type.h" #include "clang/AST/ExprObjC.h" @@ -188,9 +189,11 @@ public: /// processRegionChanges - Called by GRStateManager whenever a change is made /// to the store. Used to update checkers that track region values. - const GRState* processRegionChanges(const GRState *state, - const MemRegion * const *Begin, - const MemRegion * const *End); + const GRState * + processRegionChanges(const GRState *state, + const StoreManager::InvalidatedSymbols *invalidated, + const MemRegion * const *Begin, + const MemRegion * const *End); virtual GRStateManager& getStateManager() { return StateMgr; } @@ -458,6 +461,13 @@ private: const void *tag, bool isLoad); bool InlineCall(ExplodedNodeSet &Dst, const CallExpr *CE, ExplodedNode *Pred); + + +public: + /// Returns true if calling the specific function or method would possibly + /// cause global variables to be invalidated. + bool doesInvalidateGlobals(const CallOrObjCMessage &callOrMessage) const; + }; } // end ento namespace diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h index a957c89..0d61d0e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/GRState.h @@ -368,6 +368,12 @@ private: assert(refCount > 0); --refCount; } + + const GRState *invalidateRegionsImpl(const MemRegion * const *Begin, + const MemRegion * const *End, + const Expr *E, unsigned BlockCount, + StoreManager::InvalidatedSymbols &IS, + bool invalidateGlobals) const; }; class GRStateSet { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h index 6d8fc89..734024c 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h @@ -187,6 +187,7 @@ public: return CallE && isa<CXXMemberCallExpr>(CallE); } + SVal getFunctionCallee() const; SVal getCXXCallee() const; unsigned getNumArgs() const { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 0f9e56a..65eabea 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -172,7 +172,7 @@ public: nonloc::ConcreteInt makeIntVal(const IntegerLiteral* integer) { return nonloc::ConcreteInt( BasicVals.getValue(integer->getValue(), - integer->getType()->isUnsignedIntegerType())); + integer->getType()->isUnsignedIntegerOrEnumerationType())); } nonloc::ConcreteInt makeBoolVal(const CXXBoolLiteralExpr *boolean) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index 21c6ae7..cdbdf64 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -188,7 +188,7 @@ public: const MemRegion * const *Begin, const MemRegion * const *End, const Expr *E, unsigned Count, - InvalidatedSymbols *IS, + InvalidatedSymbols &IS, bool invalidateGlobals, InvalidatedRegions *Regions) = 0; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index 3d6f9fa..1f6ea3d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -15,6 +15,7 @@ #include "clang/Analysis/ProgramPoint.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" namespace clang { @@ -95,13 +96,17 @@ public: /// processRegionChanges - Called by GRStateManager whenever a change is made /// to the store. Used to update checkers that track region values. - virtual const GRState* processRegionChanges(const GRState* state, - const MemRegion* const *Begin, - const MemRegion* const *End) = 0; + virtual const GRState * + processRegionChanges(const GRState *state, + const StoreManager::InvalidatedSymbols *invalidated, + const MemRegion* const *Begin, + const MemRegion* const *End) = 0; - inline const GRState* processRegionChange(const GRState* state, - const MemRegion* MR) { - return processRegionChanges(state, &MR, &MR+1); + + inline const GRState * + processRegionChange(const GRState* state, + const MemRegion* MR) { + return processRegionChanges(state, 0, &MR, &MR+1); } /// Called by CoreEngine when the analysis worklist is either empty or the diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h deleted file mode 100644 index 6ccccd0..0000000 --- a/include/clang/Tooling/Tooling.h +++ /dev/null @@ -1,81 +0,0 @@ -//===--- Tooling.h - Framework for standalone Clang tools -------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements functions to run clang tools standalone instead -// of running them as a plugin. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLING_TOOLING_H -#define LLVM_CLANG_TOOLING_TOOLING_H - -#include "llvm/ADT/StringRef.h" -#include <string> -#include <vector> - -namespace clang { - -class FrontendAction; - -namespace tooling { - -/// \brief Runs (and deletes) the tool on 'Code' with the -fsynatx-only flag. -/// -/// \param ToolAction The action to run over the code. -/// \param Code C++ code. -/// -/// \return - True if 'ToolAction' was successfully executed. -bool RunSyntaxOnlyToolOnCode( - clang::FrontendAction *ToolAction, llvm::StringRef Code); - -/// \brief Runs (and deletes) the tool with the given Clang flags. -/// -/// \param ToolAction The action to run over the code. -/// \param Argc The number of elements in Argv. -/// \param Argv The command line arguments, including the path the binary -/// was started with (Argv[0]). -bool RunToolWithFlags( - clang::FrontendAction* ToolAction, int Argc, char *Argv[]); - -/// \brief Converts a vector<string> into a vector<char*> suitable to pass -/// to main-style functions taking (int Argc, char *Argv[]). -std::vector<char*> CommandLineToArgv(const std::vector<std::string>* Command); - -/// \brief Specifies the working directory and command of a compilation. -struct CompileCommand { - /// \brief The working directory the command was executed from. - std::string Directory; - - /// \brief The command line that was executed. - std::vector<std::string> CommandLine; -}; - -/// \brief Looks up the compile command for 'FileName' in 'JsonDatabase'. -/// -/// \param FileName The path to an input file for which we want the compile -/// command line. If the 'JsonDatabase' was created by CMake, this must be -/// an absolute path inside the CMake source directory which does not have -/// symlinks resolved. -/// -/// \param JsonDatabase A JSON formatted list of compile commands. This lookup -/// command supports only a subset of the JSON standard as written by CMake. -/// -/// \param ErrorMessage If non-empty, an error occurred and 'ErrorMessage' will -/// be set to contain the error message. In this case CompileCommand will -/// contain an empty directory and command line. -/// -/// \see JsonCompileCommandLineDatabase -CompileCommand FindCompileArgsInJsonDatabase( - llvm::StringRef FileName, llvm::StringRef JsonDatabase, - std::string &ErrorMessage); - -} // end namespace tooling -} // end namespace clang - -#endif // LLVM_CLANG_TOOLING_TOOLING_H |