diff options
Diffstat (limited to 'include')
99 files changed, 2282 insertions, 526 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 787c44a..d8c37eb 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 15 +#define CINDEX_VERSION_MINOR 19 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -409,6 +409,11 @@ CINDEX_LINKAGE CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu, unsigned offset); /** + * \brief Returns non-zero if the given source location is in a system header. + */ +CINDEX_LINKAGE int clang_Location_isInSystemHeader(CXSourceLocation location); + +/** * \brief Retrieve a NULL (invalid) source range. */ CINDEX_LINKAGE CXSourceRange clang_getNullRange(void); @@ -1898,7 +1903,11 @@ enum CXCursorKind { */ CXCursor_ObjCBoolLiteralExpr = 145, - CXCursor_LastExpr = CXCursor_ObjCBoolLiteralExpr, + /** \brief Represents the "self" expression in a ObjC method. + */ + CXCursor_ObjCSelfExpr = 146, + + CXCursor_LastExpr = CXCursor_ObjCSelfExpr, /* Statements */ CXCursor_FirstStmt = 200, @@ -2901,6 +2910,83 @@ CINDEX_LINKAGE CXType clang_getArrayElementType(CXType T); CINDEX_LINKAGE long long clang_getArraySize(CXType T); /** + * \brief List the possible error codes for \c clang_Type_getSizeOf, + * \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and + * \c clang_Cursor_getOffsetOf. + * + * A value of this enumeration type can be returned if the target type is not + * a valid argument to sizeof, alignof or offsetof. + */ +enum CXTypeLayoutError { + /** + * \brief Type is of kind CXType_Invalid. + */ + CXTypeLayoutError_Invalid = -1, + /** + * \brief The type is an incomplete Type. + */ + CXTypeLayoutError_Incomplete = -2, + /** + * \brief The type is a dependent Type. + */ + CXTypeLayoutError_Dependent = -3, + /** + * \brief The type is not a constant size type. + */ + CXTypeLayoutError_NotConstantSize = -4, + /** + * \brief The Field name is not valid for this record. + */ + CXTypeLayoutError_InvalidFieldName = -5 +}; + +/** + * \brief Return the alignment of a type in bytes as per C++[expr.alignof] + * standard. + * + * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned. + * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete + * is returned. + * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is + * returned. + * If the type declaration is not a constant size type, + * CXTypeLayoutError_NotConstantSize is returned. + */ +CINDEX_LINKAGE long long clang_Type_getAlignOf(CXType T); + +/** + * \brief Return the size of a type in bytes as per C++[expr.sizeof] standard. + * + * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned. + * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete + * is returned. + * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is + * returned. + */ +CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T); + +/** + * \brief Return the offset of a field named S in a record of type T in bits + * as it would be returned by __offsetof__ as per C++11[18.2p4] + * + * If the cursor is not a record field declaration, CXTypeLayoutError_Invalid + * is returned. + * If the field's type declaration is an incomplete type, + * CXTypeLayoutError_Incomplete is returned. + * If the field's type declaration is a dependent type, + * CXTypeLayoutError_Dependent is returned. + * If the field's name S is not found, + * CXTypeLayoutError_InvalidFieldName is returned. + */ +CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S); + +/** + * \brief Returns non-zero if the cursor specifies a Record member that is a + * bitfield. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isBitField(CXCursor C); + +/** * \brief Returns 1 if the base class specified by the cursor with kind * CX_CXXBaseSpecifier is virtual. */ @@ -2918,9 +3004,11 @@ enum CX_CXXAccessSpecifier { }; /** - * \brief Returns the access control level for the C++ base specifier - * represented by a cursor with kind CXCursor_CXXBaseSpecifier or - * CXCursor_AccessSpecifier. + * \brief Returns the access control level for the referenced object. + * + * If the cursor refers to a C++ declaration, its access control level within its + * parent scope is returned. Otherwise, if the cursor refers to a base specifier or + * access specifier, the specifier itself is returned. */ CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor); @@ -3276,6 +3364,61 @@ CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C); CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C); /** + * \brief Property attributes for a \c CXCursor_ObjCPropertyDecl. + */ +typedef enum { + CXObjCPropertyAttr_noattr = 0x00, + CXObjCPropertyAttr_readonly = 0x01, + CXObjCPropertyAttr_getter = 0x02, + CXObjCPropertyAttr_assign = 0x04, + CXObjCPropertyAttr_readwrite = 0x08, + CXObjCPropertyAttr_retain = 0x10, + CXObjCPropertyAttr_copy = 0x20, + CXObjCPropertyAttr_nonatomic = 0x40, + CXObjCPropertyAttr_setter = 0x80, + CXObjCPropertyAttr_atomic = 0x100, + CXObjCPropertyAttr_weak = 0x200, + CXObjCPropertyAttr_strong = 0x400, + CXObjCPropertyAttr_unsafe_unretained = 0x800 +} CXObjCPropertyAttrKind; + +/** + * \brief Given a cursor that represents a property declaration, return the + * associated property attributes. The bits are formed from + * \c CXObjCPropertyAttrKind. + * + * \param reserved Reserved for future use, pass 0. + */ +CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, + unsigned reserved); + +/** + * \brief 'Qualifiers' written next to the return and parameter types in + * ObjC method declarations. + */ +typedef enum { + CXObjCDeclQualifier_None = 0x0, + CXObjCDeclQualifier_In = 0x1, + CXObjCDeclQualifier_Inout = 0x2, + CXObjCDeclQualifier_Out = 0x4, + CXObjCDeclQualifier_Bycopy = 0x8, + CXObjCDeclQualifier_Byref = 0x10, + CXObjCDeclQualifier_Oneway = 0x20 +} CXObjCDeclQualifierKind; + +/** + * \brief Given a cursor that represents an ObjC method or parameter + * declaration, return the associated ObjC qualifiers for the return type or the + * parameter respectively. The bits are formed from CXObjCDeclQualifierKind. + */ +CINDEX_LINKAGE unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C); + +/** + * \brief Returns non-zero if the given cursor is a variadic function or method. + */ +CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C); + +/** * \brief Given a cursor that represents a declaration, return the associated * comment's source range. The range may include multiple consecutive comments * with whitespace in between. @@ -3324,6 +3467,13 @@ CINDEX_LINKAGE CXModule clang_Cursor_getModule(CXCursor C); /** * \param Module a module object. * + * \returns the module file where the provided module object came from. + */ +CINDEX_LINKAGE CXFile clang_Module_getASTFile(CXModule Module); + +/** + * \param Module a module object. + * * \returns the parent of a sub-module or NULL if the given module is top-level, * e.g. for 'std.vector' it will return the 'std' module. */ diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index d4878a9..c5d3337 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -867,6 +867,9 @@ public: const FunctionType *adjustFunctionType(const FunctionType *Fn, FunctionType::ExtInfo EInfo); + /// \brief Change the result type of a function type once it is deduced. + void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType); + /// \brief Return the uniqued reference to the type for a complex /// number with the specified element type. QualType getComplexType(QualType T) const; @@ -1100,7 +1103,8 @@ public: UnaryTransformType::UTTKind UKind) const; /// \brief C++11 deduced auto type. - QualType getAutoType(QualType DeducedType) const; + QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto, + bool IsDependent = false) const; /// \brief C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; @@ -1451,7 +1455,18 @@ public: qs.addObjCLifetime(lifetime); return getQualifiedType(type, qs); } - + + /// getUnqualifiedObjCPointerType - Returns version of + /// Objective-C pointer type with lifetime qualifier removed. + QualType getUnqualifiedObjCPointerType(QualType type) const { + if (!type.getTypePtr()->isObjCObjectPointerType() || + !type.getQualifiers().hasObjCLifetime()) + return type; + Qualifiers Qs = type.getQualifiers(); + Qs.removeObjCLifetime(); + return getQualifiedType(type.getUnqualifiedType(), Qs); + } + DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; @@ -1578,6 +1593,14 @@ public: /// beneficial for performance to overalign a data type. unsigned getPreferredTypeAlign(const Type *T) const; + /// \brief Return the alignment in bits that should be given to a + /// global variable with type \p T. + unsigned getAlignOfGlobalVar(QualType T) const; + + /// \brief Return the alignment in characters that should be given to a + /// global variable with type \p T. + CharUnits getAlignOfGlobalVarInChars(QualType T) const; + /// \brief Return a conservative estimate of the alignment of the specified /// decl \p D. /// diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h index c709895..5a56b4d 100644 --- a/include/clang/AST/ASTUnresolvedSet.h +++ b/include/clang/AST/ASTUnresolvedSet.h @@ -41,10 +41,6 @@ public: const_iterator begin() const { return const_iterator(Decls.begin()); } const_iterator end() const { return const_iterator(Decls.end()); } - void addDecl(ASTContext &C, NamedDecl *D) { - addDecl(C, D, AS_none); - } - void addDecl(ASTContext &C, NamedDecl *D, AccessSpecifier AS) { Decls.push_back(DeclAccessPair::make(D, AS), C); } @@ -52,10 +48,13 @@ public: /// Replaces the given declaration with the new one, once. /// /// \return true if the set changed - bool replace(const NamedDecl* Old, NamedDecl *New) { - for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) - if (I->getDecl() == Old) - return (I->setDecl(New), true); + bool replace(const NamedDecl* Old, NamedDecl *New, AccessSpecifier AS) { + for (DeclsTy::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) { + if (I->getDecl() == Old) { + I->set(New, AS); + return true; + } + } return false; } diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td index 9587ace..8c88494 100644 --- a/include/clang/AST/CommentCommands.td +++ b/include/clang/AST/CommentCommands.td @@ -67,14 +67,12 @@ class DeclarationVerbatimLineCommand<string name> : } class FunctionDeclarationVerbatimLineCommand<string name> : - VerbatimLineCommand<name> { - let IsDeclarationCommand = 1; + DeclarationVerbatimLineCommand<name> { let IsFunctionDeclarationCommand = 1; } class RecordLikeDeclarationVerbatimLineCommand<string name> : - VerbatimLineCommand<name> { - let IsDeclarationCommand = 1; + DeclarationVerbatimLineCommand<name> { let IsRecordLikeDeclarationCommand = 1; } @@ -121,6 +119,7 @@ def Headerfile : BlockCommand<"headerfile"> { let IsHeaderfileCommand = 1; } // We don't do any additional semantic analysis for the following // BlockCommands. It might be a good idea to do something extra for them, but // for now we model them as plain BlockCommands. +def Arg : BlockCommand<"arg">; def Attention : BlockCommand<"attention">; def Author : BlockCommand<"author">; def Authors : BlockCommand<"authors">; @@ -128,7 +127,9 @@ def Bug : BlockCommand<"bug">; def Copyright : BlockCommand<"copyright">; def Date : BlockCommand<"date">; def Invariant : BlockCommand<"invariant">; +def Li : BlockCommand<"li">; def Note : BlockCommand<"note">; +def Par : BlockCommand<"par">; def Post : BlockCommand<"post">; def Pre : BlockCommand<"pre">; def Remark : BlockCommand<"remark">; @@ -140,9 +141,11 @@ def Todo : BlockCommand<"todo">; def Version : BlockCommand<"version">; def Warning : BlockCommand<"warning">; // HeaderDoc commands +def Abstract : BlockCommand<"abstract">; def ClassDesign : RecordLikeDetailCommand<"classdesign">; def CoClass : RecordLikeDetailCommand<"coclass">; def Dependency : RecordLikeDetailCommand<"dependency">; +def Discussion : BlockCommand<"discussion">; def Helper : RecordLikeDetailCommand<"helper">; def HelperClass : RecordLikeDetailCommand<"helperclass">; def Helps : RecordLikeDetailCommand<"helps">; @@ -150,6 +153,7 @@ def InstanceSize : RecordLikeDetailCommand<"instancesize">; def Ownership : RecordLikeDetailCommand<"ownership">; def Performance : RecordLikeDetailCommand<"performance">; def Security : RecordLikeDetailCommand<"security">; +def SeeAlso : BlockCommand<"seealso">; def SuperClass : RecordLikeDetailCommand<"superclass">; //===----------------------------------------------------------------------===// @@ -173,6 +177,10 @@ def FDollar : VerbatimBlockCommand<"f$">; // Inline LaTeX formula defm FBracket : VerbatimBlockCommand<"f[", "f]">; // Displayed LaTeX formula defm FBrace : VerbatimBlockCommand<"f{", "f}">; // LaTeX environment +// HeaderDoc commands +defm Textblock : VerbatimBlockCommand<"textblock", "/textblock">; +defm Link : VerbatimBlockCommand<"link", "/link">; + //===----------------------------------------------------------------------===// // VerbatimLineCommand //===----------------------------------------------------------------------===// diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index 4179f45..f152c77 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_COMMENT_LEXER_H #include "clang/Basic/SourceManager.h" +#include "clang/Basic/Diagnostic.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -227,6 +228,8 @@ private: /// computed (for example, resolved decimal character references). llvm::BumpPtrAllocator &Allocator; + DiagnosticsEngine &Diags; + const CommandTraits &Traits; const char *const BufferStart; @@ -316,6 +319,10 @@ private: return FileLoc.getLocWithOffset(CharNo); } + DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) { + return Diags.Report(Loc, DiagID); + } + /// Eat string matching regexp \code \s*\* \endcode. void skipLineStartingDecorations(); @@ -346,7 +353,8 @@ private: void lexHTMLEndTag(Token &T); public: - Lexer(llvm::BumpPtrAllocator &Allocator, const CommandTraits &Traits, + Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags, + const CommandTraits &Traits, SourceLocation FileLoc, const char *BufferStart, const char *BufferEnd); diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 7927279..a0c76c0 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -219,10 +219,6 @@ public: return getLinkage() == ExternalLinkage; } - /// \brief True if this decl has external linkage. Don't cache the linkage, - /// because we are not finished setting up the redecl chain for the decl. - bool hasExternalLinkageUncached() const; - /// \brief Determines the visibility of this entity. Visibility getVisibility() const { return getLinkageAndVisibility().getVisibility(); @@ -641,6 +637,13 @@ public: ListInit ///< Direct list-initialization (C++11) }; + /// \brief Kinds of thread-local storage. + enum TLSKind { + TLS_None, ///< Not a TLS variable. + TLS_Static, ///< TLS with a known-constant initializer. + TLS_Dynamic ///< TLS with a dynamic initializer. + }; + protected: /// \brief Placeholder type used in Init to denote an unparsed C++ default /// argument. @@ -664,7 +667,7 @@ private: friend class ASTDeclReader; unsigned SClass : 3; - unsigned ThreadSpecified : 1; + unsigned TSCSpec : 2; unsigned InitStyle : 2; /// \brief Whether this variable is the exception variable in a C++ catch @@ -687,7 +690,7 @@ private: /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; }; - enum { NumVarDeclBits = 14 }; + enum { NumVarDeclBits = 12 }; friend class ASTDeclReader; friend class StmtIteratorBase; @@ -771,9 +774,23 @@ public: } void setStorageClass(StorageClass SC); - void setThreadSpecified(bool T) { VarDeclBits.ThreadSpecified = T; } - bool isThreadSpecified() const { - return VarDeclBits.ThreadSpecified; + void setTSCSpec(ThreadStorageClassSpecifier TSC) { + VarDeclBits.TSCSpec = TSC; + } + ThreadStorageClassSpecifier getTSCSpec() const { + return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec); + } + TLSKind getTLSKind() const { + switch (VarDeclBits.TSCSpec) { + case TSCS_unspecified: + return TLS_None; + case TSCS___thread: // Fall through. + case TSCS__Thread_local: + return TLS_Static; + case TSCS_thread_local: + return TLS_Dynamic; + } + llvm_unreachable("Unknown thread storage class specifier!"); } /// hasLocalStorage - Returns true if a variable with function scope @@ -813,6 +830,14 @@ public: /// external, C linkage. bool isExternC() const; + /// \brief Determines whether this variable's context is, or is nested within, + /// a C++ extern "C" linkage spec. + bool isInExternCContext() const; + + /// \brief Determines whether this variable's context is, or is nested within, + /// a C++ extern "C++" linkage spec. + bool isInExternCXXContext() const; + /// isLocalVarDecl - Returns true for local variable declarations /// other than parameters. Note that this includes static variables /// inside of functions. It also includes variables inside blocks. @@ -1698,6 +1723,14 @@ public: /// external, C linkage. bool isExternC() const; + /// \brief Determines whether this function's context is, or is nested within, + /// a C++ extern "C" linkage spec. + bool isInExternCContext() const; + + /// \brief Determines whether this function's context is, or is nested within, + /// a C++ extern "C++" linkage spec. + bool isInExternCXXContext() const; + /// \brief Determines whether this is a global function. bool isGlobal() const; @@ -2394,7 +2427,7 @@ protected: bool IsScopedUsingClassTag : 1; /// IsFixed - True if this is an enumeration with fixed underlying type. Only - /// possible in C++11 or Microsoft extensions mode. + /// possible in C++11, Microsoft extensions, or Objective C mode. bool IsFixed : 1; /// \brief Indicates whether it is possible for declarations of this kind @@ -2780,18 +2813,18 @@ public: NumNegativeBits = Num; } - /// \brief Returns true if this is a C++0x scoped enumeration. + /// \brief Returns true if this is a C++11 scoped enumeration. bool isScoped() const { return IsScoped; } - /// \brief Returns true if this is a C++0x scoped enumeration. + /// \brief Returns true if this is a C++11 scoped enumeration. bool isScopedUsingClassTag() const { return IsScopedUsingClassTag; } - /// \brief Returns true if this is a C++0x enumeration with fixed underlying - /// type. + /// \brief Returns true if this is an Objective-C, C++11, or + /// Microsoft-style enumeration with a fixed underlying type. bool isFixed() const { return IsFixed; } @@ -3162,6 +3195,67 @@ public: } }; +/// \brief This represents the body of a CapturedStmt, and serves as its +/// DeclContext. +class CapturedDecl : public Decl, public DeclContext { +private: + /// \brief The number of parameters to the outlined function. + unsigned NumParams; + /// \brief The body of the outlined function. + Stmt *Body; + + explicit CapturedDecl(DeclContext *DC, unsigned NumParams) + : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), + NumParams(NumParams), Body(0) { } + + ImplicitParamDecl **getParams() const { + return reinterpret_cast<ImplicitParamDecl **>( + const_cast<CapturedDecl *>(this) + 1); + } + +public: + static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); + static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned NumParams); + + Stmt *getBody() const { return Body; } + void setBody(Stmt *B) { Body = B; } + + unsigned getNumParams() const { return NumParams; } + + ImplicitParamDecl *getParam(unsigned i) const { + assert(i < NumParams); + return getParams()[i]; + } + void setParam(unsigned i, ImplicitParamDecl *P) { + assert(i < NumParams); + getParams()[i] = P; + } + + /// \brief Retrieve the parameter containing captured variables. + ImplicitParamDecl *getContextParam() const { return getParam(0); } + void setContextParam(ImplicitParamDecl *P) { setParam(0, P); } + + typedef ImplicitParamDecl **param_iterator; + /// \brief Retrieve an iterator pointing to the first parameter decl. + param_iterator param_begin() const { return getParams(); } + /// \brief Retrieve an iterator one past the last parameter decl. + param_iterator param_end() const { return getParams() + NumParams; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Captured; } + static DeclContext *castToDeclContext(const CapturedDecl *D) { + return static_cast<DeclContext *>(const_cast<CapturedDecl *>(D)); + } + static CapturedDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC)); + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + /// \brief Describes a module import declaration, which makes the contents /// of the named module visible in the current translation unit. /// diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 852bb9a..754facf 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -372,10 +372,13 @@ public: return const_cast<Decl*>(this)->getDeclContext(); } - /// Finds the innermost non-closure context of this declaration. - /// That is, walk out the DeclContext chain, skipping any blocks. - DeclContext *getNonClosureContext(); - const DeclContext *getNonClosureContext() const { + /// Find the innermost non-closure ancestor of this declaration, + /// walking up through blocks, lambdas, etc. If that ancestor is + /// not a code context (!isFunctionOrMethod()), returns null. + /// + /// A declaration may be its own non-closure context. + Decl *getNonClosureContext(); + const Decl *getNonClosureContext() const { return const_cast<Decl*>(this)->getNonClosureContext(); } @@ -402,6 +405,12 @@ public: return AccessSpecifier(Access); } + /// \brief Retrieve the access specifier for this declaration, even though + /// it may not yet have been properly set. + AccessSpecifier getAccessUnsafe() const { + return AccessSpecifier(Access); + } + bool hasAttrs() const { return HasAttrs; } void setAttrs(const AttrVec& Attrs) { return setAttrsImpl(Attrs, getASTContext()); @@ -1040,6 +1049,7 @@ public: bool isFunctionOrMethod() const { switch (DeclKind) { case Decl::Block: + case Decl::Captured: case Decl::ObjCMethod: return true; default: @@ -1086,14 +1096,6 @@ public: /// C++0x scoped enums), and C++ linkage specifications. bool isTransparentContext() const; - /// \brief Determines whether this context is, or is nested within, - /// a C++ extern "C" linkage spec. - bool isExternCContext() const; - - /// \brief Determines whether this context is, or is nested within, - /// a C++ extern "C++" linkage spec. - bool isExternCXXContext() const; - /// \brief Determine whether this declaration context is equivalent /// to the declaration context DC. bool Equals(const DeclContext *DC) const { @@ -1107,8 +1109,8 @@ public: /// \brief Find the nearest non-closure ancestor of this context, /// i.e. the innermost semantic parent of this context which is not /// a closure. A context may be its own non-closure ancestor. - DeclContext *getNonClosureAncestor(); - const DeclContext *getNonClosureAncestor() const { + Decl *getNonClosureAncestor(); + const Decl *getNonClosureAncestor() const { return const_cast<DeclContext*>(this)->getNonClosureAncestor(); } @@ -1402,6 +1404,9 @@ public: /// @brief Removes a declaration from this context. void removeDecl(Decl *D); + + /// @brief Checks whether a declaration is in this context. + bool containsDecl(Decl *D) const; /// lookup_iterator - An iterator that provides access to the results /// of looking up a name within this context. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 05ff49c..c483dde 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -254,6 +254,16 @@ public: TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; } }; +/// The inheritance model to use for member pointers of a given CXXRecordDecl. +enum MSInheritanceModel { + MSIM_Single, + MSIM_SinglePolymorphic, + MSIM_Multiple, + MSIM_MultiplePolymorphic, + MSIM_Virtual, + MSIM_Unspecified +}; + /// CXXRecordDecl - Represents a C++ struct/union/class. /// FIXME: This class will disappear once we've properly taught RecordDecl /// to deal with C++-specific things. @@ -1744,8 +1754,6 @@ 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. @@ -1830,7 +1838,7 @@ public: /// implicit ctor initializer generated for a field with an initializer /// defined on the member declaration. bool isInClassMemberInitializer() const { - return !Init; + return isa<CXXDefaultInitExpr>(Init); } /// isDelegatingInitializer - Returns true when this initializer is creating @@ -1957,14 +1965,8 @@ public: getNumArrayIndices()); } - /// \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); - } + /// \brief Get the initializer. + Expr *getInit() const { return static_cast<Expr*>(Init); } }; /// CXXConstructorDecl - Represents a C++ constructor within a @@ -2349,38 +2351,49 @@ public: }; private: /// Language - The language for this linkage specification. - LanguageIDs Language; + unsigned Language : 3; + /// True if this linkage spec has brances. This is needed so that hasBraces() + /// returns the correct result while the linkage spec body is being parsed. + /// Once RBraceLoc has been set this is not used, so it doesn't need to be + /// serialized. + unsigned HasBraces : 1; /// ExternLoc - The source location for the extern keyword. SourceLocation ExternLoc; /// RBraceLoc - The source location for the right brace (if valid). SourceLocation RBraceLoc; LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, - SourceLocation LangLoc, LanguageIDs lang, - SourceLocation RBLoc) + SourceLocation LangLoc, LanguageIDs lang, bool HasBraces) : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), - Language(lang), ExternLoc(ExternLoc), RBraceLoc(RBLoc) { } + Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc), + RBraceLoc(SourceLocation()) { } public: static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExternLoc, SourceLocation LangLoc, LanguageIDs Lang, - SourceLocation RBraceLoc = SourceLocation()); + bool HasBraces); static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); /// \brief Return the language specified by this linkage specification. - LanguageIDs getLanguage() const { return Language; } + LanguageIDs getLanguage() const { return LanguageIDs(Language); } /// \brief Set the language specified by this linkage specification. void setLanguage(LanguageIDs L) { Language = L; } /// \brief Determines whether this linkage specification had braces in /// its syntactic form. - bool hasBraces() const { return RBraceLoc.isValid(); } + bool hasBraces() const { + assert(!RBraceLoc.isValid() || HasBraces); + return HasBraces; + } SourceLocation getExternLoc() const { return ExternLoc; } SourceLocation getRBraceLoc() const { return RBraceLoc; } void setExternLoc(SourceLocation L) { ExternLoc = L; } - void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + void setRBraceLoc(SourceLocation L) { + RBraceLoc = L; + HasBraces = RBraceLoc.isValid(); + } SourceLocation getLocEnd() const LLVM_READONLY { if (hasBraces()) @@ -2974,6 +2987,56 @@ public: friend class ASTDeclReader; }; +/// An instance of this class represents the declaration of a property +/// member. This is a Microsoft extension to C++, first introduced in +/// Visual Studio .NET 2003 as a parallel to similar features in C# +/// and Managed C++. +/// +/// A property must always be a non-static class member. +/// +/// A property member superficially resembles a non-static data +/// member, except preceded by a property attribute: +/// __declspec(property(get=GetX, put=PutX)) int x; +/// Either (but not both) of the 'get' and 'put' names may be omitted. +/// +/// A reference to a property is always an lvalue. If the lvalue +/// undergoes lvalue-to-rvalue conversion, then a getter name is +/// required, and that member is called with no arguments. +/// If the lvalue is assigned into, then a setter name is required, +/// and that member is called with one argument, the value assigned. +/// Both operations are potentially overloaded. Compound assignments +/// are permitted, as are the increment and decrement operators. +/// +/// The getter and putter methods are permitted to be overloaded, +/// although their return and parameter types are subject to certain +/// restrictions according to the type of the property. +/// +/// A property declared using an incomplete array type may +/// additionally be subscripted, adding extra parameters to the getter +/// and putter methods. +class MSPropertyDecl : public DeclaratorDecl { + IdentifierInfo *GetterId, *SetterId; + +public: + MSPropertyDecl(DeclContext *DC, SourceLocation L, + DeclarationName N, QualType T, TypeSourceInfo *TInfo, + SourceLocation StartL, IdentifierInfo *Getter, + IdentifierInfo *Setter): + DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter), + SetterId(Setter) {} + + static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + static bool classof(const Decl *D) { return D->getKind() == MSProperty; } + + bool hasGetter() const { return GetterId != NULL; } + IdentifierInfo* getGetterId() const { return GetterId; } + bool hasSetter() const { return SetterId != NULL; } + IdentifierInfo* getSetterId() const { return SetterId; } + + friend class ASTDeclReader; +}; + /// Insertion operator for diagnostics. This allows sending an AccessSpecifier /// into a diagnostic with <<. const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 253c23c..3a12878 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -101,7 +101,7 @@ public: SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef<TemplateParameterList*> FriendTypeTPLists - = ArrayRef<TemplateParameterList*>()); + = None); static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned FriendTypeNumTPLists); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index c294922..40de013 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1136,7 +1136,8 @@ public: // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, - bool shallowCategoryLookup= false) const; + bool shallowCategoryLookup= false, + const ObjCCategoryDecl *C= 0) const; ObjCMethodDecl *lookupInstanceMethod(Selector Sel, bool shallowCategoryLookup = false) const { return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup); @@ -1155,6 +1156,15 @@ public: return lookupPrivateMethod(Sel, false); } + /// \brief Lookup a setter or getter in the class hierarchy, + /// including in all categories except for category passed + /// as argument. + ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, + const ObjCCategoryDecl *Cat) const { + return lookupMethod(Sel, true/*isInstance*/, + false/*shallowCategoryLookup*/, Cat); + } + SourceLocation getEndOfDefinitionLoc() const { if (!hasDefinition()) return getLocation(); @@ -1788,6 +1798,8 @@ class ObjCImplementationDecl : public ObjCImplDecl { virtual void anchor(); /// Implementation Class's super class. ObjCInterfaceDecl *SuperClass; + SourceLocation SuperLoc; + /// \@implementation may have private ivars. SourceLocation IvarLBraceLoc; SourceLocation IvarRBraceLoc; @@ -1808,10 +1820,11 @@ class ObjCImplementationDecl : public ObjCImplDecl { ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, + SourceLocation superLoc = SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()) : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc), - SuperClass(superDecl), IvarLBraceLoc(IvarLBraceLoc), + SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), IvarInitializers(0), NumIvarInitializers(0), HasNonZeroConstructors(false), HasDestructors(false) {} @@ -1821,6 +1834,7 @@ public: ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, + SourceLocation superLoc = SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); @@ -1893,6 +1907,7 @@ public: const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; } ObjCInterfaceDecl *getSuperClass() { return SuperClass; } + SourceLocation getSuperClassLoc() const { return SuperLoc; } void setSuperClass(ObjCInterfaceDecl * superCls) { SuperClass = superCls; } diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h index eb186c2..2e3cbfa 100644 --- a/include/clang/AST/EvaluatedExprVisitor.h +++ b/include/clang/AST/EvaluatedExprVisitor.h @@ -55,7 +55,7 @@ public: // Only the selected subexpression matters; the other one is not evaluated. return this->Visit(E->getChosenSubExpr(Context)); } - + void VisitDesignatedInitExpr(DesignatedInitExpr *E) { // Only the actual initializer matters; the designators are all constant // expressions. @@ -72,6 +72,15 @@ public: return static_cast<ImplClass*>(this)->VisitExpr(CE); } + void VisitLambdaExpr(LambdaExpr *LE) { + // Only visit the capture initializers, and not the body. + for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(), + E = LE->capture_init_end(); + I != E; ++I) + if (*I) + this->Visit(*I); + } + /// \brief The basis case walks all of the children of the statement or /// expression, assuming they are all potentially evaluated. void VisitStmt(Stmt *S) { diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 36d70d8..4ff1257 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -427,12 +427,24 @@ private: public: + /// \brief Returns true if this expression is a gl-value that + /// potentially refers to a bit-field. + /// + /// In C++, whether a gl-value refers to a bitfield is essentially + /// an aspect of the value-kind type system. + bool refersToBitField() const { return getObjectKind() == OK_BitField; } + /// \brief If this expression refers to a bit-field, retrieve the /// declaration of that bit-field. - FieldDecl *getBitField(); + /// + /// Note that this returns a non-null pointer in subtly different + /// places than refersToBitField returns true. In particular, this can + /// return a non-null pointer even for r-values loaded from + /// bit-fields, but it will return null for a conditional bit-field. + FieldDecl *getSourceBitField(); - const FieldDecl *getBitField() const { - return const_cast<Expr*>(this)->getBitField(); + const FieldDecl *getSourceBitField() const { + return const_cast<Expr*>(this)->getSourceBitField(); } /// \brief If this expression is an l-value for an Objective C @@ -2644,7 +2656,7 @@ protected: (ty->isInstantiationDependentType() || (op && op->isInstantiationDependent())), (ty->containsUnexpandedParameterPack() || - op->containsUnexpandedParameterPack())), + (op && op->containsUnexpandedParameterPack()))), Op(op) { assert(kind != CK_Invalid && "creating cast with invalid cast kind"); CastExprBits.Kind = kind; diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 04f6fb6..91e5b21 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -29,6 +29,7 @@ class CXXConstructorDecl; class CXXDestructorDecl; class CXXMethodDecl; class CXXTemporary; +class MSPropertyDecl; class TemplateArgumentListInfo; class UuidAttr; @@ -560,6 +561,64 @@ public: } }; +/// A member reference to an MSPropertyDecl. This expression always +/// has pseudo-object type, and therefore it is typically not +/// encountered in a fully-typechecked expression except within the +/// syntactic form of a PseudoObjectExpr. +class MSPropertyRefExpr : public Expr { + Expr *BaseExpr; + MSPropertyDecl *TheDecl; + SourceLocation MemberLoc; + bool IsArrow; + NestedNameSpecifierLoc QualifierLoc; + +public: + MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, + QualType ty, ExprValueKind VK, + NestedNameSpecifierLoc qualifierLoc, + SourceLocation nameLoc) + : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary, + /*type-dependent*/ false, baseExpr->isValueDependent(), + baseExpr->isInstantiationDependent(), + baseExpr->containsUnexpandedParameterPack()), + BaseExpr(baseExpr), TheDecl(decl), + MemberLoc(nameLoc), IsArrow(isArrow), + QualifierLoc(qualifierLoc) {} + + MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} + + SourceRange getSourceRange() const LLVM_READONLY { + return SourceRange(getLocStart(), getLocEnd()); + } + bool isImplicitAccess() const { + return getBaseExpr() && getBaseExpr()->isImplicitCXXThis(); + } + SourceLocation getLocStart() const { + if (!isImplicitAccess()) + return BaseExpr->getLocStart(); + else if (QualifierLoc) + return QualifierLoc.getBeginLoc(); + else + return MemberLoc; + } + SourceLocation getLocEnd() const { return getMemberLoc(); } + + child_range children() { + return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); + } + static bool classof(const Stmt *T) { + return T->getStmtClass() == MSPropertyRefExprClass; + } + + Expr *getBaseExpr() const { return BaseExpr; } + MSPropertyDecl *getPropertyDecl() const { return TheDecl; } + bool isArrow() const { return IsArrow; } + SourceLocation getMemberLoc() const { return MemberLoc; } + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + friend class ASTStmtReader; +}; + /// CXXUuidofExpr - A microsoft C++ @c __uuidof expression, which gets /// the _GUID that corresponds to the supplied type or expression. /// @@ -825,6 +884,53 @@ public: friend class ASTStmtWriter; }; +/// \brief This wraps a use of a C++ default initializer (technically, +/// a brace-or-equal-initializer for a non-static data member) when it +/// is implicitly used in a mem-initializer-list in a constructor +/// (C++11 [class.base.init]p8) or in aggregate initialization +/// (C++1y [dcl.init.aggr]p7). +class CXXDefaultInitExpr : public Expr { + /// \brief The field whose default is being used. + FieldDecl *Field; + + /// \brief The location where the default initializer expression was used. + SourceLocation Loc; + + CXXDefaultInitExpr(ASTContext &C, SourceLocation Loc, FieldDecl *Field, + QualType T); + + CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} + +public: + // Field is the non-static data member whose default initializer is used + // by this expression. + static CXXDefaultInitExpr *Create(ASTContext &C, SourceLocation Loc, + FieldDecl *Field) { + return new (C) CXXDefaultInitExpr(C, Loc, Field, Field->getType()); + } + + // Get the field whose initializer will be used. + FieldDecl *getField() { return Field; } + const FieldDecl *getField() const { return Field; } + + // Get the initialization expression that will be used. + const Expr *getExpr() const { return Field->getInClassInitializer(); } + Expr *getExpr() { return Field->getInClassInitializer(); } + + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXDefaultInitExprClass; + } + + // Iterators + child_range children() { return child_range(); } + + friend class ASTReader; + friend class ASTStmtReader; +}; + /// CXXTemporary - Represents a C++ temporary. class CXXTemporary { /// Destructor - The destructor that needs to be called. diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index dfd4527..a94c69a 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -476,7 +476,8 @@ public: SourceLocation l, SourceLocation oploc, Expr *base, bool arrow = false, bool freeIvar = false) : - Expr(ObjCIvarRefExprClass, t, VK_LValue, OK_Ordinary, + Expr(ObjCIvarRefExprClass, t, VK_LValue, + d->isBitField() ? OK_BitField : OK_Ordinary, /*TypeDependent=*/false, base->isValueDependent(), base->isInstantiationDependent(), base->containsUnexpandedParameterPack()), diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index 94faa19..b6d22cf 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -141,6 +141,16 @@ public: raw_ostream &) { llvm_unreachable("Target does not support mangling guard variables"); } + // FIXME: Revisit this once we know what we need to do for MSVC compatibility. + virtual void mangleItaniumThreadLocalInit(const VarDecl *D, + raw_ostream &) { + llvm_unreachable("Target does not support mangling thread_local variables"); + } + virtual void mangleItaniumThreadLocalWrapper(const VarDecl *D, + raw_ostream &) { + llvm_unreachable("Target does not support mangling thread_local variables"); + } + /// @} }; diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h index 3a8b218..84a6e96 100644 --- a/include/clang/AST/RawCommentList.h +++ b/include/clang/AST/RawCommentList.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H #define LLVM_CLANG_AST_RAW_COMMENT_LIST_H +#include "clang/Basic/CommentOptions.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" @@ -40,7 +41,7 @@ public: RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { } RawComment(const SourceManager &SourceMgr, SourceRange SR, - bool Merged = false); + bool Merged, bool ParseAllComments); CommentKind getKind() const LLVM_READONLY { return (CommentKind) Kind; @@ -82,7 +83,8 @@ public: /// Returns true if this comment is not a documentation comment. bool isOrdinary() const LLVM_READONLY { - return (Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC); + return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) && + !ParseAllComments; } /// Returns true if this comment any kind of a documentation comment. @@ -90,6 +92,11 @@ public: return !isInvalid() && !isOrdinary(); } + /// Returns whether we are parsing all comments. + bool isParseAllComments() const LLVM_READONLY { + return ParseAllComments; + } + /// Returns raw comment text with comment markers. StringRef getRawText(const SourceManager &SourceMgr) const { if (RawTextValid) @@ -135,6 +142,10 @@ private: bool IsTrailingComment : 1; bool IsAlmostTrailingComment : 1; + /// When true, ordinary comments starting with "//" and "/*" will be + /// considered as documentation comments. + bool ParseAllComments : 1; + mutable bool BeginLineValid : 1; ///< True if BeginLine is valid mutable bool EndLineValid : 1; ///< True if EndLine is valid mutable unsigned BeginLine; ///< Cached line number @@ -142,10 +153,12 @@ private: /// \brief Constructor for AST deserialization. RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, - bool IsAlmostTrailingComment) : + bool IsAlmostTrailingComment, + bool ParseAllComments) : Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), IsAttached(false), IsTrailingComment(IsTrailingComment), IsAlmostTrailingComment(IsAlmostTrailingComment), + ParseAllComments(ParseAllComments), BeginLineValid(false), EndLineValid(false) { } @@ -207,4 +220,3 @@ private: } // end namespace clang #endif - diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0191964..b5a4b5e 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1228,8 +1228,9 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { for (DeclContext::decl_iterator Child = DC->decls_begin(), ChildEnd = DC->decls_end(); Child != ChildEnd; ++Child) { - // BlockDecls are traversed through BlockExprs. - if (!isa<BlockDecl>(*Child)) + // BlockDecls and CapturedDecls are traversed through BlockExprs and + // CapturedStmts respectively. + if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child)) TRY_TO(TraverseDecl(*Child)); } @@ -1258,6 +1259,14 @@ DEF_TRAVERSE_DECL(BlockDecl, { return true; }) +DEF_TRAVERSE_DECL(CapturedDecl, { + TRY_TO(TraverseStmt(D->getBody())); + // This return statement makes sure the traversal of nodes in + // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) + // is skipped - don't remove it. + return true; + }) + DEF_TRAVERSE_DECL(EmptyDecl, { }) DEF_TRAVERSE_DECL(FileScopeAsmDecl, { @@ -1671,6 +1680,10 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) { return true; } +DEF_TRAVERSE_DECL(MSPropertyDecl, { + TRY_TO(TraverseDeclaratorHelper(D)); + }) + DEF_TRAVERSE_DECL(FieldDecl, { TRY_TO(TraverseDeclaratorHelper(D)); if (D->isBitField()) @@ -2058,6 +2071,10 @@ DEF_TRAVERSE_STMT(CXXTypeidExpr, { TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(MSPropertyRefExpr, { + TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); +}) + DEF_TRAVERSE_STMT(CXXUuidofExpr, { // The child-iterator will pick up the arg if it's an expression, // but not if it's a type. @@ -2153,6 +2170,7 @@ DEF_TRAVERSE_STMT(CompoundLiteralExpr, { DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, { }) DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, { }) DEF_TRAVERSE_STMT(CXXDefaultArgExpr, { }) +DEF_TRAVERSE_STMT(CXXDefaultInitExpr, { }) DEF_TRAVERSE_STMT(CXXDeleteExpr, { }) DEF_TRAVERSE_STMT(ExprWithCleanups, { }) DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, { }) @@ -2177,7 +2195,10 @@ DEF_TRAVERSE_STMT(ObjCEncodeExpr, { }) DEF_TRAVERSE_STMT(ObjCIsaExpr, { }) DEF_TRAVERSE_STMT(ObjCIvarRefExpr, { }) -DEF_TRAVERSE_STMT(ObjCMessageExpr, { }) +DEF_TRAVERSE_STMT(ObjCMessageExpr, { + if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo()) + TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); +}) DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, { }) DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, { }) DEF_TRAVERSE_STMT(ObjCProtocolExpr, { }) @@ -2210,6 +2231,9 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { DEF_TRAVERSE_STMT(SEHTryStmt, {}) DEF_TRAVERSE_STMT(SEHExceptStmt, {}) DEF_TRAVERSE_STMT(SEHFinallyStmt,{}) +DEF_TRAVERSE_STMT(CapturedStmt, { + TRY_TO(TraverseDecl(S->getCapturedDecl())); +}) DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { }) DEF_TRAVERSE_STMT(OpaqueValueExpr, { }) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index cf8fc24..74c9ec2 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -16,10 +16,12 @@ #include "clang/AST/DeclGroup.h" #include "clang/AST/StmtIterator.h" +#include "clang/Basic/CapturedStmt.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include <string> @@ -31,6 +33,7 @@ namespace llvm { namespace clang { class ASTContext; class Attr; + class CapturedDecl; class Decl; class Expr; class IdentifierInfo; @@ -39,6 +42,7 @@ namespace clang { class PrinterHelper; struct PrintingPolicy; class QualType; + class RecordDecl; class SourceManager; class StringLiteral; class SwitchStmt; @@ -1384,7 +1388,6 @@ protected: unsigned NumInputs; unsigned NumClobbers; - IdentifierInfo **Names; Stmt **Exprs; AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile, @@ -1392,10 +1395,12 @@ protected: Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile), NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { } + friend class ASTStmtReader; + public: /// \brief Build an empty inline-assembly statement. explicit AsmStmt(StmtClass SC, EmptyShell Empty) : - Stmt(SC, Empty), Names(0), Exprs(0) { } + Stmt(SC, Empty), Exprs(0) { } SourceLocation getAsmLoc() const { return AsmLoc; } void setAsmLoc(SourceLocation L) { AsmLoc = L; } @@ -1418,17 +1423,6 @@ public: unsigned getNumOutputs() const { return NumOutputs; } - IdentifierInfo *getOutputIdentifier(unsigned i) const { - return Names[i]; - } - - StringRef getOutputName(unsigned i) const { - if (IdentifierInfo *II = getOutputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - /// getOutputConstraint - Return the constraint string for the specified /// output operand. All output constraints are known to be non-empty (either /// '=' or '+'). @@ -1451,17 +1445,6 @@ public: unsigned getNumInputs() const { return NumInputs; } - IdentifierInfo *getInputIdentifier(unsigned i) const { - return Names[i + NumOutputs]; - } - - StringRef getInputName(unsigned i) const { - if (IdentifierInfo *II = getInputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - /// getInputConstraint - Return the specified input constraint. Unlike output /// constraints, these can be empty. StringRef getInputConstraint(unsigned i) const; @@ -1532,6 +1515,9 @@ class GCCAsmStmt : public AsmStmt { // FIXME: If we wanted to, we could allocate all of these in one big array. StringLiteral **Constraints; StringLiteral **Clobbers; + IdentifierInfo **Names; + + friend class ASTStmtReader; public: GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, @@ -1542,7 +1528,7 @@ public: /// \brief Build an empty inline-assembly statement. explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty), - Constraints(0), Clobbers(0) { } + Constraints(0), Clobbers(0), Names(0) { } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } @@ -1607,6 +1593,17 @@ public: //===--- Output operands ---===// + IdentifierInfo *getOutputIdentifier(unsigned i) const { + return Names[i]; + } + + StringRef getOutputName(unsigned i) const { + if (IdentifierInfo *II = getOutputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + StringRef getOutputConstraint(unsigned i) const; const StringLiteral *getOutputConstraintLiteral(unsigned i) const { @@ -1624,6 +1621,17 @@ public: //===--- Input operands ---===// + IdentifierInfo *getInputIdentifier(unsigned i) const { + return Names[i + NumOutputs]; + } + + StringRef getInputName(unsigned i) const { + if (IdentifierInfo *II = getInputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + StringRef getInputConstraint(unsigned i) const; const StringLiteral *getInputConstraintLiteral(unsigned i) const { @@ -1640,6 +1648,7 @@ public: return const_cast<GCCAsmStmt*>(this)->getInputExpr(i); } +private: void setOutputsAndInputsAndClobbers(ASTContext &C, IdentifierInfo **Names, StringLiteral **Constraints, @@ -1648,6 +1657,7 @@ public: unsigned NumInputs, StringLiteral **Clobbers, unsigned NumClobbers); +public: //===--- Other ---===// @@ -1674,7 +1684,7 @@ public: /// class MSAsmStmt : public AsmStmt { SourceLocation LBraceLoc, EndLoc; - std::string AsmStr; + StringRef AsmStr; unsigned NumAsmToks; @@ -1682,11 +1692,13 @@ class MSAsmStmt : public AsmStmt { StringRef *Constraints; StringRef *Clobbers; + friend class ASTStmtReader; + public: MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs, - ArrayRef<IdentifierInfo*> names, ArrayRef<StringRef> constraints, + ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs, StringRef asmstr, ArrayRef<StringRef> clobbers, SourceLocation endloc); @@ -1705,10 +1717,7 @@ public: Token *getAsmToks() { return AsmToks; } //===--- Asm String Analysis ---===// - - const std::string *getAsmString() const { return &AsmStr; } - std::string *getAsmString() { return &AsmStr; } - void setAsmString(StringRef &E) { AsmStr = E.str(); } + StringRef getAsmString() const { return AsmStr; } /// Assemble final IR asm string. std::string generateAsmString(ASTContext &C) const; @@ -1716,6 +1725,7 @@ public: //===--- Output operands ---===// StringRef getOutputConstraint(unsigned i) const { + assert(i < NumOutputs); return Constraints[i]; } @@ -1728,6 +1738,7 @@ public: //===--- Input operands ---===// StringRef getInputConstraint(unsigned i) const { + assert(i < NumInputs); return Constraints[i + NumOutputs]; } @@ -1740,7 +1751,27 @@ public: //===--- Other ---===// - StringRef getClobber(unsigned i) const { return Clobbers[i]; } + ArrayRef<StringRef> getAllConstraints() const { + return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs); + } + ArrayRef<StringRef> getClobbers() const { + return ArrayRef<StringRef>(Clobbers, NumClobbers); + } + ArrayRef<Expr*> getAllExprs() const { + return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs), + NumInputs + NumOutputs); + } + + StringRef getClobber(unsigned i) const { return getClobbers()[i]; } + +private: + void initialize(ASTContext &C, + StringRef AsmString, + ArrayRef<Token> AsmToks, + ArrayRef<StringRef> Constraints, + ArrayRef<Expr*> Exprs, + ArrayRef<StringRef> Clobbers); +public: SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } @@ -1882,6 +1913,198 @@ public: } }; +/// \brief This captures a statement into a function. For example, the following +/// pragma annotated compound statement can be represented as a CapturedStmt, +/// and this compound statement is the body of an anonymous outlined function. +/// @code +/// #pragma omp parallel +/// { +/// compute(); +/// } +/// @endcode +class CapturedStmt : public Stmt { +public: + /// \brief The different capture forms: by 'this' or by reference, etc. + enum VariableCaptureKind { + VCK_This, + VCK_ByRef + }; + + /// \brief Describes the capture of either a variable or 'this'. + class Capture { + llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind; + SourceLocation Loc; + + public: + /// \brief Create a new capture. + /// + /// \param Loc The source location associated with this capture. + /// + /// \param Kind The kind of capture (this, ByRef, ...). + /// + /// \param Var The variable being captured, or null if capturing this. + /// + Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0) + : VarAndKind(Var, Kind), Loc(Loc) { + switch (Kind) { + case VCK_This: + assert(Var == 0 && "'this' capture cannot have a variable!"); + break; + case VCK_ByRef: + assert(Var && "capturing by reference must have a variable!"); + break; + } + } + + /// \brief Determine the kind of capture. + VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); } + + /// \brief Retrieve the source location at which the variable or 'this' was + /// first used. + SourceLocation getLocation() const { return Loc; } + + /// \brief Determine whether this capture handles the C++ 'this' pointer. + bool capturesThis() const { return getCaptureKind() == VCK_This; } + + /// \brief Determine whether this capture handles a variable. + bool capturesVariable() const { return getCaptureKind() != VCK_This; } + + /// \brief Retrieve the declaration of the variable being captured. + /// + /// This operation is only valid if this capture does not capture 'this'. + VarDecl *getCapturedVar() const { + assert(!capturesThis() && "No variable available for 'this' capture"); + return VarAndKind.getPointer(); + } + friend class ASTStmtReader; + }; + +private: + /// \brief The number of variable captured, including 'this'. + unsigned NumCaptures; + + /// \brief The pointer part is the implicit the outlined function and the + /// int part is the captured region kind, 'CR_Default' etc. + llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind; + + /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl. + RecordDecl *TheRecordDecl; + + /// \brief Construct a captured statement. + CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures, + ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD); + + /// \brief Construct an empty captured statement. + CapturedStmt(EmptyShell Empty, unsigned NumCaptures); + + Stmt **getStoredStmts() const { + return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1); + } + + Capture *getStoredCaptures() const; + + void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; } + +public: + static CapturedStmt *Create(ASTContext &Context, Stmt *S, + CapturedRegionKind Kind, + ArrayRef<Capture> Captures, + ArrayRef<Expr *> CaptureInits, + CapturedDecl *CD, RecordDecl *RD); + + static CapturedStmt *CreateDeserialized(ASTContext &Context, + unsigned NumCaptures); + + /// \brief Retrieve the statement being captured. + Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; } + const Stmt *getCapturedStmt() const { + return const_cast<CapturedStmt *>(this)->getCapturedStmt(); + } + + /// \brief Retrieve the outlined function declaration. + CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); } + const CapturedDecl *getCapturedDecl() const { + return const_cast<CapturedStmt *>(this)->getCapturedDecl(); + } + + /// \brief Set the outlined function declaration. + void setCapturedDecl(CapturedDecl *D) { + assert(D && "null CapturedDecl"); + CapDeclAndKind.setPointer(D); + } + + /// \brief Retrieve the captured region kind. + CapturedRegionKind getCapturedRegionKind() const { + return CapDeclAndKind.getInt(); + } + + /// \brief Set the captured region kind. + void setCapturedRegionKind(CapturedRegionKind Kind) { + CapDeclAndKind.setInt(Kind); + } + + /// \brief Retrieve the record declaration for captured variables. + const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; } + + /// \brief Set the record declaration for captured variables. + void setCapturedRecordDecl(RecordDecl *D) { + assert(D && "null RecordDecl"); + TheRecordDecl = D; + } + + /// \brief True if this variable has been captured. + bool capturesVariable(const VarDecl *Var) const; + + /// \brief An iterator that walks over the captures. + typedef Capture *capture_iterator; + typedef const Capture *const_capture_iterator; + + /// \brief Retrieve an iterator pointing to the first capture. + capture_iterator capture_begin() { return getStoredCaptures(); } + const_capture_iterator capture_begin() const { return getStoredCaptures(); } + + /// \brief Retrieve an iterator pointing past the end of the sequence of + /// captures. + capture_iterator capture_end() const { + return getStoredCaptures() + NumCaptures; + } + + /// \brief Retrieve the number of captures, including 'this'. + unsigned capture_size() const { return NumCaptures; } + + /// \brief Iterator that walks over the capture initialization arguments. + typedef Expr **capture_init_iterator; + + /// \brief Retrieve the first initialization argument. + capture_init_iterator capture_init_begin() const { + return reinterpret_cast<Expr **>(getStoredStmts()); + } + + /// \brief Retrieve the iterator pointing one past the last initialization + /// argument. + capture_init_iterator capture_init_end() const { + return capture_init_begin() + NumCaptures; + } + + SourceLocation getLocStart() const LLVM_READONLY { + return getCapturedStmt()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getCapturedStmt()->getLocEnd(); + } + SourceRange getSourceRange() const LLVM_READONLY { + return getCapturedStmt()->getSourceRange(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CapturedStmtClass; + } + + child_range children(); + + friend class ASTStmtReader; +}; + } // end namespace clang #endif diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 23fa3e8..39f10d3 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -1326,10 +1326,20 @@ protected: unsigned AttrKind : 32 - NumTypeBits; }; + class AutoTypeBitfields { + friend class AutoType; + + unsigned : NumTypeBits; + + /// Was this placeholder type spelled as 'decltype(auto)'? + unsigned IsDecltypeAuto : 1; + }; + union { TypeBitfields TypeBits; ArrayTypeBitfields ArrayTypeBits; AttributedTypeBitfields AttributedTypeBits; + AutoTypeBitfields AutoTypeBits; BuiltinTypeBitfields BuiltinTypeBits; FunctionTypeBitfields FunctionTypeBits; ObjCObjectTypeBitfields ObjCObjectTypeBits; @@ -1443,8 +1453,8 @@ public: } /// isLiteralType - Return true if this is a literal type - /// (C++0x [basic.types]p10) - bool isLiteralType() const; + /// (C++11 [basic.types]p10) + bool isLiteralType(ASTContext &Ctx) const; /// \brief Test if this type is a standard-layout type. /// (C++0x [basic.type]p9) @@ -1609,6 +1619,10 @@ public: return TypeBits.InstantiationDependent; } + /// \brief Determine whether this type is an undeduced type, meaning that + /// it somehow involves a C++11 'auto' type which has not yet been deduced. + bool isUndeducedType() const; + /// \brief Whether this type is a variably-modified type (C99 6.7.5). bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } @@ -2092,14 +2106,6 @@ public: } }; -/// The inheritance model to use for this member pointer. -enum MSInheritanceModel { - MSIM_Single, - MSIM_Multiple, - MSIM_Virtual, - MSIM_Unspecified -}; - /// MemberPointerType - C++ 8.3.3 - Pointers to members /// class MemberPointerType : public Type, public llvm::FoldingSetNode { @@ -2135,10 +2141,6 @@ public: return !PointeeType->isFunctionProtoType(); } - /// Returns the number of pointer and integer slots used to represent this - /// member pointer in the MS C++ ABI. - std::pair<unsigned, unsigned> getMSMemberPointerSlots() const; - const Type *getClass() const { return Class; } bool isSugared() const { return false; } @@ -3554,41 +3556,48 @@ public: } }; -/// \brief Represents a C++0x auto type. +/// \brief Represents a C++11 auto or C++1y decltype(auto) type. /// -/// These types are usually a placeholder for a deduced type. However, within -/// templates and before the initializer is attached, there is no deduced type -/// and an auto type is type-dependent and canonical. +/// These types are usually a placeholder for a deduced type. However, before +/// the initializer is attached, or if the initializer is type-dependent, there +/// is no deduced type and an auto type is canonical. In the latter case, it is +/// also a dependent type. class AutoType : public Type, public llvm::FoldingSetNode { - AutoType(QualType DeducedType) + AutoType(QualType DeducedType, bool IsDecltypeAuto, bool IsDependent) : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, - /*Dependent=*/DeducedType.isNull(), - /*InstantiationDependent=*/DeducedType.isNull(), + /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent, /*VariablyModified=*/false, /*ContainsParameterPack=*/false) { - assert((DeducedType.isNull() || !DeducedType->isDependentType()) && - "deduced a dependent type for auto"); + assert((DeducedType.isNull() || !IsDependent) && + "auto deduced to dependent type"); + AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto; } friend class ASTContext; // ASTContext creates these public: - bool isSugared() const { return isDeduced(); } + bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; } + + bool isSugared() const { return !isCanonicalUnqualified(); } QualType desugar() const { return getCanonicalTypeInternal(); } + /// \brief Get the type deduced for this auto type, or null if it's either + /// not been deduced or was deduced to a dependent type. QualType getDeducedType() const { - return isDeduced() ? getCanonicalTypeInternal() : QualType(); + return !isCanonicalUnqualified() ? getCanonicalTypeInternal() : QualType(); } bool isDeduced() const { - return !isDependentType(); + return !isCanonicalUnqualified() || isDependentType(); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType()); + Profile(ID, getDeducedType(), isDecltypeAuto(), isDependentType()); } - static void Profile(llvm::FoldingSetNodeID &ID, - QualType Deduced) { + static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, + bool IsDecltypeAuto, bool IsDependent) { ID.AddPointer(Deduced.getAsOpaquePtr()); + ID.AddBoolean(IsDecltypeAuto); + ID.AddBoolean(IsDependent); } static bool classof(const Type *T) { @@ -4638,7 +4647,7 @@ inline QualType QualType::getUnqualifiedType() const { return QualType(getSplitUnqualifiedTypeImpl(*this).Ty, 0); } - + inline SplitQualType QualType::getSplitUnqualifiedType() const { if (!getTypePtr()->getCanonicalTypeInternal().hasLocalQualifiers()) return split(); @@ -4670,7 +4679,7 @@ inline void QualType::removeLocalCVRQualifiers(unsigned Mask) { inline unsigned QualType::getAddressSpace() const { return getQualifiers().getAddressSpace(); } - + /// getObjCGCAttr - Return the gc attribute of this type. inline Qualifiers::GC QualType::getObjCGCAttr() const { return getQualifiers().getObjCGCAttr(); @@ -5031,6 +5040,11 @@ inline bool Type::isBooleanType() const { return false; } +inline bool Type::isUndeducedType() const { + const AutoType *AT = getContainedAutoType(); + return AT && !AT->isDeduced(); +} + /// \brief Determines whether this is a type for which one can define /// an overloaded operator. inline bool Type::isOverloadableType() const { diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index d5c485f..840e07d 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -94,7 +94,7 @@ DEPENDENT_TYPE(TemplateTypeParm, Type) NON_CANONICAL_TYPE(SubstTemplateTypeParm, Type) DEPENDENT_TYPE(SubstTemplateTypeParmPack, Type) NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TemplateSpecialization, Type) -NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Auto, Type) +TYPE(Auto, Type) DEPENDENT_TYPE(InjectedClassName, Type) DEPENDENT_TYPE(DependentName, Type) DEPENDENT_TYPE(DependentTemplateSpecialization, Type) diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index f10addc..ab62dd0 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -129,7 +129,8 @@ typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher; /// \endcode /// /// Usable as: Any Matcher -inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> anything() { +inline internal::PolymorphicMatcherWithParam0<internal::TrueMatcher> +anything() { return internal::PolymorphicMatcherWithParam0<internal::TrueMatcher>(); } @@ -157,6 +158,17 @@ const internal::VariadicAllOfMatcher<Decl> decl; /// \endcode const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl; +/// \brief Matches a declaration of a namespace. +/// +/// Given +/// \code +/// namespace {} +/// namespace test {} +/// \endcode +/// namespaceDecl() +/// matches "namespace {}" and "namespace test {}" +const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl; + /// \brief Matches C++ class declarations. /// /// Example matches \c X, \c Z @@ -2514,6 +2526,38 @@ AST_MATCHER_P(CXXMethodDecl, ofClass, InnerMatcher.matches(*Parent, Finder, Builder)); } +/// \brief Matches if the given method declaration is virtual. +/// +/// Given +/// \code +/// class A { +/// public: +/// virtual void x(); +/// }; +/// \endcode +/// matches A::x +AST_MATCHER(CXXMethodDecl, isVirtual) { + return Node.isVirtual(); +} + +/// \brief Matches if the given method declaration overrides another method. +/// +/// Given +/// \code +/// class A { +/// public: +/// virtual void x(); +/// }; +/// class B : public A { +/// public: +/// virtual void x(); +/// }; +/// \endcode +/// matches B::x +AST_MATCHER(CXXMethodDecl, isOverride) { + return Node.size_overridden_methods() > 0; +} + /// \brief Matches member expressions that are called with '->' as opposed /// to '.'. /// diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 37aa332..441a79a 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -928,6 +928,10 @@ def TypeTagForDatatype : InheritableAttr { // Microsoft-related attributes +def MsProperty : Attr { + let Spellings = [Declspec<"property">]; +} + def MsStruct : InheritableAttr { let Spellings = [Declspec<"ms_struct">]; } diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def new file mode 100644 index 0000000..9e9f6d08 --- /dev/null +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -0,0 +1,18 @@ +//===-- BuiltinsAArch64.def - AArch64 Builtin function database -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the AArch64-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// The format of this database matches clang/Basic/Builtins.def. + +// In libgcc +BUILTIN(__clear_cache, "vv*v*", "") diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h new file mode 100644 index 0000000..484bbb1 --- /dev/null +++ b/include/clang/Basic/CapturedStmt.h @@ -0,0 +1,23 @@ +//===--- CapturedStmt.h - Types for CapturedStmts ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_CLANG_BASIC_CAPTUREDSTMT_H +#define LLVM_CLANG_BASIC_CAPTUREDSTMT_H + +namespace clang { + +/// \brief The different kinds of captured statement. +enum CapturedRegionKind { + CR_Default +}; + +} // end namespace clang + +#endif // LLVM_CLANG_BASIC_CAPTUREDSTMT_H diff --git a/include/clang/Basic/CommentOptions.h b/include/clang/Basic/CommentOptions.h index 79b9a6b..7991875 100644 --- a/include/clang/Basic/CommentOptions.h +++ b/include/clang/Basic/CommentOptions.h @@ -27,6 +27,11 @@ struct CommentOptions { /// \brief Command names to treat as block commands in comments. /// Should not include the leading backslash. BlockCommandNamesTy BlockCommandNames; + + /// \brief Treat ordinary comments as documentation comments. + bool ParseAllComments; + + CommentOptions() : ParseAllComments(false) { } }; } // end namespace clang diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index 45742bc..ad2afa7 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -34,14 +34,15 @@ def Named : Decl<1>; def UnresolvedUsingValue : DDecl<Value>; def IndirectField : DDecl<Value>; def Declarator : DDecl<Value, 1>; + def Field : DDecl<Declarator>; + def ObjCIvar : DDecl<Field>; + def ObjCAtDefsField : DDecl<Field>; + def MSProperty : DDecl<Declarator>; def Function : DDecl<Declarator>, DeclContext; def CXXMethod : DDecl<Function>; def CXXConstructor : DDecl<CXXMethod>; def CXXDestructor : DDecl<CXXMethod>; def CXXConversion : DDecl<CXXMethod>; - def Field : DDecl<Declarator>; - def ObjCIvar : DDecl<Field>; - def ObjCAtDefsField : DDecl<Field>; def Var : DDecl<Declarator>; def ImplicitParam : DDecl<Var>; def ParmVar : DDecl<Var>; @@ -72,6 +73,7 @@ def Friend : Decl; def FriendTemplate : Decl; def StaticAssert : Decl; def Block : Decl, DeclContext; +def Captured : Decl, DeclContext; def ClassScopeFunctionSpecialization : Decl; def Import : Decl; def OMPThreadPrivate : Decl; diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 0327636..3e12594 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -175,7 +175,6 @@ private: bool SuppressAllDiagnostics; // Suppress all diagnostics. bool ElideType; // Elide common types of templates. bool PrintTemplateTree; // Print a tree when comparing templates. - bool WarnOnSpellCheck; // Emit warning when spellcheck is initiated. bool ShowColors; // Color printing is enabled. OverloadsShown ShowOverloads; // Which overload candidates to show. unsigned ErrorLimit; // Cap of # errors emitted, 0 -> no limit. @@ -467,10 +466,6 @@ public: /// tree format. void setPrintTemplateTree(bool Val = false) { PrintTemplateTree = Val; } bool getPrintTemplateTree() { return PrintTemplateTree; } - - /// \brief Warn when spellchecking is initated, for testing. - void setWarnOnSpellCheck(bool Val = false) { WarnOnSpellCheck = Val; } - bool getWarnOnSpellCheck() { return WarnOnSpellCheck; } /// \brief Set color printing, so the type diffing will inject color markers /// into the output. @@ -1301,10 +1296,6 @@ public: /// warnings and errors. virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info); - - /// \brief Clone the diagnostic consumer, producing an equivalent consumer - /// that can be used in a different context. - virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0; }; /// \brief A diagnostic client that ignores all diagnostics. @@ -1314,9 +1305,24 @@ class IgnoringDiagConsumer : public DiagnosticConsumer { const Diagnostic &Info) { // Just ignore it. } - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { - return new IgnoringDiagConsumer(); - } +}; + +/// \brief Diagnostic consumer that forwards diagnostics along to an +/// existing, already-initialized diagnostic consumer. +/// +class ForwardingDiagnosticConsumer : public DiagnosticConsumer { + DiagnosticConsumer &Target; + +public: + ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {} + + virtual ~ForwardingDiagnosticConsumer(); + + virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info); + virtual void clear(); + + virtual bool IncludeInDiagnosticCounts() const; }; // Struct used for sending info about how a type should be printed. diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 9be32af..c69f85f 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -12,7 +12,7 @@ let Component = "AST" in { // Constant expression diagnostics. These (and their users) belong in Sema. def note_expr_divide_by_zero : Note<"division by zero">; def note_constexpr_invalid_cast : Note< - "%select{reinterpret_cast|dynamic_cast|cast which performs the conversions of" + "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of" " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression">; def note_constexpr_invalid_downcast : Note< "cannot cast object of dynamic type %0 to type %1">; @@ -26,6 +26,8 @@ def note_constexpr_lshift_discards : Note<"signed left shift discards bits">; def note_constexpr_invalid_function : Note< "%select{non-constexpr|undefined}0 %select{function|constructor}1 %2 cannot " "be used in a constant expression">; +def note_constexpr_no_return : Note< + "control reached end of constexpr function">; def note_constexpr_virtual_call : Note< "cannot evaluate virtual function call in a constant expression">; def note_constexpr_virtual_base : Note< @@ -82,11 +84,20 @@ def note_constexpr_depth_limit_exceeded : Note< def note_constexpr_call_limit_exceeded : Note< "constexpr evaluation hit maximum call limit">; def note_constexpr_lifetime_ended : Note< - "read of %select{temporary|variable}0 whose lifetime has ended">; -def note_constexpr_ltor_volatile_type : Note< - "read of volatile-qualified type %0 is not allowed in a constant expression">; -def note_constexpr_ltor_volatile_obj : Note< - "read of volatile %select{temporary|object %1|member %1}0 is not allowed in " + "%select{read of|assignment to|increment of|decrement of}0 " + "%select{temporary|variable}1 whose lifetime has ended">; +def note_constexpr_access_uninit : Note< + "%select{read of|assignment to|increment of|decrement of}0 " + "object outside its lifetime is not allowed in a constant expression">; +def note_constexpr_modify_const_type : Note< + "modification of object of const-qualified type %0 is not allowed " + "in a constant expression">; +def note_constexpr_access_volatile_type : Note< + "%select{read of|assignment to|increment of|decrement of}0 " + "volatile-qualified type %1 is not allowed in a constant expression">; +def note_constexpr_access_volatile_obj : Note< + "%select{read of|assignment to|increment of|decrement of}0 volatile " + "%select{temporary|object %2|member %2}1 is not allowed in " "a constant expression">; def note_constexpr_ltor_mutable : Note< "read of mutable member %0 is not allowed in a constant expression">; @@ -94,14 +105,19 @@ def note_constexpr_ltor_non_const_int : Note< "read of non-const variable %0 is not allowed in a constant expression">; def note_constexpr_ltor_non_constexpr : Note< "read of non-constexpr variable %0 is not allowed in a constant expression">; -def note_constexpr_read_past_end : Note< - "read of dereferenced one-past-the-end pointer is not allowed in a " - "constant expression">; -def note_constexpr_read_inactive_union_member : Note< - "read of member %0 of union with %select{active member %2|no active member}1 " +def note_constexpr_access_null : Note< + "%select{read of|assignment to|increment of|decrement of}0 " + "dereferenced null pointer is not allowed in a constant expression">; +def note_constexpr_access_past_end : Note< + "%select{read of|assignment to|increment of|decrement of}0 " + "dereferenced one-past-the-end pointer is not allowed in a constant expression">; +def note_constexpr_access_inactive_union_member : Note< + "%select{read of|assignment to|increment of|decrement of}0 " + "member %1 of union with %select{active member %3|no active member}2 " "is not allowed in a constant expression">; -def note_constexpr_read_uninit : Note< - "read of uninitialized object is not allowed in a constant expression">; +def note_constexpr_modify_global : Note< + "a constant expression cannot modify an object that is visible outside " + "that expression">; def note_constexpr_calls_suppressed : Note< "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to " "see all)">; diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td index 3880e0e..c913e31 100644 --- a/include/clang/Basic/DiagnosticCommentKinds.td +++ b/include/clang/Basic/DiagnosticCommentKinds.td @@ -156,5 +156,9 @@ def warn_verbatim_block_end_without_start : Warning< "'%select{\\|@}0%1' command does not terminate a verbatim text block">, InGroup<Documentation>, DefaultIgnore; +def warn_unknown_comment_command_name : Warning< + "unknown command tag name">, + InGroup<DocumentationUnknownCommand>, DefaultIgnore; + } // end of documentation issue category } // end of AST component diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 15b8948..db457b1 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -105,8 +105,6 @@ def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this "-fobjc-arc is not supported on versions of OS X prior to 10.6">; def err_drv_mg_requires_m_or_mm : Error< "option '-MG' requires '-M' or '-MM'">; -def err_drv_asan_android_requires_pie : Error< - "AddressSanitizer on Android requires '-pie'">; def err_drv_unknown_objc_runtime : Error< "unknown or ill-formed Objective-C runtime '%0'">; diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 111622e..f05fb9b 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -67,6 +67,8 @@ def warn_fe_serialized_diag_failure : Warning< def err_verify_missing_line : Error< "missing or invalid line number following '@' in expected %0">; +def err_verify_missing_file : Error< + "file '%0' could not be located in expected %1">; def err_verify_invalid_range : Error< "invalid range following '-' in expected %0">; def err_verify_missing_start : Error< diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index a12a4f9..d5f777d 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -27,7 +27,9 @@ def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">; def Availability : DiagGroup<"availability">; def Section : DiagGroup<"section">; def AutoImport : DiagGroup<"auto-import">; -def ConstantConversion : DiagGroup<"constant-conversion">; +def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">; +def ConstantConversion : + DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >; def LiteralConversion : DiagGroup<"literal-conversion">; def StringConversion : DiagGroup<"string-conversion">; def SignConversion : DiagGroup<"sign-conversion">; @@ -66,7 +68,9 @@ def : DiagGroup<"discard-qual">; def : DiagGroup<"div-by-zero">; def DocumentationHTML : DiagGroup<"documentation-html">; -def DocumentationPedantic : DiagGroup<"documentation-pedantic">; +def DocumentationUnknownCommand : DiagGroup<"documentation-unknown-command">; +def DocumentationPedantic : DiagGroup<"documentation-pedantic", + [DocumentationUnknownCommand]>; def DocumentationDeprecatedSync : DiagGroup<"documentation-deprecated-sync">; def Documentation : DiagGroup<"documentation", [DocumentationHTML, @@ -80,6 +84,11 @@ def ExtraSemi : DiagGroup<"extra-semi", [CXX11ExtraSemi]>; def FormatExtraArgs : DiagGroup<"format-extra-args">; def FormatZeroLength : DiagGroup<"format-zero-length">; +// Warnings for C++1y code which is not compatible with prior C++ standards. +def CXXPre1yCompat : DiagGroup<"cxx98-cxx11-compat">; +def CXXPre1yCompatPedantic : DiagGroup<"cxx98-cxx11-compat-pedantic", + [CXXPre1yCompat]>; + def CXX98CompatBindToTemporaryCopy : DiagGroup<"c++98-compat-bind-to-temporary-copy">; def CXX98CompatLocalTypeTemplateArgs : @@ -90,9 +99,12 @@ def CXX98CompatUnnamedTypeTemplateArgs : def CXX98Compat : DiagGroup<"c++98-compat", [CXX98CompatBindToTemporaryCopy, CXX98CompatLocalTypeTemplateArgs, - CXX98CompatUnnamedTypeTemplateArgs]>; + CXX98CompatUnnamedTypeTemplateArgs, + CXXPre1yCompat]>; // Warnings for C++11 features which are Extensions in C++98 mode. -def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat]>; +def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", + [CXX98Compat, + CXXPre1yCompatPedantic]>; def CXX11Narrowing : DiagGroup<"c++11-narrowing">; @@ -110,8 +122,11 @@ def ReservedUserDefinedLiteral : def CXX11Compat : DiagGroup<"c++11-compat", [CXX11Narrowing, - CXX11CompatReservedUserDefinedLiteral]>; + CXX11CompatReservedUserDefinedLiteral, + CXXPre1yCompat]>; def : DiagGroup<"c++0x-compat", [CXX11Compat]>; +def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic", + [CXXPre1yCompatPedantic]>; def : DiagGroup<"effc++">; def DivZero : DiagGroup<"division-by-zero">; @@ -122,6 +137,7 @@ def GlobalConstructors : DiagGroup<"global-constructors">; def BitwiseOpParentheses: DiagGroup<"bitwise-op-parentheses">; def LogicalOpParentheses: DiagGroup<"logical-op-parentheses">; def ShiftOpParentheses: DiagGroup<"shift-op-parentheses">; +def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">; def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; @@ -253,7 +269,6 @@ def : DiagGroup<"strict-overflow=5">; def : DiagGroup<"strict-overflow">; def InvalidOffsetof : DiagGroup<"invalid-offsetof">; -def LambdaExtensions : DiagGroup<"lambda-extensions">; def : DiagGroup<"strict-prototypes">; def StrictSelector : DiagGroup<"strict-selector-match">; def MethodDuplicate : DiagGroup<"duplicate-method-match">; @@ -352,6 +367,7 @@ def Parentheses : DiagGroup<"parentheses", [LogicalOpParentheses, BitwiseOpParentheses, ShiftOpParentheses, + OverloadedShiftOpParentheses, ParenthesesOnEquality, DanglingElse]>; @@ -476,6 +492,10 @@ def NonGCC : DiagGroup<"non-gcc", // earlier C++ versions. def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11LongLong]>; +// A warning group for warnings about using C++1y features as extensions in +// earlier C++ versions. +def CXX1y : DiagGroup<"c++1y-extensions">; + def : DiagGroup<"c++0x-extensions", [CXX11]>; def DelegatingCtorCycles : DiagGroup<"delegating-ctor-cycles">; diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 339788b..2c16000 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -174,6 +174,11 @@ def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">, InGroup<C99>; def ext_binary_literal : Extension< "binary integer literals are a GNU extension">, InGroup<GNU>; +def ext_binary_literal_cxx1y : Extension< + "binary integer literals are a C++1y extension">, InGroup<CXX1y>; +def warn_cxx11_compat_binary_literal : Warning< + "binary integer literals are incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompatPedantic>, DefaultIgnore; def err_pascal_string_too_long : Error<"Pascal string is too long">; def warn_octal_escape_too_large : ExtWarn<"octal escape sequence out of range">; def warn_hex_escape_too_large : ExtWarn<"hex escape sequence out of range">; @@ -403,16 +408,15 @@ def warn_pragma_include_alias_expected_filename : def err__Pragma_malformed : Error< "_Pragma takes a parenthesized string literal">; -def err_pragma_comment_malformed : Error< - "pragma comment requires parenthesized identifier and optional string">; def err_pragma_message_malformed : Error< - "pragma message requires parenthesized string">; + "pragma %select{message|warning|error}0 requires parenthesized string">; def err_pragma_push_pop_macro_malformed : Error< "pragma %0 requires a parenthesized string">; def warn_pragma_pop_macro_no_push : Warning< "pragma pop_macro could not pop '%0', no matching push_macro">; def warn_pragma_message : Warning<"%0">, InGroup<PoundPragmaMessage>, DefaultWarnNoWerror; +def err_pragma_message : Error<"%0">; def warn_pragma_ignored : Warning<"unknown pragma ignored">, InGroup<UnknownPragmas>, DefaultIgnore; def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, @@ -446,7 +450,6 @@ def warn_pragma_diagnostic_unknown_warning : def warn_pragma_debug_unexpected_command : Warning< "unexpected debug command '%0'">; -def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">; def err_defined_macro_name : Error<"'defined' cannot be used as a macro name">; def err_paste_at_start : Error< "'##' cannot appear at start of macro expansion">; @@ -476,9 +479,9 @@ def ext_pp_line_zero : Extension< def err_pp_line_invalid_filename : Error< "invalid filename for #line directive">; def warn_pp_line_decimal : Warning< - "#line directive interprets number as decimal, not octal">; + "%select{#line|GNU line marker}0 directive interprets number as decimal, not octal">; def err_pp_line_digit_sequence : Error< - "#line directive requires a simple digit sequence">; + "%select{#line|GNU line marker}0 directive requires a simple digit sequence">; def err_pp_linemarker_requires_integer : Error< "line marker directive requires a positive integer argument">; def err_pp_linemarker_invalid_filename : Error< diff --git a/include/clang/Basic/DiagnosticOptions.def b/include/clang/Basic/DiagnosticOptions.def index 8e5562c..41bbff2 100644 --- a/include/clang/Basic/DiagnosticOptions.def +++ b/include/clang/Basic/DiagnosticOptions.def @@ -72,7 +72,6 @@ DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected DIAGOPT(ElideType, 1, 0) /// Elide identical types in template diffing DIAGOPT(ShowTemplateTree, 1, 0) /// Print a template tree when diffing -DIAGOPT(WarnOnSpellCheck, 1, 0) /// -fwarn-on-spellcheck VALUE_DIAGOPT(ErrorLimit, 32, 0) /// Limit # errors emitted. /// Limit depth of macro expansion backtrace. diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 04a433c..e001bd4 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -18,6 +18,13 @@ def w_asm_qualifier_ignored : Warning<"ignored %0 qualifier on asm">, def warn_file_asm_volatile : Warning< "meaningless 'volatile' on asm outside function">, CatInlineAsm; +let CategoryName = "Inline Assembly Issue" in { +def err_asm_empty : Error<"__asm used with no assembly instructions">; +def err_inline_ms_asm_parsing : Error<"%0">; +def err_msasm_unsupported_arch : Error< + "Unsupported architecture '%0' for MS-style inline assembly">; +} + let CategoryName = "Parse Issue" in { def ext_empty_translation_unit : Extension< @@ -277,6 +284,11 @@ def warn_auto_storage_class : Warning< def ext_auto_storage_class : ExtWarn< "'auto' storage class specifier is not permitted in C++11, and will not " "be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>; +def ext_decltype_auto_type_specifier : ExtWarn< + "'decltype(auto)' type specifier is a C++1y extension">, InGroup<CXX1y>; +def warn_cxx11_compat_decltype_auto_type_specifier : Warning< + "'decltype(auto)' type specifier is incompatible with C++ standards before " + "C++1y">, InGroup<CXXPre1yCompat>, DefaultIgnore; def ext_for_range : ExtWarn< "range-based for loop is a C++11 extension">, InGroup<CXX11>; def warn_cxx98_compat_for_range : Warning< @@ -352,6 +364,8 @@ def warn_cxx98_compat_static_assert : Warning< InGroup<CXX98Compat>, DefaultIgnore; def err_paren_after_colon_colon : Error< "unexpected parenthesis after '::'">; +def err_function_definition_not_allowed : Error< + "function definition is not allowed here">; /// Objective-C parser diagnostics def err_expected_minus_or_plus : Error< @@ -411,6 +425,8 @@ def err_missing_catch_finally : Error< def err_objc_concat_string : Error<"unexpected token after Objective-C string">; def err_expected_objc_container : Error< "'@end' must appear in an Objective-C context">; +def err_unexpected_protocol_qualifier : Error< + "@implementation declaration can not be protocol qualified">; def err_objc_unexpected_atend : Error< "'@end' appears where closing brace '}' is expected">; def error_property_ivar_decl : Error< @@ -527,6 +543,22 @@ def err_ms_declspec_type : Error< "__declspec attributes must be an identifier or string literal">; def warn_ms_declspec_unknown : Warning< "unknown __declspec attribute %0 ignored">, InGroup<UnknownAttributes>; +def err_ms_property_no_getter_or_putter : Error< + "property does not specify a getter or a putter">; +def err_ms_property_unknown_accessor : Error< + "expected 'get' or 'put' in property declaration">; +def err_ms_property_has_set_accessor : Error< + "putter for property must be specified as 'put', not 'set'">; +def err_ms_property_missing_accessor_kind : Error< + "missing 'get=' or 'put='">; +def err_ms_property_expected_equal : Error< + "expected '=' after '%0'">; +def err_ms_property_duplicate_accessor : Error< + "property declaration specifies '%0' accessor twice">; +def err_ms_property_expected_accessor_name : Error< + "expected name of accessor method">; +def err_ms_property_expected_comma_or_rparen : Error< + "expected ',' or ')' at end of property accessor list">; /// C++ Templates def err_expected_template : Error<"expected template">; @@ -670,6 +702,8 @@ def err_duplicate_virt_specifier : Error< def err_scoped_enum_missing_identifier : Error< "scoped enumeration requires a name">; +def ext_scoped_enum : ExtWarn< + "scoped enumerations are a C++11 extension">, InGroup<CXX11>; def warn_cxx98_compat_scoped_enum : Warning< "scoped enumerations are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -751,6 +785,10 @@ def warn_pragma_unused_expected_punc : Warning< def err_pragma_fp_contract_scope : Error< "'#pragma fp_contract' should only appear at file scope or at the start of a " "compound expression">; +// - #pragma comment +def err_pragma_comment_malformed : Error< + "pragma comment requires parenthesized identifier and optional string">; +def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">; // OpenCL Section 6.8.g diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index c4815cd..f5345eb 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -78,6 +78,9 @@ def ext_vla : Extension<"variable length arrays are a C99 feature">, InGroup<VLAExtension>; def warn_vla_used : Warning<"variable length array used">, InGroup<VLA>, DefaultIgnore; +def warn_cxx11_compat_array_of_runtime_bound : Warning< + "arrays of runtime bound are incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompatPedantic>, DefaultIgnore; def err_vla_non_pod : Error<"variable length array of non-POD element type %0">; def err_vla_in_sfinae : Error< "variable length array cannot be formed during template argument deduction">; @@ -296,9 +299,9 @@ def warn_exit_time_destructor : Warning< InGroup<ExitTimeDestructors>, DefaultIgnore; def err_invalid_thread : Error< - "'__thread' is only allowed on variable declarations">; + "'%0' is only allowed on variable declarations">; def err_thread_non_global : Error< - "'__thread' variables must have global storage">; + "'%0' variables must have global storage">; def err_thread_unsupported : Error< "thread-local storage is unsupported for the current target">; @@ -639,6 +642,10 @@ def warn_objc_isa_use : Warning< def warn_objc_isa_assign : Warning< "assignment to Objective-C's isa is deprecated in favor of " "object_setClass()">, InGroup<DeprecatedObjCIsaUsage>; +def warn_objc_pointer_masking : Warning< + "bitmasking for introspection of Objective-C object pointers is strongly " + "discouraged">, + InGroup<DiagGroup<"deprecated-objc-pointer-introspection">>; def warn_objc_property_default_assign_on_object : Warning< "default property attribute 'assign' not appropriate for non-GC object">, InGroup<ObjCPropertyNoAttribute>; @@ -1300,7 +1307,8 @@ def err_member_function_call_bad_cvr : Error<"member function %0 not viable: " "volatile or restrict|const, volatile, or restrict}2">; def err_reference_bind_to_bitfield : Error< - "%select{non-const|volatile}0 reference cannot bind to bit-field %1">; + "%select{non-const|volatile}0 reference cannot bind to " + "bit-field%select{| %1}2">; def err_reference_bind_to_vector_element : Error< "%select{non-const|volatile}0 reference cannot bind to vector element">; def err_reference_var_requires_init : Error< @@ -1421,7 +1429,7 @@ def err_auto_not_allowed : Error< "|in non-static union member|in non-static class member|in interface member" "|in exception declaration|in template parameter|in block literal" "|in template argument|in typedef|in type alias|in function return type" - "|here}0">; + "|in conversion function type|here}0">; def err_auto_var_requires_init : Error< "declaration of variable %0 with type %1 requires an initializer">; def err_auto_new_requires_ctor_arg : Error< @@ -1447,7 +1455,8 @@ def err_auto_var_deduction_failure_from_init_list : Error< def err_auto_new_deduction_failure : Error< "new expression for type %0 has incompatible constructor argument of type %1">; def err_auto_different_deductions : Error< - "'auto' deduced as %0 in declaration of %1 and deduced as %2 in declaration of %3">; + "'%select{auto|decltype(auto)}0' deduced as %1 in declaration of %2 and " + "deduced as %3 in declaration of %4">; def err_implied_std_initializer_list_not_found : Error< "cannot deduce type of initializer list because std::initializer_list was " "not found; include <initializer_list>">; @@ -1458,6 +1467,34 @@ def warn_dangling_std_initializer_list : Warning< "%select{the full-expression|the constructor}0">, InGroup<DiagGroup<"dangling-initializer-list">>; +// C++1y decltype(auto) type +def err_decltype_auto_cannot_be_combined : Error< + "'decltype(auto)' cannot be combined with other type specifiers">; +def err_decltype_auto_function_declarator_not_declaration : Error< + "'decltype(auto)' can only be used as a return type " + "in a function declaration">; +def err_decltype_auto_compound_type : Error< + "cannot form %select{pointer to|reference to|array of}0 'decltype(auto)'">; +def err_decltype_auto_initializer_list : Error< + "cannot deduce 'decltype(auto)' from initializer list">; + +// C++1y deduced return types +def err_auto_fn_deduction_failure : Error< + "cannot deduce return type %0 from returned value of type %1">; +def err_auto_fn_different_deductions : Error< + "'%select{auto|decltype(auto)}0' in return type deduced as %1 here but " + "deduced as %2 in earlier return statement">; +def err_auto_fn_used_before_defined : Error< + "function %0 with deduced return type cannot be used before it is defined">; +def err_auto_fn_no_return_but_not_auto : Error< + "cannot deduce return type %0 for function with no return statements">; +def err_auto_fn_return_void_but_not_auto : Error< + "cannot deduce return type %0 from omitted return expression">; +def err_auto_fn_return_init_list : Error< + "cannot deduce return type from initializer list">; +def err_auto_fn_virtual : Error< + "function with deduced return type cannot be virtual">; + // C++11 override control def override_keyword_only_allowed_on_virtual_member_functions : Error< "only virtual member functions can be marked '%0'">; @@ -1547,6 +1584,11 @@ def note_for_range_begin_end : Note< def warn_cxx98_compat_constexpr : Warning< "'constexpr' specifier is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +// FIXME: Maybe this should also go in -Wc++1y-compat? +def warn_cxx1y_compat_constexpr_not_const : Warning< + "'constexpr' non-static member function will not be implicitly 'const' " + "in C++1y; add 'const' to avoid a change in behavior">, + InGroup<DiagGroup<"constexpr-not-const">>; def err_invalid_constexpr : Error< "%select{function parameter|typedef|non-static data member}0 " "cannot be constexpr">; @@ -1585,20 +1627,54 @@ def err_constexpr_non_literal_param : Error< "not a literal type">; def err_constexpr_body_invalid_stmt : Error< "statement not allowed in constexpr %select{function|constructor}0">; -def err_constexpr_type_definition : Error< - "types cannot be defined in a constexpr %select{function|constructor}0">; +def ext_constexpr_body_invalid_stmt : ExtWarn< + "use of this statement in a constexpr %select{function|constructor}0 " + "is a C++1y extension">, InGroup<CXX1y>; +def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning< + "use of this statement in a constexpr %select{function|constructor}0 " + "is incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompat>, DefaultIgnore; +def ext_constexpr_type_definition : ExtWarn< + "type definition in a constexpr %select{function|constructor}0 " + "is a C++1y extension">, InGroup<CXX1y>; +def warn_cxx11_compat_constexpr_type_definition : Warning< + "type definition in a constexpr %select{function|constructor}0 " + "is incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompat>, DefaultIgnore; def err_constexpr_vla : Error< "variably-modified type %0 cannot be used in a constexpr " "%select{function|constructor}1">; -def err_constexpr_var_declaration : Error< - "variables cannot be declared in a constexpr %select{function|constructor}0">; +def ext_constexpr_local_var : ExtWarn< + "variable declaration in a constexpr %select{function|constructor}0 " + "is a C++1y extension">, InGroup<CXX1y>; +def warn_cxx11_compat_constexpr_local_var : Warning< + "variable declaration in a constexpr %select{function|constructor}0 " + "is incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompat>, DefaultIgnore; +def err_constexpr_local_var_static : Error< + "%select{static|thread_local}1 variable not permitted in a constexpr " + "%select{function|constructor}0">; +def err_constexpr_local_var_non_literal_type : Error< + "variable of non-literal type %1 cannot be defined in a constexpr " + "%select{function|constructor}0">; +def err_constexpr_local_var_no_init : Error< + "variables defined in a constexpr %select{function|constructor}0 must be " + "initialized">; def ext_constexpr_function_never_constant_expr : ExtWarn< "constexpr %select{function|constructor}0 never produces a " "constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError; def err_constexpr_body_no_return : Error< "no return statement in constexpr function">; -def err_constexpr_body_multiple_return : Error< - "multiple return statements in constexpr function">; +def warn_cxx11_compat_constexpr_body_no_return : Warning< + "constexpr function with no return statements is incompatible with C++ " + "standards before C++1y">, InGroup<CXXPre1yCompat>, DefaultIgnore; +def ext_constexpr_body_multiple_return : ExtWarn< + "multiple return statements in constexpr function is a C++1y extension">, + InGroup<CXX1y>; +def warn_cxx11_compat_constexpr_body_multiple_return : Warning< + "multiple return statements in constexpr function " + "is incompatible with C++ standards before C++1y">, + InGroup<CXXPre1yCompat>, DefaultIgnore; def note_constexpr_body_previous_return : Note< "previous return statement is here">; def err_constexpr_function_try_block : Error< @@ -1810,6 +1886,19 @@ def err_attribute_section_local_variable : Error< def warn_mismatched_section : Warning< "section does not match previous declaration">, InGroup<Section>; +def err_anonymous_property: Error< + "anonymous property is not supported">; +def err_property_is_variably_modified: Error< + "property '%0' has a variably modified type">; +def err_no_getter_for_property : Error< + "no getter defined for property '%0'">; +def err_no_setter_for_property : Error< + "no setter defined for property '%0'">; +def error_cannot_find_suitable_getter : Error< + "cannot find suitable getter for property '%0'">; +def error_cannot_find_suitable_setter : Error< + "cannot find suitable setter for property '%0'">; + def err_attribute_aligned_not_power_of_two : Error< "requested alignment is not a power of 2">; def err_attribute_aligned_greater_than_8192 : Error< @@ -2088,7 +2177,7 @@ def warn_impcast_integer_precision_constant : Warning< InGroup<ConstantConversion>; def warn_impcast_bitfield_precision_constant : Warning< "implicit truncation from %2 to bitfield changes value from %0 to %1">, - InGroup<ConstantConversion>; + InGroup<BitFieldConstantConversion>; def warn_impcast_literal_float_to_integer : Warning< "implicit conversion from %0 to %1 changes value from %2 to %3">, InGroup<LiteralConversion>; @@ -2370,6 +2459,11 @@ def note_ovl_candidate_failed_overload_resolution : Note< "function %0">; def note_ovl_candidate_non_deduced_mismatch : Note< "candidate template ignored: could not match %diff{$ against $|types}0,1">; +// This note is needed because the above note would sometimes print two +// different types with the same name. Remove this note when the above note +// can handle that case properly. +def note_ovl_candidate_non_deduced_mismatch_qualified : Note< + "candidate template ignored: could not match %q0 against %q1">; // Note that we don't treat templates differently for this diagnostic. def note_ovl_candidate_arity : Note<"candidate " @@ -3364,6 +3458,9 @@ def err_non_thread_thread : Error< "non-thread-local declaration of %0 follows thread-local declaration">; def err_thread_non_thread : Error< "thread-local declaration of %0 follows non-thread-local declaration">; +def err_thread_thread_different_kind : Error< + "thread-local declaration of %0 with %select{static|dynamic}1 initialization " + "follows declaration with %select{dynamic|static}1 initialization">; def err_redefinition_different_type : Error< "redefinition of %0 with a different type%diff{: $ vs $|}1,2">; def err_redefinition_different_kind : Error< @@ -3722,8 +3819,10 @@ def err_arc_unsupported_weak_class : Error< def err_arc_weak_unavailable_assign : Error< "assignment of a weak-unavailable object to a __weak object">; def err_arc_weak_unavailable_property : Error< - "synthesis of a weak-unavailable property is disallowed " - "because it requires synthesis of an instance variable of the __weak object">; + "synthesizing __weak instance variable of type %0, which does not " + "support weak references">; +def note_implemented_by_class : Note< + "when implemented by class %0">; def err_arc_convesion_of_weak_unavailable : Error< "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to" " a __weak object of type %2">; @@ -3956,6 +4055,8 @@ def err_sizeof_alignof_incomplete_type : Error< "incomplete type %1">; def err_sizeof_alignof_bitfield : Error< "invalid application of '%select{sizeof|alignof}0' to bit-field">; +def err_alignof_member_of_incomplete_type : Error< + "invalid application of 'alignof' to a field of a class still being defined">; def err_vecstep_non_scalar_vector_type : Error< "'vec_step' requires built-in scalar or vector type, %0 invalid">; def err_offsetof_incomplete_type : Error< @@ -4020,6 +4121,13 @@ def warn_bitwise_and_in_bitwise_or : Warning< def warn_logical_and_in_logical_or : Warning< "'&&' within '||'">, InGroup<LogicalOpParentheses>; +def warn_overloaded_shift_in_comparison :Warning< + "overloaded operator %select{>>|<<}0 has lower precedence than " + "comparison operator">, + InGroup<OverloadedShiftOpParentheses>; +def note_evaluate_comparison_first :Note< + "place parentheses around comparison expression to evaluate it first">; + def warn_addition_in_bitshift : Warning< "operator '%0' has lower precedence than '%1'; " "'%1' will be evaluated first">, InGroup<ShiftOpParentheses>; @@ -4468,8 +4576,7 @@ def err_catch_param_not_objc_type : Error< def err_illegal_qualifiers_on_catch_parm : Error< "illegal qualifiers on @catch parameter">; def err_storage_spec_on_catch_parm : Error< - "@catch parameter cannot have storage specifier %select{|'typedef'|'extern'|" - "'static'|'auto'|'register'|'__private_extern__'|'mutable'}0">; + "@catch parameter cannot have storage specifier '%0'">; def warn_register_objc_catch_parm : Warning< "'register' storage specifier on @catch parameter will be ignored">; def err_qualified_objc_catch_parm : Error< @@ -4523,6 +4630,9 @@ def err_bad_cxx_cast_generic : Error< def err_bad_cxx_cast_rvalue : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" "functional-style cast}0 from rvalue to reference type %2">; +def err_bad_cxx_cast_bitfield : Error< + "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" + "functional-style cast}0 from bit-field lvalue to reference type %2">; def err_bad_cxx_cast_qualifiers_away : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" "functional-style cast}0 from %1 to %2 casts away qualifiers">; @@ -4686,7 +4796,16 @@ def warn_overloaded_virtual : Warning< "%q0 hides overloaded virtual %select{function|functions}1">, InGroup<OverloadedVirtual>, DefaultIgnore; def note_hidden_overloaded_virtual_declared_here : Note< - "hidden overloaded virtual function %q0 declared here">; + "hidden overloaded virtual function %q0 declared here" + "%select{|: different classes%diff{ ($ vs $)|}2,3" + "|: different number of parameters (%2 vs %3)" + "|: type mismatch at %ordinal2 parameter%diff{ ($ vs $)|}3,4" + "|: different return type%diff{ ($ vs $)|}2,3" + "|: different qualifiers (" + "%select{none|const|restrict|const and restrict|volatile|const and volatile|" + "volatile and restrict|const, volatile, and restrict}2 vs " + "%select{none|const|restrict|const and restrict|volatile|const and volatile|" + "volatile and restrict|const, volatile, and restrict}3)}1">; def warn_using_directive_in_header : Warning< "using namespace directive in global context in header">, InGroup<HeaderHygiene>, DefaultIgnore; @@ -4753,9 +4872,6 @@ let CategoryName = "Lambda Issue" in { "incomplete result type %0 in lambda expression">; def err_lambda_objc_object_result : Error< "non-pointer Objective-C class type %0 in lambda expression result">; - def ext_lambda_default_arguments : ExtWarn< - "C++11 forbids default arguments for lambda expressions">, - InGroup<LambdaExtensions>; def err_noreturn_lambda_has_return_expr : Error< "lambda declared 'noreturn' should not return">; def warn_maybe_falloff_nonvoid_lambda : Warning< @@ -4775,6 +4891,9 @@ let CategoryName = "Lambda Issue" in { "here">; } +def err_return_in_captured_stmt : Error< + "cannot return from %0">; + def err_operator_arrow_circular : Error< "circular pointer delegation detected">; def err_pseudo_dtor_base_not_scalar : Error< @@ -5313,16 +5432,13 @@ let CategoryName = "Inline Assembly Issue" in { def err_asm_tying_incompatible_types : Error< "unsupported inline asm: input with type " "%diff{$ matching output with type $|}0,1">; + def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">; def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">; - def err_asm_empty : Error<"__asm used with no assembly instructions">; def err_asm_invalid_input_size : Error< "invalid input size for constraint '%0'">; def err_invalid_asm_cast_lvalue : Error< "invalid use of a cast in a inline asm context requiring an l-value: " "remove the cast or build with -fheinous-gnu-extensions">; - def err_inline_ms_asm_parsing : Error<"%0">; - def err_msasm_unsupported_arch : Error< - "Unsupported architecture '%0' for MS-style inline assembly">; def warn_asm_label_on_auto_decl : Warning< "ignored asm label '%0' on automatic variable">; @@ -5402,6 +5518,13 @@ def ext_in_class_initializer_non_constant : Extension< "in-class initializer for static data member is not a constant expression; " "folding it to a constant is a GNU extension">, InGroup<GNU>; +def err_thread_dynamic_init : Error< + "initializer for thread-local variable must be a constant expression">; +def err_thread_nontrivial_dtor : Error< + "type of thread-local variable has non-trivial destruction">; +def note_use_thread_local : Note< + "use 'thread_local' to allow this">; + // C++ anonymous unions and GNU anonymous structs/unions def ext_anonymous_union : Extension< "anonymous unions are a C11 extension">, InGroup<C11>; @@ -6020,8 +6143,10 @@ def ext_mixed_decls_code : Extension< "ISO C90 forbids mixing declarations and code">, InGroup<DiagGroup<"declaration-after-statement">>; -def err_non_variable_decl_in_for : Error< +def err_non_local_variable_decl_in_for : Error< "declaration of non-local variable in 'for' loop">; +def err_non_variable_decl_in_for : Error< + "non-variable declaration in 'for' loop">; def err_toomany_element_decls : Error< "only one element declaration is allowed">; def err_selector_element_not_lvalue : Error< @@ -6205,7 +6330,9 @@ def err_sampler_argument_required : Error< "sampler_t variable required - got %0">; def err_wrong_sampler_addressspace: Error< "sampler type cannot be used with the __local and __global address space qualifiers">; - +def err_opencl_global_invalid_addr_space : Error< + "global variables must have a constant address space qualifier">; + // OpenMP support. def err_omp_expected_var_arg_suggest : Error< "%0 is not a global variable, static local variable or static data member%select{|; did you mean %2?}1">; diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index 7137404..1b45b10 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/include/clang/Basic/DiagnosticSerializationKinds.td @@ -58,6 +58,10 @@ def err_pch_undef : Error< "%select{command line contains|precompiled header was built with}0 " "'-undef' but %select{precompiled header was not built with it|" "it is not present on the command line}0">; +def err_pch_pp_detailed_record : Error< + "%select{command line contains|precompiled header was built with}0 " + "'-detailed-preprocessing-record' but %select{precompiled header was not " + "built with it|it is not present on the command line}0">; def err_not_a_pch_file : Error< "'%0' does not appear to be a precompiled header file">, DefaultFatal; diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index c04a893..d4d5339 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -394,7 +394,7 @@ public: /// /// \returns A new iterator into the set of known identifiers. The /// caller is responsible for deleting this iterator. - virtual IdentifierIterator *getIdentifiers() const; + virtual IdentifierIterator *getIdentifiers(); }; /// \brief An abstract class used to resolve numerical identifier diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index 3de0107..b17dfbc 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -156,7 +156,7 @@ ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling") -BENIGN_LANGOPT(InstantiationDepth, 32, 512, +BENIGN_LANGOPT(InstantiationDepth, 32, 256, "maximum template instantiation depth") BENIGN_LANGOPT(ConstexprCallDepth, 32, 512, "maximum constexpr call depth") diff --git a/include/clang/Basic/OnDiskHashTable.h b/include/clang/Basic/OnDiskHashTable.h index 06cb143..ee30123 100644 --- a/include/clang/Basic/OnDiskHashTable.h +++ b/include/clang/Basic/OnDiskHashTable.h @@ -103,7 +103,7 @@ inline uint32_t ReadLE32(const unsigned char *&Data) { // Hosts that directly support little-endian 32-bit loads can just // use them. Big-endian hosts need a bswap. uint32_t V = *((const uint32_t*)Data); - if (llvm::sys::isBigEndianHost()) + if (llvm::sys::IsBigEndianHost) V = llvm::ByteSwap_32(V); Data += 4; return V; diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 00c96c3..f82b196 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -646,6 +646,13 @@ class SourceManager : public RefCountedBase<SourceManager> { // Statistics for -print-stats. mutable unsigned NumLinearScans, NumBinaryProbes; + /// \brief Associates a FileID with its "included/expanded in" decomposed + /// location. + /// + /// Used to cache results from and speed-up \c getDecomposedIncludedLoc + /// function. + mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned> > IncludedLocMap; + /// The key value into the IsBeforeInTUCache table. typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey; @@ -1127,6 +1134,10 @@ public: return getDecomposedSpellingLocSlowCase(E, Offset); } + /// \brief Returns the "included/expanded in" decomposed location of the given + /// FileID. + std::pair<FileID, unsigned> getDecomposedIncludedLoc(FileID FID) const; + /// \brief Returns the offset from the start of the file that the /// specified SourceLocation represents. /// diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index 8706179..eb3fc65 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -38,8 +38,8 @@ namespace clang { TST_void, TST_char, TST_wchar, // C++ wchar_t - TST_char16, // C++0x char16_t - TST_char32, // C++0x char32_t + TST_char16, // C++11 char16_t + TST_char32, // C++11 char32_t TST_int, TST_int128, TST_half, // OpenCL half, ARM NEON __fp16 @@ -57,11 +57,12 @@ namespace clang { TST_typename, // Typedef, C++ class-name or enum name, etc. 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_atomic, // C11 _Atomic + TST_decltype, // C++11 decltype + TST_underlyingType, // __underlying_type for C++11 + TST_auto, // C++11 auto + TST_decltype_auto, // C++1y decltype(auto) + TST_unknown_anytype, // __unknown_anytype extension + TST_atomic, // C11 _Atomic TST_image1d_t, // OpenCL image1d_t TST_image1d_array_t, // OpenCL image1d_array_t TST_image1d_buffer_t, // OpenCL image1d_buffer_t @@ -145,7 +146,7 @@ namespace clang { TSK_ExplicitSpecialization, /// This template specialization was instantiated from a template /// due to an explicit instantiation declaration request - /// (C++0x [temp.explicit]). + /// (C++11 [temp.explicit]). TSK_ExplicitInstantiationDeclaration, /// This template specialization was instantiated from a template /// due to an explicit instantiation definition request @@ -153,6 +154,19 @@ namespace clang { TSK_ExplicitInstantiationDefinition }; + /// \brief Thread storage-class-specifier. + enum ThreadStorageClassSpecifier { + TSCS_unspecified, + /// GNU __thread. + TSCS___thread, + /// C++11 thread_local. Implies 'static' at block scope, but not at + /// class scope. + TSCS_thread_local, + /// C11 _Thread_local. Must be combined with either 'static' or 'extern' + /// if used at block scope. + TSCS__Thread_local + }; + /// \brief Storage classes. enum StorageClass { // These are legal on both functions and variables. diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 8f6a1c9..cbfce83 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -27,6 +27,7 @@ def DeclStmt : Stmt; def SwitchCase : Stmt<1>; def CaseStmt : DStmt<SwitchCase>; def DefaultStmt : DStmt<SwitchCase>; +def CapturedStmt : Stmt; // Asm statements def AsmStmt : Stmt<1>; @@ -107,6 +108,7 @@ def CXXNullPtrLiteralExpr : DStmt<Expr>; def CXXThisExpr : DStmt<Expr>; def CXXThrowExpr : DStmt<Expr>; def CXXDefaultArgExpr : DStmt<Expr>; +def CXXDefaultInitExpr : DStmt<Expr>; def CXXScalarValueInitExpr : DStmt<Expr>; def CXXNewExpr : DStmt<Expr>; def CXXDeleteExpr : DStmt<Expr>; @@ -163,6 +165,7 @@ def BlockExpr : DStmt<Expr>; def OpaqueValueExpr : DStmt<Expr>; // Microsoft Extensions. +def MSPropertyRefExpr : DStmt<Expr>; def CXXUuidofExpr : DStmt<Expr>; def SEHTryStmt : Stmt; def SEHExceptStmt : Stmt; diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h index 1d5004c..66e378f 100644 --- a/include/clang/Basic/TargetBuiltins.h +++ b/include/clang/Basic/TargetBuiltins.h @@ -21,6 +21,15 @@ namespace clang { + /// \brief AArch64 builtins + namespace AArch64 { + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsAArch64.def" + LastTSBuiltin + }; + } /// \brief ARM builtins namespace ARM { enum { diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index c05f062..49b26ac 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -66,6 +66,7 @@ protected: unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; unsigned char SuitableAlign; + unsigned char MinGlobalAlign; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short MaxVectorAlign; const char *DescriptionString; @@ -156,7 +157,16 @@ public: /// __builtin_va_list as defined by ARM AAPCS ABI /// http://infocenter.arm.com // /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf - AAPCSABIBuiltinVaList + AAPCSABIBuiltinVaList, + + // typedef struct __va_list_tag + // { + // long __gpr; + // long __fpr; + // void *__overflow_arg_area; + // void *__reg_save_area; + // } va_list[1]; + SystemZBuiltinVaList }; protected: @@ -266,6 +276,10 @@ public: /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } + /// getMinGlobalAlign - Return the minimum alignment of a global variable, + /// unless its alignment is explicitly reduced via attributes. + unsigned getMinGlobalAlign() const { return MinGlobalAlign; } + /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in /// bits. unsigned getWCharWidth() const { return getTypeWidth(WCharType); } diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index a254fae..bcf0f31 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -262,6 +262,7 @@ KEYWORD(_Generic , KEYALL) KEYWORD(_Imaginary , KEYALL) KEYWORD(_Noreturn , KEYALL) KEYWORD(_Static_assert , KEYALL) +KEYWORD(_Thread_local , KEYALL) KEYWORD(__func__ , KEYALL) KEYWORD(__objc_yes , KEYALL) KEYWORD(__objc_no , KEYALL) @@ -614,6 +615,11 @@ ANNOTATION(pragma_pack) // handles them. ANNOTATION(pragma_parser_crash) +// Annotation for #pragma clang __debug captured... +// The lexer produces these so that they only take effect when the parser +// handles them. +ANNOTATION(pragma_captured) + // Annotation for #pragma ms_struct... // The lexer produces these so that they only take effect when the parser // handles them. diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index 3373e01..77bc797 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -77,9 +77,23 @@ class Inst <string n, string p, string t, Op o> { Op Operand = o; bit isShift = 0; bit isVCVT_N = 0; + + // Certain intrinsics have different names than their representative + // instructions. This field allows us to handle this correctly when we + // are generating tests. + string InstName = ""; + + // Certain intrinsics even though they are not a WOpInst or LOpInst, + // generate a WOpInst/LOpInst instruction (see below for definition + // of a WOpInst/LOpInst). For testing purposes we need to know + // this. Ex: vset_lane which outputs vmov instructions. + bit isHiddenWInst = 0; + bit isHiddenLInst = 0; } -// Used to generate Builtins.def: +// The following instruction classes are implemented via builtins. +// These declarations are used to generate Builtins.def: +// // SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8", "p8") // IInst: Instruction with generic integer suffix (e.g., "i8") // WInst: Instruction with only bit size suffix (e.g., "8") @@ -87,6 +101,22 @@ class SInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} class IInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} class WInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} +// The following instruction classes are implemented via operators +// instead of builtins. As such these declarations are only used for +// the purpose of generating tests. +// +// SOpInst: Instruction with signed/unsigned suffix (e.g., "s8", +// "u8", "p8"). +// IOpInst: Instruction with generic integer suffix (e.g., "i8"). +// WOpInst: Instruction with bit size only suffix (e.g., "8"). +// LOpInst: Logical instruction with no bit size suffix. +// NoTestOpInst: Intrinsic that has no corresponding instruction. +class SOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class IOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class WOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class LOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} +class NoTestOpInst<string n, string p, string t, Op o> : Inst<n, p, t, o> {} + // prototype: return (arg, arg, ...) // v: void // t: best-fit integer (int/poly args) @@ -123,9 +153,10 @@ class WInst<string n, string p, string t> : Inst<n, p, t, OP_NONE> {} //////////////////////////////////////////////////////////////////////////////// // E.3.1 Addition -def VADD : Inst<"vadd", "ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>; -def VADDL : Inst<"vaddl", "wdd", "csiUcUsUi", OP_ADDL>; -def VADDW : Inst<"vaddw", "wwd", "csiUcUsUi", OP_ADDW>; +def VADD : IOpInst<"vadd", "ddd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_ADD>; +def VADDL : SOpInst<"vaddl", "wdd", "csiUcUsUi", OP_ADDL>; +def VADDW : SOpInst<"vaddw", "wwd", "csiUcUsUi", OP_ADDW>; def VHADD : SInst<"vhadd", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VRHADD : SInst<"vrhadd", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VQADD : SInst<"vqadd", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; @@ -134,12 +165,12 @@ def VRADDHN : IInst<"vraddhn", "hkk", "silUsUiUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.2 Multiplication -def VMUL : Inst<"vmul", "ddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MUL>; +def VMUL : IOpInst<"vmul", "ddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MUL>; def VMULP : SInst<"vmul", "ddd", "PcQPc">; -def VMLA : Inst<"vmla", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>; -def VMLAL : Inst<"vmlal", "wwdd", "csiUcUsUi", OP_MLAL>; -def VMLS : Inst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>; -def VMLSL : Inst<"vmlsl", "wwdd", "csiUcUsUi", OP_MLSL>; +def VMLA : IOpInst<"vmla", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLA>; +def VMLAL : SOpInst<"vmlal", "wwdd", "csiUcUsUi", OP_MLAL>; +def VMLS : IOpInst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>; +def VMLSL : SOpInst<"vmlsl", "wwdd", "csiUcUsUi", OP_MLSL>; def VQDMULH : SInst<"vqdmulh", "ddd", "siQsQi">; def VQRDMULH : SInst<"vqrdmulh", "ddd", "siQsQi">; def VQDMLAL : SInst<"vqdmlal", "wwdd", "si">; @@ -149,9 +180,10 @@ def VQDMULL : SInst<"vqdmull", "wdd", "si">; //////////////////////////////////////////////////////////////////////////////// // E.3.3 Subtraction -def VSUB : Inst<"vsub", "ddd", "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>; -def VSUBL : Inst<"vsubl", "wdd", "csiUcUsUi", OP_SUBL>; -def VSUBW : Inst<"vsubw", "wwd", "csiUcUsUi", OP_SUBW>; +def VSUB : IOpInst<"vsub", "ddd", + "csilfUcUsUiUlQcQsQiQlQfQUcQUsQUiQUl", OP_SUB>; +def VSUBL : SOpInst<"vsubl", "wdd", "csiUcUsUi", OP_SUBL>; +def VSUBW : SOpInst<"vsubw", "wwd", "csiUcUsUi", OP_SUBW>; def VQSUB : SInst<"vqsub", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl">; def VHSUB : SInst<"vhsub", "ddd", "csiUcUsUiQcQsQiQUcQUsQUi">; def VSUBHN : IInst<"vsubhn", "hkk", "silUsUiUl">; @@ -159,23 +191,29 @@ def VRSUBHN : IInst<"vrsubhn", "hkk", "silUsUiUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.4 Comparison -def VCEQ : Inst<"vceq", "udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>; -def VCGE : Inst<"vcge", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>; -def VCLE : Inst<"vcle", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>; -def VCGT : Inst<"vcgt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>; -def VCLT : Inst<"vclt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>; +def VCEQ : IOpInst<"vceq", "udd", "csifUcUsUiPcQcQsQiQfQUcQUsQUiQPc", OP_EQ>; +def VCGE : SOpInst<"vcge", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GE>; +let InstName = "vcge" in +def VCLE : SOpInst<"vcle", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LE>; +def VCGT : SOpInst<"vcgt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_GT>; +let InstName = "vcgt" in +def VCLT : SOpInst<"vclt", "udd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_LT>; +let InstName = "vacge" in { def VCAGE : IInst<"vcage", "udd", "fQf">; def VCALE : IInst<"vcale", "udd", "fQf">; +} +let InstName = "vacgt" in { def VCAGT : IInst<"vcagt", "udd", "fQf">; def VCALT : IInst<"vcalt", "udd", "fQf">; +} def VTST : WInst<"vtst", "udd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc">; //////////////////////////////////////////////////////////////////////////////// // E.3.5 Absolute Difference def VABD : SInst<"vabd", "ddd", "csiUcUsUifQcQsQiQUcQUsQUiQf">; -def VABDL : Inst<"vabdl", "wdd", "csiUcUsUi", OP_ABDL>; -def VABA : Inst<"vaba", "dddd", "csiUcUsUiQcQsQiQUcQUsQUi", OP_ABA>; -def VABAL : Inst<"vabal", "wwdd", "csiUcUsUi", OP_ABAL>; +def VABDL : SOpInst<"vabdl", "wdd", "csiUcUsUi", OP_ABDL>; +def VABA : SOpInst<"vaba", "dddd", "csiUcUsUiQcQsQiQUcQUsQUi", OP_ABA>; +def VABAL : SOpInst<"vabal", "wwdd", "csiUcUsUi", OP_ABAL>; //////////////////////////////////////////////////////////////////////////////// // E.3.6 Max/Min @@ -264,35 +302,43 @@ def VST4_LANE : WInst<"vst4_lane", "vp4i", "QUsQUiQsQiQhQfQPsUcUsUicsihfPcPs">; //////////////////////////////////////////////////////////////////////////////// // E.3.16 Extract lanes from a vector +let InstName = "vmov" in def VGET_LANE : IInst<"vget_lane", "sdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.17 Set lanes within a vector +let InstName = "vmov" in def VSET_LANE : IInst<"vset_lane", "dsdi", "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl">; //////////////////////////////////////////////////////////////////////////////// // E.3.18 Initialize a vector from bit pattern -def VCREATE: Inst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>; +def VCREATE : NoTestOpInst<"vcreate", "dl", "csihfUcUsUiUlPcPsl", OP_CAST>; //////////////////////////////////////////////////////////////////////////////// // E.3.19 Set all lanes to same value -def VDUP_N : Inst<"vdup_n", "ds", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; -def VMOV_N : Inst<"vmov_n", "ds", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; -def VDUP_LANE : Inst<"vdup_lane", "dgi", - "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl",OP_DUP_LN>; +let InstName = "vmov" in { +def VDUP_N : WOpInst<"vdup_n", "ds", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; +def VMOV_N : WOpInst<"vmov_n", "ds", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", OP_DUP>; +} +let InstName = "" in +def VDUP_LANE: WOpInst<"vdup_lane", "dgi", + "UcUsUicsiPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUl", + OP_DUP_LN>; //////////////////////////////////////////////////////////////////////////////// // E.3.20 Combining vectors -def VCOMBINE : Inst<"vcombine", "kdd", "csilhfUcUsUiUlPcPs", OP_CONC>; +def VCOMBINE : NoTestOpInst<"vcombine", "kdd", "csilhfUcUsUiUlPcPs", OP_CONC>; //////////////////////////////////////////////////////////////////////////////// // E.3.21 Splitting vectors -def VGET_HIGH : Inst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; -def VGET_LOW : Inst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +let InstName = "vmov" in { +def VGET_HIGH : NoTestOpInst<"vget_high", "dk", "csilhfUcUsUiUlPcPs", OP_HI>; +def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; +} //////////////////////////////////////////////////////////////////////////////// // E.3.22 Converting vectors @@ -313,39 +359,46 @@ def VQMOVUN : SInst<"vqmovun", "ek", "sil">; //////////////////////////////////////////////////////////////////////////////// // E.3.23-24 Table lookup, Extended table lookup +let InstName = "vtbl" in { def VTBL1 : WInst<"vtbl1", "ddt", "UccPc">; def VTBL2 : WInst<"vtbl2", "d2t", "UccPc">; def VTBL3 : WInst<"vtbl3", "d3t", "UccPc">; def VTBL4 : WInst<"vtbl4", "d4t", "UccPc">; +} +let InstName = "vtbx" in { def VTBX1 : WInst<"vtbx1", "dddt", "UccPc">; def VTBX2 : WInst<"vtbx2", "dd2t", "UccPc">; def VTBX3 : WInst<"vtbx3", "dd3t", "UccPc">; def VTBX4 : WInst<"vtbx4", "dd4t", "UccPc">; +} //////////////////////////////////////////////////////////////////////////////// // E.3.25 Operations with a scalar value -def VMLA_LANE : Inst<"vmla_lane", "dddgi", "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; -def VMLAL_LANE : Inst<"vmlal_lane", "wwddi", "siUsUi", OP_MLAL_LN>; -def VQDMLAL_LANE : Inst<"vqdmlal_lane", "wwddi", "si", OP_QDMLAL_LN>; -def VMLS_LANE : Inst<"vmls_lane", "dddgi", "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; -def VMLSL_LANE : Inst<"vmlsl_lane", "wwddi", "siUsUi", OP_MLSL_LN>; -def VQDMLSL_LANE : Inst<"vqdmlsl_lane", "wwddi", "si", OP_QDMLSL_LN>; -def VMUL_N : Inst<"vmul_n", "dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>; -def VMUL_LANE : Inst<"vmul_lane", "ddgi", "sifUsUiQsQiQfQUsQUi", OP_MUL_LN>; -def VMULL_N : SInst<"vmull_n", "wda", "siUsUi">; -def VMULL_LANE : Inst<"vmull_lane", "wddi", "siUsUi", OP_MULL_LN>; -def VQDMULL_N : SInst<"vqdmull_n", "wda", "si">; -def VQDMULL_LANE : Inst<"vqdmull_lane", "wddi", "si", OP_QDMULL_LN>; -def VQDMULH_N : SInst<"vqdmulh_n", "dda", "siQsQi">; -def VQDMULH_LANE : Inst<"vqdmulh_lane", "ddgi", "siQsQi", OP_QDMULH_LN>; -def VQRDMULH_N : SInst<"vqrdmulh_n", "dda", "siQsQi">; -def VQRDMULH_LANE : Inst<"vqrdmulh_lane", "ddgi", "siQsQi", OP_QRDMULH_LN>; -def VMLA_N : Inst<"vmla_n", "ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>; -def VMLAL_N : Inst<"vmlal_n", "wwda", "siUsUi", OP_MLAL_N>; -def VQDMLAL_N : SInst<"vqdmlal_n", "wwda", "si">; -def VMLS_N : Inst<"vmls_n", "ddds", "siUsUifQsQiQUsQUiQf", OP_MLS_N>; -def VMLSL_N : Inst<"vmlsl_n", "wwda", "siUsUi", OP_MLSL_N>; -def VQDMLSL_N : SInst<"vqdmlsl_n", "wwda", "si">; +def VMLA_LANE : IOpInst<"vmla_lane", "dddgi", + "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; +def VMLAL_LANE : SOpInst<"vmlal_lane", "wwddi", "siUsUi", OP_MLAL_LN>; +def VQDMLAL_LANE : SOpInst<"vqdmlal_lane", "wwddi", "si", OP_QDMLAL_LN>; +def VMLS_LANE : IOpInst<"vmls_lane", "dddgi", + "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; +def VMLSL_LANE : SOpInst<"vmlsl_lane", "wwddi", "siUsUi", OP_MLSL_LN>; +def VQDMLSL_LANE : SOpInst<"vqdmlsl_lane", "wwddi", "si", OP_QDMLSL_LN>; +def VMUL_N : IOpInst<"vmul_n", "dds", "sifUsUiQsQiQfQUsQUi", OP_MUL_N>; +def VMUL_LANE : IOpInst<"vmul_lane", "ddgi", + "sifUsUiQsQiQfQUsQUi", OP_MUL_LN>; +def VMULL_N : SInst<"vmull_n", "wda", "siUsUi">; +def VMULL_LANE : SOpInst<"vmull_lane", "wddi", "siUsUi", OP_MULL_LN>; +def VQDMULL_N : SInst<"vqdmull_n", "wda", "si">; +def VQDMULL_LANE : SOpInst<"vqdmull_lane", "wddi", "si", OP_QDMULL_LN>; +def VQDMULH_N : SInst<"vqdmulh_n", "dda", "siQsQi">; +def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "ddgi", "siQsQi", OP_QDMULH_LN>; +def VQRDMULH_N : SInst<"vqrdmulh_n", "dda", "siQsQi">; +def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ddgi", "siQsQi", OP_QRDMULH_LN>; +def VMLA_N : IOpInst<"vmla_n", "ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>; +def VMLAL_N : SOpInst<"vmlal_n", "wwda", "siUsUi", OP_MLAL_N>; +def VQDMLAL_N : SInst<"vqdmlal_n", "wwda", "si">; +def VMLS_N : IOpInst<"vmls_n", "ddds", "siUsUifQsQiQUsQUiQf", OP_MLS_N>; +def VMLSL_N : SOpInst<"vmlsl_n", "wwda", "siUsUi", OP_MLSL_N>; +def VQDMLSL_N : SInst<"vqdmlsl_n", "wwda", "si">; //////////////////////////////////////////////////////////////////////////////// // E.3.26 Vector Extract @@ -354,16 +407,16 @@ def VEXT : WInst<"vext", "dddi", //////////////////////////////////////////////////////////////////////////////// // E.3.27 Reverse vector elements -def VREV64 : Inst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", +def VREV64 : WOpInst<"vrev64", "dd", "csiUcUsUiPcPsfQcQsQiQUcQUsQUiQPcQPsQf", OP_REV64>; -def VREV32 : Inst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>; -def VREV16 : Inst<"vrev16", "dd", "cUcPcQcQUcQPc", OP_REV16>; +def VREV32 : WOpInst<"vrev32", "dd", "csUcUsPcPsQcQsQUcQUsQPcQPs", OP_REV32>; +def VREV16 : WOpInst<"vrev16", "dd", "cUcPcQcQUcQPc", OP_REV16>; //////////////////////////////////////////////////////////////////////////////// // E.3.28 Other single operand arithmetic def VABS : SInst<"vabs", "dd", "csifQcQsQiQf">; def VQABS : SInst<"vqabs", "dd", "csiQcQsQi">; -def VNEG : Inst<"vneg", "dd", "csifQcQsQiQf", OP_NEG>; +def VNEG : SOpInst<"vneg", "dd", "csifQcQsQiQf", OP_NEG>; def VQNEG : SInst<"vqneg", "dd", "csiQcQsQi">; def VCLS : SInst<"vcls", "dd", "csiQcQsQi">; def VCLZ : IInst<"vclz", "dd", "csiUcUsUiQcQsQiQUcQUsQUi">; @@ -373,12 +426,13 @@ def VRSQRTE : SInst<"vrsqrte", "dd", "fUiQfQUi">; //////////////////////////////////////////////////////////////////////////////// // E.3.29 Logical operations -def VMVN : Inst<"vmvn", "dd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>; -def VAND : Inst<"vand", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>; -def VORR : Inst<"vorr", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>; -def VEOR : Inst<"veor", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>; -def VBIC : Inst<"vbic", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>; -def VORN : Inst<"vorn", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>; +def VMVN : LOpInst<"vmvn", "dd", "csiUcUsUiPcQcQsQiQUcQUsQUiQPc", OP_NOT>; +def VAND : LOpInst<"vand", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_AND>; +def VORR : LOpInst<"vorr", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_OR>; +def VEOR : LOpInst<"veor", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_XOR>; +def VBIC : LOpInst<"vbic", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ANDN>; +def VORN : LOpInst<"vorn", "ddd", "csilUcUsUiUlQcQsQiQlQUcQUsQUiQUl", OP_ORN>; +let isHiddenLInst = 1 in def VBSL : SInst<"vbsl", "dudd", "csilUcUsUiUlfPcPsQcQsQiQlQUcQUsQUiQUlQfQPcQPs">; @@ -391,7 +445,7 @@ def VUZP : WInst<"vuzp", "2dd", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">; //////////////////////////////////////////////////////////////////////////////// // E.3.31 Vector reinterpret cast operations def VREINTERPRET - : Inst<"vreinterpret", "dd", + : NoTestOpInst<"vreinterpret", "dd", "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT>; //////////////////////////////////////////////////////////////////////////////// diff --git a/include/clang/Driver/ArgList.h b/include/clang/Driver/ArgList.h index 3967dcc..9db170c 100644 --- a/include/clang/Driver/ArgList.h +++ b/include/clang/Driver/ArgList.h @@ -237,10 +237,19 @@ namespace driver { /// true if the option is present, false if the negation is present, and /// \p Default if neither option is given. If both the option and its /// negation are present, the last one wins. - bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const; + bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default = true) const; + + /// hasFlag - Given an option \p Pos, an alias \p PosAlias and its negative + /// form \p Neg, return true if the option or its alias is present, false if + /// the negation is present, and \p Default if none of the options are + /// given. If multiple options are present, the last one wins. + bool hasFlag(OptSpecifier Pos, OptSpecifier PosAlias, OptSpecifier Neg, + bool Default = true) const; /// AddLastArg - Render only the last argument match \p Id0, if present. void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const; + void AddLastArg(ArgStringList &Output, OptSpecifier Id0, + OptSpecifier Id1) const; /// AddAllArgs - Render all arguments matching the given ids. void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index e4dd345..96a50fc 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -245,9 +245,6 @@ def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">, def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, HelpText<"Silence ObjC rewriting warnings">; -def fwarn_on_spellcheck : Flag<["-"], "fwarn-on-spellcheck">, - HelpText<"Emit warning if spell-check is initiated, for testing">; - //===----------------------------------------------------------------------===// // Frontend Options //===----------------------------------------------------------------------===// diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 1330e95..d9053d1 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -335,6 +335,7 @@ public: const ToolChain *TC, const char *BoundArch, bool AtTopLevel, + bool MultipleArchs, const char *LinkingOutput, InputInfo &Result) const; @@ -346,11 +347,15 @@ public: /// \param JA - The action of interest. /// \param BaseInput - The original input file that this action was /// triggered by. + /// \param BoundArch - The bound architecture. /// \param AtTopLevel - Whether this is a "top-level" action. + /// \param MultipleArchs - Whether multiple -arch options were supplied. const char *GetNamedOutputPath(Compilation &C, const JobAction &JA, const char *BaseInput, - bool AtTopLevel) const; + const char *BoundArch, + bool AtTopLevel, + bool MultipleArchs) const; /// GetTemporaryPath - Return the pathname of a temporary file to use /// as part of compilation; the file will have the given prefix and suffix. diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 112feb7..3a5358a 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -181,6 +181,7 @@ def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>, def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>, HelpText<"Treat source input files as Objective-C inputs">; def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>; +def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>; def P : Flag<["-"], "P">, Flags<[CC1Option]>, HelpText<"Disable linemarker output in -E mode">; def Qn : Flag<["-"], "Qn">; @@ -310,6 +311,11 @@ def fastcp : Flag<["-"], "fastcp">, Group<f_Group>; def fastf : Flag<["-"], "fastf">, Group<f_Group>; def fast : Flag<["-"], "fast">, Group<f_Group>; def fasynchronous_unwind_tables : Flag<["-"], "fasynchronous-unwind-tables">, Group<f_Group>; + +def fautolink : Flag <["-"], "fautolink">, Group<f_Group>; +def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, Flags<[NoForward, CC1Option]>, + HelpText<"Disable generation of linker directives for automatic library linking">; + def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable the 'blocks' language feature">; def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>; @@ -327,9 +333,12 @@ def fcatch_undefined_behavior : Flag<["-"], "fcatch-undefined-behavior">, Group< def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>; def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use colors in diagnostics">; +def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>; +def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, MetaVarName<"<arg>">; +def fparse_all_comments : Flag<["-"], "fparse-all-comments">, Group<f_clang_Group>, Flags<[CC1Option]>; def fcommon : Flag<["-"], "fcommon">, Group<f_Group>; def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>; def fconstant_cfstrings : Flag<["-"], "fconstant-cfstrings">, Group<f_Group>; @@ -403,7 +412,7 @@ def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>, def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>; def fsanitize_address_zero_base_shadow : Flag<["-"], "fsanitize-address-zero-base-shadow">, Group<f_clang_Group>, Flags<[CC1Option]>, - HelpText<"Make AddressSanitizer map shadow memory" + HelpText<"Make AddressSanitizer map shadow memory " "at zero offset">; def fno_sanitize_address_zero_base_shadow : Flag<["-"], "fno-sanitize-address-zero-base-shadow">, Group<f_clang_Group>; @@ -507,10 +516,6 @@ def fmodules_prune_after : Joined<["-"], "fmodules-prune-after=">, Group<i_Group HelpText<"Specify the interval (in seconds) after which a module file will be considered unused">; def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, Flags<[NoForward,CC1Option]>, HelpText<"Enable the 'modules' language feature">; -def fmodules_autolink : Flag <["-"], "fmodules-autolink">, Group<f_Group>, Flags<[NoForward,CC1Option]>, - HelpText<"Enable autolinking of the libraries for imported modules">; -def fno_modules_autolink : Flag <["-"], "fno-modules-autolink">, Group<f_Group>, - HelpText<"Disable autolinking of the libraries for imported modules">; def fmodules_ignore_macro : Joined<["-"], "fmodules-ignore-macro=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Ignore the definition of the given macro when building and loading modules">; def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>; @@ -536,6 +541,7 @@ def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option]> def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>, Flags<[CC1Option]>; def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>; +def fno_diagnostics_color : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>; def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Compile common globals like normal definitions">; def fno_constant_cfstrings : Flag<["-"], "fno-constant-cfstrings">, Group<f_Group>, @@ -699,6 +705,9 @@ def fno_tree_vectorize : Flag<["-"], "fno-tree-vectorize">, Alias<fno_vectorize> def fslp_vectorize : Flag<["-"], "fslp-vectorize">, Group<f_Group>, HelpText<"Enable the superword-level parallelism vectorization passes">; def fno_slp_vectorize : Flag<["-"], "fno-slp-vectorize">, Group<f_Group>; +def fslp_vectorize_aggressive : Flag<["-"], "fslp-vectorize-aggressive">, Group<f_Group>, + HelpText<"Enable the BB vectorization passes">; +def fno_slp_vectorize_aggressive : Flag<["-"], "fno-slp-vectorize-aggressive">, Group<f_Group>; def ftree_slp_vectorize : Flag<["-"], "ftree-slp-vectorize">, Alias<fslp_vectorize>; def fno_tree_slp_vectorize : Flag<["-"], "fno-tree-slp-vectorize">, Alias<fno_slp_vectorize>; def Wlarge_by_value_copy_def : Flag<["-"], "Wlarge-by-value-copy">, @@ -928,6 +937,7 @@ def msoft_float : Flag<["-"], "msoft-float">, Group<m_Group>, Flags<[CC1Option]> HelpText<"Use software floating point">; def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>, HelpText<"Don't generate implicit floating point instructions">; +def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>; def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>; def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>; def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>; @@ -954,12 +964,16 @@ def mprfchw : Flag<["-"], "mprfchw">, Group<m_x86_Features_Group>; def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>; def mips16 : Flag<["-"], "mips16">, Group<m_Group>; def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>; +def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>; +def mno_micromips : Flag<["-"], "mno-micromips">, Group<m_Group>; def mxgot : Flag<["-"], "mxgot">, Group<m_Group>; def mno_xgot : Flag<["-"], "mno-xgot">, Group<m_Group>; def mdsp : Flag<["-"], "mdsp">, Group<m_Group>; def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>; def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>; def mno_dspr2 : Flag<["-"], "mno-dspr2">, Group<m_Group>; +def msingle_float : Flag<["-"], "msingle-float">, Group<m_Group>; +def mdouble_float : Flag<["-"], "mdouble-float">, Group<m_Group>; def mips32 : Flag<["-"], "mips32">, Group<mips_CPUs_Group>, HelpText<"Equivalent to -march=mips32">, Flags<[HelpHidden]>; def mips32r2 : Flag<["-"], "mips32r2">, Group<mips_CPUs_Group>, diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index ae9e397..aae3d79 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -82,6 +82,9 @@ protected: static void addExternCSystemInclude(const ArgList &DriverArgs, ArgStringList &CC1Args, const Twine &Path); + static void addExternCSystemIncludeIfExists(const ArgList &DriverArgs, + ArgStringList &CC1Args, + const Twine &Path); static void addSystemIncludes(const ArgList &DriverArgs, ArgStringList &CC1Args, ArrayRef<StringRef> Paths); @@ -195,9 +198,13 @@ public: /// \brief Test whether this toolchain defaults to PIC. virtual bool isPICDefault() const = 0; - /// \brief Tests whether this toolchain forces its default for PIC or non-PIC. - /// If this returns true, any PIC related flags should be ignored and instead - /// the result of \c isPICDefault() is used exclusively. + /// \brief Test whether this toolchain defaults to PIE. + virtual bool isPIEDefault() const = 0; + + /// \brief Tests whether this toolchain forces its default for PIC, PIE or + /// non-PIC. If this returns true, any PIC related flags should be ignored + /// and instead the results of \c isPICDefault() and \c isPIEDefault() are + /// used exclusively. virtual bool isPICDefaultForced() const = 0; /// SupportsProfiling - Does this tool chain support -pg. diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index d6cc114e..5304dc7 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -57,9 +57,6 @@ struct FormatStyle { /// instead of \c A<A<int>> for LS_Cpp03. LanguageStandard Standard; - /// \brief If \c true, analyze the formatted file for C++03 compatibility. - bool DeriveBackwardsCompatibility; - /// \brief Indent case labels one level from the switch statement. /// /// When false, use the same indentation level as for the switch statement. @@ -91,6 +88,10 @@ struct FormatStyle { /// \brief Add a space in front of an Objective-C protocol list, i.e. use /// Foo <Protocol> instead of Foo<Protocol>. bool ObjCSpaceBeforeProtocolList; + + /// \brief If \c true, aligns escaped newlines as far left as possible. + /// Otherwise puts them into the right-most column. + bool AlignEscapedNewlinesLeft; }; /// \brief Returns a format style complying with the LLVM coding standards: @@ -105,6 +106,10 @@ FormatStyle getGoogleStyle(); /// http://www.chromium.org/developers/coding-style. FormatStyle getChromiumStyle(); +/// \brief Returns a format style complying with Mozilla's style guide: +/// https://developer.mozilla.org/en-US/docs/Developer_Guide/Coding_Style. +FormatStyle getMozillaStyle(); + /// \brief Reformats the given \p Ranges in the token stream coming out of /// \c Lex. /// diff --git a/include/clang/Frontend/ChainedDiagnosticConsumer.h b/include/clang/Frontend/ChainedDiagnosticConsumer.h index ce2b242..b7dc7c7 100644 --- a/include/clang/Frontend/ChainedDiagnosticConsumer.h +++ b/include/clang/Frontend/ChainedDiagnosticConsumer.h @@ -60,12 +60,6 @@ public: Primary->HandleDiagnostic(DiagLevel, Info); Secondary->HandleDiagnostic(DiagLevel, Info); } - - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const { - return new ChainedDiagnosticConsumer(Primary->clone(Diags), - Secondary->clone(Diags)); - } - }; } // end namspace clang diff --git a/include/clang/Frontend/ChainedIncludesSource.h b/include/clang/Frontend/ChainedIncludesSource.h index e14580e..aa30460 100644 --- a/include/clang/Frontend/ChainedIncludesSource.h +++ b/include/clang/Frontend/ChainedIncludesSource.h @@ -26,9 +26,9 @@ public: static ChainedIncludesSource *create(CompilerInstance &CI); -private: ExternalSemaSource &getFinalReader() const { return *FinalReader; } +private: std::vector<CompilerInstance *> CIs; OwningPtr<ExternalSemaSource> FinalReader; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 1c0b9fa..f6e2472 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -28,6 +28,7 @@ CODEGENOPT(Name, Bits, Default) CODEGENOPT(Name, Bits, Default) #endif +CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe. CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files. @@ -120,8 +121,6 @@ VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information ///< in debug info. -CODEGENOPT(ModulesAutolink, 1, 0) ///< Whether to auto-link imported modules - /// The user specified number of registers to be used for integral arguments, /// or 0 if unspecified. VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index d0bbf30..db6b418 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -137,7 +137,7 @@ public: #include "clang/Frontend/CodeGenOptions.def" RelocationModel = "pic"; - memcpy(CoverageVersion, "*204", 4); + memcpy(CoverageVersion, "402*", 4); } }; diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 0d67462..dbd7606 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -427,6 +427,7 @@ public: /// { ASTReader *getModuleManager() const { return ModuleManager; } + void setModuleManager(ASTReader *Reader) { ModuleManager = Reader; } /// } /// @name Code Completion @@ -492,12 +493,8 @@ public: /// /// \param ShouldOwnClient If Client is non-NULL, specifies whether /// the diagnostic object should take ownership of the client. - /// - /// \param ShouldCloneClient If Client is non-NULL, specifies whether that - /// client should be cloned. void createDiagnostics(DiagnosticConsumer *Client = 0, - bool ShouldOwnClient = true, - bool ShouldCloneClient = true); + bool ShouldOwnClient = true); /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. /// @@ -521,7 +518,6 @@ public: createDiagnostics(DiagnosticOptions *Opts, DiagnosticConsumer *Client = 0, bool ShouldOwnClient = true, - bool ShouldCloneClient = true, const CodeGenOptions *CodeGenOpts = 0); /// Create the file manager and replace any existing one with it. diff --git a/include/clang/Frontend/LogDiagnosticPrinter.h b/include/clang/Frontend/LogDiagnosticPrinter.h index 0c700a7..e8a6bb3 100644 --- a/include/clang/Frontend/LogDiagnosticPrinter.h +++ b/include/clang/Frontend/LogDiagnosticPrinter.h @@ -70,8 +70,6 @@ public: virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info); - - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namespace clang diff --git a/include/clang/Frontend/TextDiagnosticBuffer.h b/include/clang/Frontend/TextDiagnosticBuffer.h index 6f1c0e8..93ac299 100644 --- a/include/clang/Frontend/TextDiagnosticBuffer.h +++ b/include/clang/Frontend/TextDiagnosticBuffer.h @@ -45,8 +45,6 @@ public: /// FlushDiagnostics - Flush the buffered diagnostics to an given /// diagnostic engine. void FlushDiagnostics(DiagnosticsEngine &Diags) const; - - virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namspace clang diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index 470438e..dc80470 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -50,7 +50,6 @@ public: void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP); void EndSourceFile(); void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namespace clang diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h index 06a3b24..95d7752 100644 --- a/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -61,6 +61,18 @@ class FileEntry; /// The line number may be absolute (as above), or relative to the current /// line by prefixing the number with either '+' or '-'. /// +/// If the diagnostic is generated in a separate file, for example in a shared +/// header file, it may be beneficial to be able to declare the file in which +/// the diagnostic will appear, rather than placing the expected-* directive in +/// the actual file itself. This can be done using the following syntax: +/// +/// \code +/// // expected-error@path/include.h:15 {{error message}} +/// \endcode +/// +/// The path can be absolute or relative and the same search paths will be used +/// as for #include directives. +/// /// The simple syntax above allows each specification to match exactly one /// error. You can use the extended syntax to customize this. The extended /// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of @@ -254,8 +266,6 @@ public: virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info); - - virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } // end namspace clang diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h new file mode 100644 index 0000000..1fd295e --- /dev/null +++ b/include/clang/Lex/MacroArgs.h @@ -0,0 +1,125 @@ +//===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MacroArgs interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_MACROARGS_H +#define LLVM_CLANG_MACROARGS_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include <vector> + +namespace clang { + class MacroInfo; + class Preprocessor; + class Token; + class SourceLocation; + +/// MacroArgs - An instance of this class captures information about +/// the formal arguments specified to a function-like macro invocation. +class MacroArgs { + /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the + /// arguments. All of the actual argument tokens are allocated immediately + /// after the MacroArgs object in memory. This is all of the arguments + /// concatenated together, with 'EOF' markers at the end of each argument. + unsigned NumUnexpArgTokens; + + /// VarargsElided - True if this is a C99 style varargs macro invocation and + /// there was no argument specified for the "..." argument. If the argument + /// was specified (even empty) or this isn't a C99 style varargs function, or + /// if in strict mode and the C99 varargs macro had only a ... argument, this + /// is false. + bool VarargsElided; + + /// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty + /// if not yet computed. This includes the EOF marker at the end of the + /// stream. + std::vector<std::vector<Token> > PreExpArgTokens; + + /// StringifiedArgs - This contains arguments in 'stringified' form. If the + /// stringified form of an argument has not yet been computed, this is empty. + std::vector<Token> StringifiedArgs; + + /// ArgCache - This is a linked list of MacroArgs objects that the + /// Preprocessor owns which we use to avoid thrashing malloc/free. + MacroArgs *ArgCache; + + MacroArgs(unsigned NumToks, bool varargsElided) + : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(0) {} + ~MacroArgs() {} +public: + /// MacroArgs ctor function - Create a new MacroArgs object with the specified + /// macro and argument info. + static MacroArgs *create(const MacroInfo *MI, + ArrayRef<Token> UnexpArgTokens, + bool VarargsElided, Preprocessor &PP); + + /// destroy - Destroy and deallocate the memory for this object. + /// + void destroy(Preprocessor &PP); + + /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected + /// by pre-expansion, return false. Otherwise, conservatively return true. + bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const; + + /// getUnexpArgument - Return a pointer to the first token of the unexpanded + /// token list for the specified formal. + /// + const Token *getUnexpArgument(unsigned Arg) const; + + /// getArgLength - Given a pointer to an expanded or unexpanded argument, + /// return the number of tokens, not counting the EOF, that make up the + /// argument. + static unsigned getArgLength(const Token *ArgPtr); + + /// getPreExpArgument - Return the pre-expanded form of the specified + /// argument. + const std::vector<Token> & + getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP); + + /// getStringifiedArgument - Compute, cache, and return the specified argument + /// that has been 'stringified' as required by the # operator. + const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP, + SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd); + + /// getNumArguments - Return the number of arguments passed into this macro + /// invocation. + unsigned getNumArguments() const { return NumUnexpArgTokens; } + + + /// isVarargsElidedUse - Return true if this is a C99 style varargs macro + /// invocation and there was no argument specified for the "..." argument. If + /// the argument was specified (even empty) or this isn't a C99 style varargs + /// function, or if in strict mode and the C99 varargs macro had only a ... + /// argument, this returns false. + bool isVarargsElidedUse() const { return VarargsElided; } + + /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of + /// tokens into the literal string token that should be produced by the C # + /// preprocessor operator. If Charify is true, then it should be turned into + /// a character literal for the Microsoft charize (#@) extension. + /// + static Token StringifyArgument(const Token *ArgToks, + Preprocessor &PP, bool Charify, + SourceLocation ExpansionLocStart, + SourceLocation ExpansionLocEnd); + + + /// deallocate - This should only be called by the Preprocessor when managing + /// its freelist. + MacroArgs *deallocate(); +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 1c9c673..dc75f18 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -161,7 +161,7 @@ public: /// \param LangOpts Language options for this translation unit. /// /// \param Target The target for this translation unit. - ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC, + ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC, const LangOptions &LangOpts, const TargetInfo *Target, HeaderSearch &HeaderInfo); @@ -177,7 +177,6 @@ public: void setBuiltinIncludeDir(const DirectoryEntry *Dir) { BuiltinIncludeDir = Dir; } - const DirectoryEntry *getBuiltinIncludeDir() { return BuiltinIncludeDir; } /// \brief Retrieve the module that owns the given header file, if any. /// diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 96359a2..db2ecd2 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -27,6 +27,7 @@ namespace clang { class Token; class IdentifierInfo; class MacroDirective; + class MacroArgs; /// \brief This interface provides a way to observe the actions of the /// preprocessor as it does its thing. @@ -159,10 +160,31 @@ public: const std::string &Str) { } + /// \brief Callback invoked when a \#pragma clang __debug directive is read. + /// \param Loc The location of the debug directive. + /// \param DebugType The identifier following __debug. + virtual void PragmaDebug(SourceLocation Loc, StringRef DebugType) { + } + + /// \brief Determines the kind of \#pragma invoking a call to PragmaMessage. + enum PragmaMessageKind { + /// \brief \#pragma message has been invoked. + PMK_Message, + + /// \brief \#pragma GCC warning has been invoked. + PMK_Warning, + + /// \brief \#pragma GCC error has been invoked. + PMK_Error + }; + /// \brief Callback invoked when a \#pragma message directive is read. /// \param Loc The location of the message directive. + /// \param Namespace The namespace of the message directive. + /// \param Kind The type of the message directive. /// \param Str The text of the message directive. - virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { + virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, + PragmaMessageKind Kind, StringRef Str) { } /// \brief Callback invoked when a \#pragma gcc dianostic push directive @@ -185,7 +207,7 @@ public: /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a /// macro invocation is found. virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range) { + SourceRange Range, const MacroArgs *Args) { } /// \brief Hook called whenever a macro definition is seen. @@ -330,9 +352,10 @@ public: Second->PragmaComment(Loc, Kind, Str); } - virtual void PragmaMessage(SourceLocation Loc, StringRef Str) { - First->PragmaMessage(Loc, Str); - Second->PragmaMessage(Loc, Str); + virtual void PragmaMessage(SourceLocation Loc, StringRef Namespace, + PragmaMessageKind Kind, StringRef Str) { + First->PragmaMessage(Loc, Namespace, Kind, Str); + Second->PragmaMessage(Loc, Namespace, Kind, Str); } virtual void PragmaDiagnosticPush(SourceLocation Loc, @@ -354,9 +377,9 @@ public: } virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range) { - First->MacroExpands(MacroNameTok, MD, Range); - Second->MacroExpands(MacroNameTok, MD, Range); + SourceRange Range, const MacroArgs *Args) { + First->MacroExpands(MacroNameTok, MD, Range, Args); + Second->MacroExpands(MacroNameTok, MD, Range, Args); } virtual void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) { diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index b13b2be..db74352 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -559,7 +559,7 @@ namespace clang { private: virtual void MacroExpands(const Token &Id, const MacroDirective *MD, - SourceRange Range); + SourceRange Range, const MacroArgs *Args); virtual void MacroDefined(const Token &Id, const MacroDirective *MD); virtual void MacroUndefined(const Token &Id, const MacroDirective *MD); virtual void InclusionDirective(SourceLocation HashLoc, diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 7a912ec..c598177 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -397,6 +397,14 @@ private: // Cached tokens state. /// allocation. MacroInfoChain *MICache; + struct DeserializedMacroInfoChain { + MacroInfo MI; + unsigned OwningModuleID; // MUST be immediately after the MacroInfo object + // so it can be accessed by MacroInfo::getOwningModuleID(). + DeserializedMacroInfoChain *Next; + }; + DeserializedMacroInfoChain *DeserialMIChainHead; + public: Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, DiagnosticsEngine &diags, LangOptions &opts, @@ -1444,8 +1452,6 @@ public: void HandlePragmaPoison(Token &PoisonTok); void HandlePragmaSystemHeader(Token &SysHeaderTok); void HandlePragmaDependency(Token &DependencyTok); - void HandlePragmaComment(Token &CommentTok); - void HandlePragmaMessage(Token &MessageTok); void HandlePragmaPushMacro(Token &Tok); void HandlePragmaPopMacro(Token &Tok); void HandlePragmaIncludeAlias(Token &Tok); diff --git a/include/clang/Parse/CMakeLists.txt b/include/clang/Parse/CMakeLists.txt index d1ff2ab..d20708e 100644 --- a/include/clang/Parse/CMakeLists.txt +++ b/include/clang/Parse/CMakeLists.txt @@ -1,3 +1,8 @@ +clang_tablegen(AttrExprArgs.inc -gen-clang-attr-expr-args-list + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + SOURCE ../Basic/Attr.td + TARGET ClangAttrExprArgs) + clang_tablegen(AttrLateParsed.inc -gen-clang-attr-late-parsed-list -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ SOURCE ../Basic/Attr.td diff --git a/include/clang/Parse/Makefile b/include/clang/Parse/Makefile index 296892c..fb63175 100644 --- a/include/clang/Parse/Makefile +++ b/include/clang/Parse/Makefile @@ -1,11 +1,17 @@ CLANG_LEVEL := ../../.. TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrLateParsed.inc +BUILT_SOURCES = AttrExprArgs.inc AttrLateParsed.inc TABLEGEN_INC_FILES_COMMON = 1 include $(CLANG_LEVEL)/Makefile +$(ObjDir)/AttrExprArgs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ + $(ObjDir)/.dir + $(Echo) "Building Clang attribute expression arguments table with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-attr-expr-args-list -o $(call SYSPATH, $@) \ + -I $(PROJ_SRC_DIR)/../../ $< + $(ObjDir)/AttrLateParsed.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ $(ObjDir)/.dir $(Echo) "Building Clang attribute late-parsed table with tblgen" diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 8cc60a2..1029a90 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -149,6 +149,7 @@ class Parser : public CodeCompletionHandler { OwningPtr<PragmaHandler> OpenCLExtensionHandler; OwningPtr<CommentHandler> CommentSemaHandler; OwningPtr<PragmaHandler> OpenMPHandler; + OwningPtr<PragmaHandler> MSCommentHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ @@ -172,6 +173,25 @@ class Parser : public CodeCompletionHandler { /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; + /// \brief RAII class that manages the template parameter depth. + class TemplateParameterDepthRAII { + unsigned &Depth; + unsigned AddedLevels; + public: + explicit TemplateParameterDepthRAII(unsigned &Depth) + : Depth(Depth), AddedLevels(0) {} + + ~TemplateParameterDepthRAII() { + Depth -= AddedLevels; + } + + void operator++() { + ++Depth; + ++AddedLevels; + } + unsigned getDepth() const { return Depth; } + }; + /// Factory object for creating AttributeList objects. AttributeFactory AttrFactory; @@ -422,6 +442,10 @@ private: /// #pragma OPENCL EXTENSION... void HandlePragmaOpenCLExtension(); + /// \brief Handle the annotation token produced for + /// #pragma clang __debug captured + StmtResult HandlePragmaCaptured(); + /// GetLookAheadToken - This peeks ahead N tokens and returns that token /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1) /// returns the token after Tok, etc. @@ -454,19 +478,13 @@ private: /// \brief Read an already-translated primary expression out of an annotation /// token. static ExprResult getExprAnnotation(Token &Tok) { - if (Tok.getAnnotationValue()) - return ExprResult((Expr *)Tok.getAnnotationValue()); - - return ExprResult(true); + return ExprResult::getFromOpaquePointer(Tok.getAnnotationValue()); } /// \brief Set the primary expression corresponding to the given annotation /// token. static void setExprAnnotation(Token &Tok, ExprResult ER) { - if (ER.isInvalid()) - Tok.setAnnotationValue(0); - else - Tok.setAnnotationValue(ER.get()); + Tok.setAnnotationValue(ER.getAsOpaquePointer()); } public: @@ -1204,6 +1222,11 @@ public: // Expr that doesn't include commas. ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast); + ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, + unsigned &NumLineToksConsumed, + void *Info, + bool IsUnevaluated); + private: ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h index 04c04a2..423f066 100644 --- a/include/clang/Rewrite/Frontend/FixItRewriter.h +++ b/include/clang/Rewrite/Frontend/FixItRewriter.h @@ -121,8 +121,6 @@ public: /// \brief Emit a diagnostic via the adapted diagnostic client. void Diag(SourceLocation Loc, unsigned DiagID); - - DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const; }; } diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 0f0d218..d5f3177 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -96,6 +96,10 @@ private: /// type_tag_for_datatype attribute. unsigned IsTypeTagForDatatype : 1; + /// True if this has extra information associated with a + /// Microsoft __delcspec(property) attribute. + unsigned IsProperty : 1; + unsigned AttrKind : 8; /// \brief The location of the 'unavailable' keyword in an @@ -134,6 +138,11 @@ public: unsigned LayoutCompatible : 1; unsigned MustBeNull : 1; }; + struct PropertyData { + IdentifierInfo *GetterId, *SetterId; + PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId) + : GetterId(getterId), SetterId(setterId) {} + }; private: TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { @@ -152,6 +161,16 @@ private: return *reinterpret_cast<const ParsedType *>(this + 1); } + PropertyData &getPropertyDataBuffer() { + assert(IsProperty); + return *reinterpret_cast<PropertyData*>(this + 1); + } + + const PropertyData &getPropertyDataBuffer() const { + assert(IsProperty); + return *reinterpret_cast<const PropertyData*>(this + 1); + } + AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION; void operator=(const AttributeList &) LLVM_DELETED_FUNCTION; void operator delete(void *) LLVM_DELETED_FUNCTION; @@ -169,7 +188,8 @@ private: AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) { + IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), + NextInPool(0) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -188,7 +208,7 @@ private: AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), - IsTypeTagForDatatype(false), + IsTypeTagForDatatype(false), IsProperty(false), UnavailableLoc(unavailable), MessageExpr(messageExpr), NextInPosition(0), NextInPool(0) { new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); @@ -208,7 +228,8 @@ private: AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) { + IsTypeTagForDatatype(true), IsProperty(false), NextInPosition(NULL), + NextInPool(NULL) { TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); new (&ExtraData.MatchingCType) ParsedType(matchingCType); ExtraData.LayoutCompatible = layoutCompatible; @@ -225,11 +246,28 @@ private: AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) { + IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), + NextInPool(0) { new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } + /// Constructor for microsoft __declspec(property) attribute. + AttributeList(IdentifierInfo *attrName, SourceRange attrRange, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierInfo *getterId, IdentifierInfo *setterId, + Syntax syntaxUsed) + : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), + AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + SyntaxUsed(syntaxUsed), + Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), + IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0), + NextInPool(0) { + new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); + AttrKind = getKind(getName(), getScopeName(), syntaxUsed); + } + friend class AttributePool; friend class AttributeFactory; @@ -253,6 +291,11 @@ public: IdentifierInfo *getParameterName() const { return ParmName; } SourceLocation getParameterLoc() const { return ParmLoc; } + /// Is this the Microsoft __declspec(property) attribute? + bool isDeclspecPropertyAttribute() const { + return IsProperty; + } + bool isAlignasAttribute() const { // FIXME: Use a better mechanism to determine this. return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword; @@ -379,6 +422,11 @@ public: return getTypeBuffer(); } + const PropertyData &getPropertyData() const { + assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute"); + return getPropertyDataBuffer(); + } + /// \brief Get an index into the attribute spelling list /// defined in Attr.td. This index is used by an attribute /// to pretty print itself. @@ -402,6 +450,10 @@ public: TypeTagForDatatypeAllocSize = sizeof(AttributeList) + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1) + / sizeof(void*) * sizeof(void*), + PropertyAllocSize = + sizeof(AttributeList) + + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1) / sizeof(void*) * sizeof(void*) }; @@ -548,6 +600,20 @@ public: parmName, parmLoc, typeArg, syntaxUsed)); } + + AttributeList *createPropertyAttribute( + IdentifierInfo *attrName, SourceRange attrRange, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierInfo *getterId, IdentifierInfo *setterId, + AttributeList::Syntax syntaxUsed) { + void *memory = allocate(AttributeFactory::PropertyAllocSize); + return add(new (memory) AttributeList(attrName, attrRange, + scopeName, scopeLoc, + parmName, parmLoc, + getterId, setterId, + syntaxUsed)); + } }; /// addAttributeLists - Add two AttributeLists together @@ -703,6 +769,21 @@ public: return attr; } + /// Add microsoft __delspec(property) attribute. + AttributeList * + addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierInfo *getterId, IdentifierInfo *setterId, + AttributeList::Syntax syntaxUsed) { + AttributeList *attr = + pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, + parmName, parmLoc, getterId, setterId, + syntaxUsed); + add(attr); + return attr; + } + AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name, SourceLocation loc, int arg) { AttributeList *attr = diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 5b90784..059919a 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -227,6 +227,14 @@ public: SCS_mutable }; + // Import thread storage class specifier enumeration and constants. + // These can be combined with SCS_extern and SCS_static. + typedef ThreadStorageClassSpecifier TSCS; + static const TSCS TSCS_unspecified = clang::TSCS_unspecified; + static const TSCS TSCS___thread = clang::TSCS___thread; + static const TSCS TSCS_thread_local = clang::TSCS_thread_local; + static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local; + // Import type specifier width enumeration and constants. typedef TypeSpecifierWidth TSW; static const TSW TSW_unspecified = clang::TSW_unspecified; @@ -272,6 +280,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_decltype_auto = clang::TST_decltype_auto; 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; @@ -310,7 +319,7 @@ public: private: // storage-class-specifier /*SCS*/unsigned StorageClassSpec : 3; - unsigned SCS_thread_specified : 1; + /*TSCS*/unsigned ThreadStorageClassSpec : 2; unsigned SCS_extern_in_linkage_spec : 1; // type-specifier @@ -362,7 +371,7 @@ private: // the setting was synthesized. SourceRange Range; - SourceLocation StorageClassSpecLoc, SCS_threadLoc; + SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc; SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc; /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, /// typename, then this is the location of the named type (if present); @@ -398,7 +407,7 @@ public: DeclSpec(AttributeFactory &attrFactory) : StorageClassSpec(SCS_unspecified), - SCS_thread_specified(false), + ThreadStorageClassSpec(TSCS_unspecified), SCS_extern_in_linkage_spec(false), TypeSpecWidth(TSW_unspecified), TypeSpecComplex(TSC_unspecified), @@ -428,21 +437,25 @@ public: } // storage-class-specifier SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } - bool isThreadSpecified() const { return SCS_thread_specified; } + TSCS getThreadStorageClassSpec() const { + return (TSCS)ThreadStorageClassSpec; + } bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; } void setExternInLinkageSpec(bool Value) { SCS_extern_in_linkage_spec = Value; } SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; } - SourceLocation getThreadSpecLoc() const { return SCS_threadLoc; } + SourceLocation getThreadStorageClassSpecLoc() const { + return ThreadStorageClassSpecLoc; + } void ClearStorageClassSpecs() { - StorageClassSpec = DeclSpec::SCS_unspecified; - SCS_thread_specified = false; + StorageClassSpec = DeclSpec::SCS_unspecified; + ThreadStorageClassSpec = DeclSpec::TSCS_unspecified; SCS_extern_in_linkage_spec = false; - StorageClassSpecLoc = SourceLocation(); - SCS_threadLoc = SourceLocation(); + StorageClassSpecLoc = SourceLocation(); + ThreadStorageClassSpecLoc = SourceLocation(); } // type-specifier @@ -487,6 +500,10 @@ public: SourceRange getTypeofParensRange() const { return TypeofParensRange; } void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } + bool containsPlaceholderType() const { + return TypeSpecType == TST_auto || TypeSpecType == TST_decltype_auto; + } + /// \brief Turn a type-specifier-type into a string like "_Bool" or "union". static const char *getSpecifierName(DeclSpec::TST T); static const char *getSpecifierName(DeclSpec::TQ Q); @@ -494,6 +511,7 @@ public: static const char *getSpecifierName(DeclSpec::TSC C); static const char *getSpecifierName(DeclSpec::TSW W); static const char *getSpecifierName(DeclSpec::SCS S); + static const char *getSpecifierName(DeclSpec::TSCS S); // type-qualifiers @@ -570,8 +588,8 @@ public: /// diagnostics to be ignored when desired. bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); - bool SetStorageClassSpecThread(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID); + bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, + const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, @@ -1480,8 +1498,9 @@ public: CXXNewContext, // C++ new-expression. CXXCatchContext, // C++ catch exception-declaration ObjCCatchContext, // Objective-C catch exception-declaration - BlockLiteralContext, // Block literal declarator. + BlockLiteralContext, // Block literal declarator. LambdaExprContext, // Lambda-expression declarator. + ConversionIdContext, // C++ conversion-type-id. TrailingReturnContext, // C++11 trailing-type-specifier. TemplateTypeArgContext, // Template type argument. AliasDeclContext, // C++11 alias-declaration. @@ -1657,6 +1676,7 @@ public: case ObjCCatchContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return true; @@ -1689,6 +1709,7 @@ public: case ObjCResultContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return false; @@ -1738,6 +1759,7 @@ public: case AliasTemplateContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return false; @@ -1920,6 +1942,7 @@ public: case ObjCCatchContext: case BlockLiteralContext: case LambdaExprContext: + case ConversionIdContext: case TemplateTypeArgContext: case TrailingReturnContext: return false; diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 8459be1..58781ac 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -75,7 +75,10 @@ public: EK_ComplexElement, /// \brief The entity being initialized is the field that captures a /// variable in a lambda. - EK_LambdaCapture + EK_LambdaCapture, + /// \brief The entity being initialized is the initializer for a compound + /// literal. + EK_CompoundLiteralInit }; private: @@ -118,8 +121,8 @@ private: /// low bit indicating whether the parameter is "consumed". uintptr_t Parameter; - /// \brief When Kind == EK_Temporary, the type source information for - /// the temporary. + /// \brief When Kind == EK_Temporary or EK_CompoundLiteralInit, the type + /// source information for the temporary. TypeSourceInfo *TypeInfo; struct LN LocAndNRVO; @@ -287,7 +290,16 @@ public: SourceLocation Loc) { return InitializedEntity(Var, Field, Loc); } - + + /// \brief Create the entity for a compound literal initializer. + static InitializedEntity InitializeCompoundLiteralInit(TypeSourceInfo *TSI) { + InitializedEntity Result(EK_CompoundLiteralInit, SourceLocation(), + TSI->getType()); + Result.TypeInfo = TSI; + return Result; + } + + /// \brief Determine the kind of initialization. EntityKind getKind() const { return Kind; } @@ -302,7 +314,7 @@ public: /// \brief Retrieve complete type-source information for the object being /// constructed, if known. TypeSourceInfo *getTypeSourceInfo() const { - if (Kind == EK_Temporary) + if (Kind == EK_Temporary || Kind == EK_CompoundLiteralInit) return TypeInfo; return 0; @@ -594,6 +606,8 @@ public: SK_QualificationConversionXValue, /// \brief Perform a qualification conversion, producing an lvalue. SK_QualificationConversionLValue, + /// \brief Perform a load from a glvalue, producing an rvalue. + SK_LValueToRValue, /// \brief Perform an implicit conversion sequence. SK_ConversionSequence, /// \brief Perform list-initialization without a constructor @@ -777,13 +791,10 @@ public: /// \param Kind the kind of initialization being performed. /// /// \param Args the argument(s) provided for initialization. - /// - /// \param NumArgs the number of arguments provided for initialization. InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, - Expr **Args, - unsigned NumArgs); + MultiExprArg Args); ~InitializationSequence(); @@ -821,7 +832,7 @@ public: bool Diagnose(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, - Expr **Args, unsigned NumArgs); + ArrayRef<Expr *> Args); /// \brief Determine the kind of initialization sequence computed. enum SequenceKind getKind() const { return SequenceKind; } @@ -911,6 +922,12 @@ public: void AddQualificationConversionStep(QualType Ty, ExprValueKind Category); + /// \brief Add a new step that performs a load of the given type. + /// + /// Although the term "LValueToRValue" is conventional, this applies to both + /// lvalues and xvalues. + void AddLValueToRValueStep(QualType Ty); + /// \brief Add a new step that applies an implicit conversion sequence. void AddConversionSequenceStep(const ImplicitConversionSequence &ICS, QualType T); diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h index 225c137..94e3807 100644 --- a/include/clang/Sema/ObjCMethodList.h +++ b/include/clang/Sema/ObjCMethodList.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H #define LLVM_CLANG_SEMA_OBJC_METHOD_LIST_H +#include "llvm/ADT/PointerIntPair.h" + namespace clang { class ObjCMethodDecl; @@ -21,16 +23,17 @@ class ObjCMethodDecl; /// ObjCMethodList - a linked list of methods with different signatures. struct ObjCMethodList { ObjCMethodDecl *Method; - ObjCMethodList *Next; - - ObjCMethodList() { - Method = 0; - Next = 0; - } - ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) { - Method = M; - Next = C; - } + /// \brief The next list object and 2 bits for extra info. + llvm::PointerIntPair<ObjCMethodList *, 2> NextAndExtraBits; + + ObjCMethodList() : Method(0) { } + ObjCMethodList(ObjCMethodDecl *M, ObjCMethodList *C) + : Method(M), NextAndExtraBits(C, 0) { } + + ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); } + unsigned getBits() const { return NextAndExtraBits.getInt(); } + void setNext(ObjCMethodList *L) { NextAndExtraBits.setPointer(L); } + void setBits(unsigned B) { NextAndExtraBits.setInt(B); } }; } diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index e064b91..c3d1f4e 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -207,6 +207,15 @@ namespace clang { assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); return *this; } + + // For types where we can fit a flag in with the pointer, provide + // conversions to/from pointer type. + static ActionResult getFromOpaquePointer(void *P) { + ActionResult Result; + Result.PtrWithInvalid = (uintptr_t)P; + return Result; + } + void *getAsOpaquePointer() const { return (void*)PtrWithInvalid; } }; /// An opaque type for threading parsed type information through the diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 2295bf4..b232b59 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_SEMA_SCOPE_INFO_H #include "clang/AST/Type.h" +#include "clang/Basic/CapturedStmt.h" #include "clang/Basic/PartialDiagnostic.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -24,9 +25,11 @@ namespace clang { class Decl; class BlockDecl; +class CapturedDecl; class CXXMethodDecl; class ObjCPropertyDecl; class IdentifierInfo; +class ImplicitParamDecl; class LabelDecl; class ReturnStmt; class Scope; @@ -73,7 +76,8 @@ protected: enum ScopeKind { SK_Function, SK_Block, - SK_Lambda + SK_Lambda, + SK_CapturedRegion }; public: @@ -319,7 +323,8 @@ public: class CapturingScopeInfo : public FunctionScopeInfo { public: enum ImplicitCaptureStyle { - ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block + ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, + ImpCap_CapturedRegion }; ImplicitCaptureStyle ImpCaptureStyle; @@ -461,7 +466,8 @@ public: } static bool classof(const FunctionScopeInfo *FSI) { - return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda; + return FSI->Kind == SK_Block || FSI->Kind == SK_Lambda + || FSI->Kind == SK_CapturedRegion; } }; @@ -492,6 +498,46 @@ public: } }; +/// \brief Retains information about a captured region. +class CapturedRegionScopeInfo: public CapturingScopeInfo { +public: + /// \brief The CapturedDecl for this statement. + CapturedDecl *TheCapturedDecl; + /// \brief The captured record type. + RecordDecl *TheRecordDecl; + /// \brief This is the enclosing scope of the captured region. + Scope *TheScope; + /// \brief The implicit parameter for the captured variables. + ImplicitParamDecl *ContextParam; + /// \brief The kind of captured region. + CapturedRegionKind CapRegionKind; + + CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, + RecordDecl *RD, ImplicitParamDecl *Context, + CapturedRegionKind K) + : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), + TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), + ContextParam(Context), CapRegionKind(K) + { + Kind = SK_CapturedRegion; + } + + virtual ~CapturedRegionScopeInfo(); + + /// \brief A descriptive name for the kind of captured region this is. + StringRef getRegionName() const { + switch (CapRegionKind) { + case CR_Default: + return "default captured statement"; + } + llvm_unreachable("Invalid captured region kind!"); + } + + static bool classof(const FunctionScopeInfo *FSI) { + return FSI->Kind == SK_CapturedRegion; + } +}; + class LambdaScopeInfo : public CapturingScopeInfo { public: /// \brief The class that describes the lambda. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 5b93e51..d7c80f2 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -37,6 +37,7 @@ #include "clang/Sema/LocInfoType.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Ownership.h" +#include "clang/Sema/ScopeInfo.h" #include "clang/Sema/TypoCorrection.h" #include "clang/Sema/Weak.h" #include "llvm/ADT/ArrayRef.h" @@ -45,6 +46,7 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCParser/MCAsmParser.h" #include <deque> #include <string> @@ -65,6 +67,7 @@ namespace clang { class ArrayType; class AttributeList; class BlockDecl; + class CapturedDecl; class CXXBasePath; class CXXBasePaths; class CXXBindTemporaryExpr; @@ -174,6 +177,7 @@ namespace clang { namespace sema { class AccessedEntity; class BlockScopeInfo; + class CapturedRegionScopeInfo; class CapturingScopeInfo; class CompoundScopeInfo; class DelayedDiagnostic; @@ -203,6 +207,17 @@ class Sema { static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); + static bool + shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, const NamedDecl *New) { + // We are about to link these. It is now safe to compute the linkage of + // the new decl. If the new decl has external linkage, we will + // link it with the hidden decl (which also has external linkage) and + // it will keep having external linkage. If it has internal linkage, we + // will not link it. Since it has no previous decls, it will remain + // with internal linkage. + return !Old->isHidden() || New->hasExternalLinkage(); + } + public: typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; typedef OpaquePtr<TemplateName> TemplateTy; @@ -585,6 +600,10 @@ public: /// have been declared. bool GlobalNewDeleteDeclared; + /// A flag to indicate that we're in a context that permits abstract + /// references to fields. This is really a + bool AllowAbstractFieldReference; + /// \brief Describes how the expressions currently being parsed are /// evaluated at run-time, if at all. enum ExpressionEvaluationContext { @@ -595,6 +614,11 @@ public: /// run time. Unevaluated, + /// \brief The current expression occurs within an unevaluated + /// operand that unconditionally permits abstract references to + /// fields, such as a SIZE operator in MS-style inline assembly. + UnevaluatedAbstract, + /// \brief The current context is "potentially evaluated" in C++11 terms, /// but the expression is evaluated at compile-time (like the values of /// cases in a switch statment). @@ -674,6 +698,10 @@ public: LambdaMangle = new LambdaMangleContext; return *LambdaMangle; } + + bool isUnevaluated() const { + return Context == Unevaluated || Context == UnevaluatedAbstract; + } }; /// A stack of expression evaluation contexts. @@ -756,6 +784,8 @@ public: /// We need to maintain a list, since selectors can have differing signatures /// across classes. In Cocoa, this happens to be extremely uncommon (only 1% /// of selectors are "overloaded"). + /// At the head of the list it is recorded whether there were 0, 1, or >= 2 + /// methods inside categories with a particular selector. GlobalMethodPool MethodPool; /// Method selectors used in a \@selector expression. Used for implementation @@ -804,6 +834,9 @@ public: bool OldFPContractState : 1; }; + typedef llvm::MCAsmParserSemaCallback::InlineAsmIdentifierInfo + InlineAsmIdentifierInfo; + public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind = TU_Complete, @@ -905,6 +938,9 @@ public: void PushFunctionScope(); void PushBlockScope(Scope *BlockScope, BlockDecl *Block); void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator); + void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, + RecordDecl *RD, + CapturedRegionKind K); void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0, const Decl *D = 0, const BlockExpr *blkExpr = 0); @@ -925,6 +961,9 @@ public: /// \brief Retrieve the current lambda expression, if any. sema::LambdaScopeInfo *getCurLambda(); + /// \brief Retrieve the current captured region, if any. + sema::CapturedRegionScopeInfo *getCurCapturedRegion(); + /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls SmallVector<Decl*,2> &WeakTopLevelDecls() { return WeakTopLevelDecl; } @@ -1222,7 +1261,7 @@ public: bool isSimpleTypeSpecifier(tok::TokenKind Kind) const; - ParsedType getTypeName(IdentifierInfo &II, SourceLocation NameLoc, + ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS = 0, bool isClassName = false, bool HasTrailingDot = false, @@ -1374,6 +1413,7 @@ public: MultiTemplateParamsArg TemplateParamLists); // Returns true if the variable declaration is a redeclaration bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous); + void CheckVariableDeclarationType(VarDecl *NewVD); void CheckCompleteVariableDeclaration(VarDecl *var); void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D); void ActOnStartFunctionDeclarator(); @@ -1575,6 +1615,12 @@ public: Declarator &D, Expr *BitfieldWidth, InClassInitStyle InitStyle, AccessSpecifier AS); + MSPropertyDecl *HandleMSProperty(Scope *S, RecordDecl *TagD, + SourceLocation DeclStart, + Declarator &D, Expr *BitfieldWidth, + InClassInitStyle InitStyle, + AccessSpecifier AS, + AttributeList *MSPropertyAttr); FieldDecl *CheckFieldDecl(DeclarationName Name, QualType T, TypeSourceInfo *TInfo, @@ -1649,7 +1695,7 @@ public: SourceLocation EqualLoc, Expr *Val); void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, Decl *EnumDecl, - Decl **Elements, unsigned NumElements, + ArrayRef<Decl *> Elements, Scope *S, AttributeList *Attr); DeclContext *getContainingDC(DeclContext *DC); @@ -1849,7 +1895,7 @@ public: bool IsNoReturnConversion(QualType FromType, QualType ToType, QualType &ResultTy); bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType); - + bool isSameOrCompatibleFunctionType(CanQualType Param, CanQualType Arg); ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, const VarDecl *NRVOCandidate, @@ -1979,7 +2025,7 @@ public: void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversion = false); void AddMethodCandidate(CXXMethodDecl *Method, @@ -2021,18 +2067,16 @@ public: Expr *Object, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet); void AddMemberOperatorCandidates(OverloadedOperatorKind Op, - SourceLocation OpLoc, - Expr **Args, unsigned NumArgs, + SourceLocation OpLoc, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, SourceRange OpRange = SourceRange()); void AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator = false, unsigned NumContextualBoolArguments = 0); void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, - SourceLocation OpLoc, - Expr **Args, unsigned NumArgs, + SourceLocation OpLoc, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet); void AddArgumentDependentLookupCandidates(DeclarationName Name, bool Operator, SourceLocation Loc, @@ -2443,8 +2487,7 @@ public: /// DiagnoseUnimplementedProperties - This routine warns on those properties /// which must be implemented by this implementation. void DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, - ObjCContainerDecl *CDecl, - const SelectorSet &InsMap); + ObjCContainerDecl *CDecl); /// DefaultSynthesizeProperties - This routine default synthesizes all /// properties which must be synthesized in the class's \@implementation. @@ -2750,6 +2793,13 @@ public: StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope); StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); + void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, + CapturedRegionKind Kind, unsigned NumParams); + StmtResult ActOnCapturedRegionEnd(Stmt *S); + void ActOnCapturedRegionError(); + RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, + SourceLocation Loc, + unsigned NumParams); const VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, bool AllowFunctionParameters); @@ -2763,13 +2813,21 @@ public: Expr *AsmString, MultiExprArg Clobbers, SourceLocation RParenLoc); - NamedDecl *LookupInlineAsmIdentifier(StringRef Name, SourceLocation Loc, - unsigned &Length, unsigned &Size, - unsigned &Type, bool &IsVarDecl); + ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, + SourceLocation TemplateKWLoc, + UnqualifiedId &Id, + InlineAsmIdentifierInfo &Info, + bool IsUnevaluatedContext); bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc); StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, - ArrayRef<Token> AsmToks, SourceLocation EndLoc); + ArrayRef<Token> AsmToks, + StringRef AsmString, + unsigned NumOutputs, unsigned NumInputs, + ArrayRef<StringRef> Constraints, + ArrayRef<StringRef> Clobbers, + ArrayRef<Expr*> Exprs, + SourceLocation EndLoc); VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, @@ -3006,7 +3064,7 @@ public: bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, CorrectionCandidateCallback &CCC, TemplateArgumentListInfo *ExplicitTemplateArgs = 0, - ArrayRef<Expr *> Args = ArrayRef<Expr *>()); + ArrayRef<Expr *> Args = None); ExprResult LookupInObjCMethod(LookupResult &LookUp, Scope *S, IdentifierInfo *II, @@ -3542,7 +3600,7 @@ public: const QualType *data() const { return Exceptions.data(); } /// \brief Integrate another called method into the collected data. - void CalledDecl(SourceLocation CallLoc, CXXMethodDecl *Method); + void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method); /// \brief Integrate an invoked expression into the collected data. void CalledExpr(Expr *E); @@ -3606,7 +3664,7 @@ public: /// \brief Determine what sort of exception specification an inheriting /// constructor of a class will have. ImplicitExceptionSpecification - ComputeInheritingCtorExceptionSpec(CXXMethodDecl *MD); + ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD); /// \brief Evaluate the implicit exception specification for a defaulted /// special member function. @@ -4450,8 +4508,7 @@ public: CXXCtorInitializer *Initializer); bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, - ArrayRef<CXXCtorInitializer *> Initializers = - ArrayRef<CXXCtorInitializer *>()); + ArrayRef<CXXCtorInitializer *> Initializers = None); void SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation); @@ -5582,7 +5639,8 @@ public: TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ArgFunctionType, FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info); + sema::TemplateDeductionInfo &Info, + bool InOverloadResolution = false); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, @@ -5594,7 +5652,8 @@ public: DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo *ExplicitTemplateArgs, FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info); + sema::TemplateDeductionInfo &Info, + bool InOverloadResolution = false); /// \brief Result type of DeduceAutoType. enum DeduceAutoResult { @@ -5604,8 +5663,17 @@ public: }; DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, - TypeSourceInfo *&Result); + QualType &Result); + DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, + QualType &Result); + QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement); void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); + bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, + bool Diagnose = true); + + bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, + SourceLocation ReturnLoc, + Expr *&RetExpr, AutoType *AT); FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, @@ -5958,7 +6026,7 @@ public: bool isUnevaluatedContext() const { assert(!ExprEvalContexts.empty() && "Must be in an expression evaluation context"); - return ExprEvalContexts.back().Context == Sema::Unevaluated; + return ExprEvalContexts.back().isUnevaluated(); } /// \brief RAII class used to determine whether SFINAE has @@ -7316,7 +7384,7 @@ private: bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto); bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, - Expr **Args, unsigned NumArgs); + ArrayRef<const Expr *> Args); bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall, const FunctionProtoType *Proto); void CheckConstructorCall(FunctionDecl *FDecl, diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 492e580..f9481c6 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -40,10 +40,9 @@ namespace clang { /// list will contain a template argument list (int) at depth 0 and a /// template argument list (17) at depth 1. class MultiLevelTemplateArgumentList { - public: - typedef std::pair<const TemplateArgument *, unsigned> ArgList; - - private: + /// \brief The template argument list at a certain template depth + typedef ArrayRef<TemplateArgument> ArgList; + /// \brief The template argument lists, stored from the innermost template /// argument list (first) to the outermost template argument list (last). SmallVector<ArgList, 4> TemplateArgumentLists; @@ -65,8 +64,8 @@ namespace clang { /// \brief Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { assert(Depth < TemplateArgumentLists.size()); - assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second); - return TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index]; + assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); + return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; } /// \brief Determine whether there is a non-NULL template argument at the @@ -76,7 +75,7 @@ namespace clang { bool hasTemplateArgument(unsigned Depth, unsigned Index) const { assert(Depth < TemplateArgumentLists.size()); - if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].second) + if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) return false; return !(*this)(Depth, Index).isNull(); @@ -86,26 +85,32 @@ namespace clang { void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg) { assert(Depth < TemplateArgumentLists.size()); - assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].second); + assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); const_cast<TemplateArgument&>( - TemplateArgumentLists[getNumLevels() - Depth - 1].first[Index]) + TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) = Arg; } /// \brief Add a new outermost level to the multi-level template argument /// list. void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { - TemplateArgumentLists.push_back(ArgList(TemplateArgs->data(), - TemplateArgs->size())); + addOuterTemplateArguments(ArgList(TemplateArgs->data(), + TemplateArgs->size())); } /// \brief Add a new outmost level to the multi-level template argument /// list. void addOuterTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) { - TemplateArgumentLists.push_back(ArgList(Args, NumArgs)); + addOuterTemplateArguments(ArgList(Args, NumArgs)); } - + + /// \brief Add a new outmost level to the multi-level template argument + /// list. + void addOuterTemplateArguments(ArgList Args) { + TemplateArgumentLists.push_back(Args); + } + /// \brief Retrieve the innermost template argument list. const ArgList &getInnermost() const { return TemplateArgumentLists.front(); @@ -187,10 +192,10 @@ namespace clang { /// this template instantiation. Sema &SemaRef; - typedef llvm::DenseMap<const Decl *, - llvm::PointerUnion<Decl *, DeclArgumentPack *> > - LocalDeclsMap; - + typedef llvm::SmallDenseMap< + const Decl *, llvm::PointerUnion<Decl *, DeclArgumentPack *>, 4> + LocalDeclsMap; + /// \brief A mapping from local declarations that occur /// within a template to their instantiations. /// @@ -401,6 +406,7 @@ namespace clang { Decl *VisitVarDecl(VarDecl *D); Decl *VisitAccessSpecDecl(AccessSpecDecl *D); Decl *VisitFieldDecl(FieldDecl *D); + Decl *VisitMSPropertyDecl(MSPropertyDecl *D); Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D); Decl *VisitStaticAssertDecl(StaticAssertDecl *D); Decl *VisitEnumDecl(EnumDecl *D); diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 3abb8f1..8292045 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -157,8 +157,8 @@ public: /// \brief The expression which caused a deduction failure. /// /// TDK_FailedOverloadResolution: this argument is the reference to - // an overloaded function which could not be resolved to a specific - // function. + /// an overloaded function which could not be resolved to a specific + /// function. Expr *Expression; }; diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 9b685ba..81f8980 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -951,6 +951,8 @@ namespace clang { DECL_OBJC_PROPERTY_IMPL, /// \brief A FieldDecl record. DECL_FIELD, + /// \brief A MSPropertyDecl record. + DECL_MS_PROPERTY, /// \brief A VarDecl record. DECL_VAR, /// \brief An ImplicitParamDecl record. @@ -961,6 +963,8 @@ namespace clang { DECL_FILE_SCOPE_ASM, /// \brief A BlockDecl record. DECL_BLOCK, + /// \brief A CapturedDecl record. + DECL_CAPTURED, /// \brief A record that stores the set of declarations that are /// lexically stored within a given DeclContext. /// @@ -1101,6 +1105,8 @@ namespace clang { STMT_RETURN, /// \brief A DeclStmt record. STMT_DECL, + /// \brief A CapturedStmt record. + STMT_CAPTURED, /// \brief A GCC-style AsmStmt record. STMT_GCCASM, /// \brief A MS-style AsmStmt record. @@ -1261,6 +1267,7 @@ namespace clang { EXPR_CXX_THIS, // CXXThisExpr EXPR_CXX_THROW, // CXXThrowExpr EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr + EXPR_CXX_DEFAULT_INIT, // CXXDefaultInitExpr EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr @@ -1300,6 +1307,7 @@ namespace clang { EXPR_ASTYPE, // AsTypeExpr // Microsoft + EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). STMT_SEH_EXCEPT, // SEHExceptStmt diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 9255336..2c0102e 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -172,6 +172,16 @@ public: /// \brief Receives __COUNTER__ value. virtual void ReadCounter(const serialization::ModuleFile &M, unsigned Value) {} + + /// \brief Returns true if this \c ASTReaderListener wants to receive the + /// input files of the AST file via \c visitInputFile, false otherwise. + virtual bool needsInputFileVisitation() { return false; } + + /// \brief if \c needsInputFileVisitation returns true, this is called for each + /// input file of the AST file. + /// + /// \returns true to continue receiving the next input file, false to stop. + virtual bool visitInputFile(StringRef Filename, bool isSystem) { return true;} }; /// \brief ASTReaderListener implementation to validate the information of @@ -1106,6 +1116,8 @@ private: void finishPendingActions(); + void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); + void addPendingDeclContextInfo(Decl *D, serialization::GlobalDeclID SemaDC, serialization::GlobalDeclID LexicalDC) { @@ -1558,7 +1570,7 @@ public: /// \brief Retrieve an iterator into the set of all identifiers /// in all loaded AST files. - virtual IdentifierIterator *getIdentifiers() const; + virtual IdentifierIterator *getIdentifiers(); /// \brief Load the contents of the global method pool for a given /// selector. @@ -1800,6 +1812,9 @@ public: /// \brief Reads a sub-expression operand during statement reading. Expr *ReadSubExpr(); + /// \brief Reads a token out of a record. + Token ReadToken(ModuleFile &M, const RecordData &Record, unsigned &Idx); + /// \brief Reads the macro record located at the given offset. MacroInfo *ReadMacroRecord(ModuleFile &F, uint64_t Offset); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 2938dc7..8ac8fde 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -63,6 +63,7 @@ class Sema; class SourceManager; class SwitchCase; class TargetInfo; +class Token; class VersionTuple; class ASTUnresolvedSet; @@ -498,6 +499,9 @@ public: Module *WritingModule, StringRef isysroot, bool hasErrors = false); + /// \brief Emit a token. + void AddToken(const Token &Tok, RecordDataImpl &Record); + /// \brief Emit a source location. void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record); diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h index eaf26d1..ab91f40 100644 --- a/include/clang/Serialization/GlobalModuleIndex.h +++ b/include/clang/Serialization/GlobalModuleIndex.h @@ -146,6 +146,11 @@ public: static std::pair<GlobalModuleIndex *, ErrorCode> readIndex(StringRef Path); + /// \brief Returns an iterator for identifiers stored in the index table. + /// + /// The caller accepts ownership of the returned object. + IdentifierIterator *createIdentifierIterator() const; + /// \brief Retrieve the set of modules that have up-to-date indexes. /// /// \param ModuleFiles Will be populated with the set of module files that diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 6dbdbbf..fb35f51 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -232,6 +232,7 @@ private: /// \sa getMaxNodesPerTopLevelFunction Optional<unsigned> MaxNodesPerTopLevelFunction; +public: /// Interprets an option's string value as a boolean. /// /// Accepts the strings "true" and "false". @@ -244,7 +245,6 @@ private: /// Interprets an option's string value as an integer value. int getOptionAsInteger(StringRef Name, int DefaultVal); -public: /// \brief Retrieves and sets the UserMode. This is a high-level option, /// which is used to set other low-level options. It is not accessible /// outside of AnalyzerOptions. diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 7a87e47..5c560b2 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -406,11 +406,6 @@ private: /// A vector of BugReports for tracking the allocated pointers and cleanup. std::vector<BugReportEquivClass *> EQClassesVector; - /// A map from PathDiagnosticPiece to the LocationContext of the inlined - /// function call it represents. - llvm::DenseMap<const PathDiagnosticCallPiece*, - const LocationContext*> LocationContextMap; - protected: BugReporter(BugReporterData& d, Kind k) : BugTypes(F.getEmptySet()), kind(k), D(d) {} @@ -482,10 +477,6 @@ public: EmitBasicReport(DeclWithIssue, BugName, Category, BugStr, Loc, &R, 1); } - void addCallPieceLocationContextPair(const PathDiagnosticCallPiece *C, - const LocationContext *LC) { - LocationContextMap[C] = LC; - } private: llvm::StringMap<BugType *> StrBugTypes; diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index 2e5f207..2e67180 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -134,10 +134,15 @@ class TrackConstraintBRVisitor bool IsSatisfied; bool IsZeroCheck; + /// We should start tracking from the last node along the path in which the + /// value is constrained. + bool IsTrackingTurnedOn; + public: TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption) : Constraint(constraint), Assumption(assumption), IsSatisfied(false), - IsZeroCheck(!Assumption && Constraint.getAs<Loc>()) {} + IsZeroCheck(!Assumption && Constraint.getAs<Loc>()), + IsTrackingTurnedOn(false) {} void Profile(llvm::FoldingSetNodeID &ID) const; diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 3f0a1b1..a80b5a7 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -21,6 +21,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerUnion.h" #include <deque> +#include <list> #include <iterator> #include <string> #include <vector> @@ -93,7 +94,7 @@ public: void HandlePathDiagnostic(PathDiagnostic *D); - enum PathGenerationScheme { None, Minimal, Extensive }; + enum PathGenerationScheme { None, Minimal, Extensive, AlternateExtensive }; virtual PathGenerationScheme getGenerationScheme() const { return Minimal; } virtual bool supportsLogicalOpControlFlow() const { return false; } virtual bool supportsAllBlockEdges() const { return false; } @@ -283,6 +284,13 @@ public: const SourceManager& getManager() const { assert(isValid()); return *SM; } void Profile(llvm::FoldingSetNodeID &ID) const; + + /// \brief Given an exploded node, retrieve the statement that should be used + /// for the diagnostic location. + static const Stmt *getStmt(const ExplodedNode *N); + + /// \brief Retrieve the statement corresponding to the sucessor node. + static const Stmt *getNextStmt(const ExplodedNode *N); }; class PathDiagnosticLocationPair { @@ -296,6 +304,9 @@ public: const PathDiagnosticLocation &getStart() const { return Start; } const PathDiagnosticLocation &getEnd() const { return End; } + void setStart(const PathDiagnosticLocation &L) { Start = L; } + void setEnd(const PathDiagnosticLocation &L) { End = L; } + void flatten() { Start.flatten(); End.flatten(); @@ -381,7 +392,7 @@ public: }; -class PathPieces : public std::deque<IntrusiveRefCntPtr<PathDiagnosticPiece> > { +class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > { void flattenTo(PathPieces &Primary, PathPieces &Current, bool ShouldFlattenMacros) const; public: @@ -608,6 +619,14 @@ public: return LPairs[0].getEnd(); } + void setStartLocation(const PathDiagnosticLocation &L) { + LPairs[0].setStart(L); + } + + void setEndLocation(const PathDiagnosticLocation &L) { + LPairs[0].setEnd(L); + } + void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); } virtual PathDiagnosticLocation getLocation() const { diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 6f99fc1..b2411e6 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -17,6 +17,7 @@ #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" @@ -134,9 +135,13 @@ enum PointerEscapeKind { class CheckerManager { const LangOptions LangOpts; - + AnalyzerOptionsRef AOptions; public: - CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } + CheckerManager(const LangOptions &langOpts, + AnalyzerOptionsRef AOptions) + : LangOpts(langOpts), + AOptions(AOptions) {} + ~CheckerManager(); bool hasPathSensitiveCheckers() const; @@ -144,6 +149,7 @@ public: void finishedCheckerRegistration(); const LangOptions &getLangOpts() const { return LangOpts; } + AnalyzerOptions &getAnalyzerOptions() { return *AOptions; } typedef CheckerBase *CheckerRef; typedef const void *CheckerTag; @@ -170,6 +176,20 @@ public: return checker; } + template <typename CHECKER> + CHECKER *registerChecker(AnalyzerOptions &AOpts) { + CheckerTag tag = getTag<CHECKER>(); + CheckerRef &ref = CheckerTags[tag]; + if (ref) + return static_cast<CHECKER *>(ref); // already registered. + + CHECKER *checker = new CHECKER(AOpts); + CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); + CHECKER::_register(checker, *this); + ref = checker; + return checker; + } + //===----------------------------------------------------------------------===// // Functions for running checkers for AST traversing.. //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index 1135b51..2c799c0 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -93,7 +93,7 @@ public: /// Returns the type of the APSInt used to store values of the given QualType. APSIntType getAPSIntType(QualType T) const { - assert(T->isIntegerType() || Loc::isLocType(T)); + assert(T->isIntegralOrEnumerationType() || Loc::isLocType(T)); return APSIntType(Ctx.getTypeSize(T), !T->isSignedIntegerOrEnumerationType()); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index cda1366..0b9762a 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -110,10 +110,6 @@ public: StoreManager &getStoreManager() { return Eng.getStoreManager(); } - - const AnalyzerOptions::ConfigTable &getConfig() const { - return Eng.getAnalysisManager().options.Config; - } /// \brief Returns the previous node in the exploded graph, which includes /// the state of the program before the checker ran. Note, checkers should diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index 5211916..edcfc8a 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -196,6 +196,10 @@ public: return const_cast<ExplodedNode*>(this)->getFirstPred(); } + const ExplodedNode *getFirstSucc() const { + return succ_empty() ? NULL : *(succ_begin()); + } + // Iterators over successor and predecessor vertices. typedef ExplodedNode* const * succ_iterator; typedef const ExplodedNode* const * const_succ_iterator; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index af2f365..9b4f77d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -37,11 +37,12 @@ class StackFrameContext; namespace ento { +class CodeTextRegion; class MemRegionManager; class MemSpaceRegion; class SValBuilder; +class SymbolicRegion; class VarRegion; -class CodeTextRegion; /// Represent a region's offset within the top level base region. class RegionOffset { @@ -145,6 +146,10 @@ public: const MemRegion *StripCasts(bool StripBaseCasts = true) const; + /// \brief If this is a symbolic region, returns the region. Otherwise, + /// goes up the base chain looking for the first symbolic base region. + const SymbolicRegion *getSymbolicBase() const; + bool hasGlobalsOrParametersStorage() const; bool hasStackStorage() const; @@ -169,6 +174,16 @@ public: /// \brief Print the region for use in diagnostics. virtual void printPretty(raw_ostream &os) const; + /// \brief Returns true if this region's textual representation can be used + /// as part of a larger expression. + virtual bool canPrintPrettyAsExpr() const; + + /// \brief Print the region as expression. + /// + /// When this region represents a subexpression, the method is for printing + /// an expression containing it. + virtual void printPrettyAsExpr(raw_ostream &os) const; + Kind getKind() const { return kind; } template<typename RegionTy> const RegionTy* getAs() const; @@ -874,8 +889,9 @@ public: return R->getKind() == VarRegionKind; } - bool canPrintPretty() const; - void printPretty(raw_ostream &os) const; + bool canPrintPrettyAsExpr() const; + + void printPrettyAsExpr(raw_ostream &os) const; }; /// CXXThisRegion - Represents the region for the implicit 'this' parameter @@ -937,6 +953,8 @@ public: bool canPrintPretty() const; void printPretty(raw_ostream &os) const; + bool canPrintPrettyAsExpr() const; + void printPrettyAsExpr(raw_ostream &os) const; }; class ObjCIvarRegion : public DeclRegion { @@ -952,8 +970,8 @@ public: const ObjCIvarDecl *getDecl() const; QualType getValueType() const; - bool canPrintPretty() const; - void printPretty(raw_ostream &os) const; + bool canPrintPrettyAsExpr() const; + void printPrettyAsExpr(raw_ostream &os) const; void dumpToStream(raw_ostream &os) const; @@ -1082,6 +1100,10 @@ public: static bool classof(const MemRegion *region) { return region->getKind() == CXXBaseObjectRegionKind; } + + bool canPrintPrettyAsExpr() const; + + void printPrettyAsExpr(raw_ostream &os) const; }; template<typename RegionTy> diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 6ea7211..42ef1db 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -201,14 +201,6 @@ public: // Binding and retrieving values to/from the environment and symbolic store. //==---------------------------------------------------------------------==// - /// \brief Create a new state with the specified CompoundLiteral binding. - /// \param CL the compound literal expression (the binding key) - /// \param LC the LocationContext of the binding - /// \param V the value to bind. - ProgramStateRef bindCompoundLiteral(const CompoundLiteralExpr *CL, - const LocationContext *LC, - SVal V) const; - /// Create a new state by binding the value 'V' to the statement 'S' in the /// state's environment. ProgramStateRef BindExpr(const Stmt *S, const LocationContext *LCtx, @@ -711,7 +703,8 @@ ProgramState::getSValAsScalarOrLoc(const Stmt *S, const LocationContext *LCtx) const { if (const Expr *Ex = dyn_cast<Expr>(S)) { QualType T = Ex->getType(); - if (Ex->isGLValue() || Loc::isLocType(T) || T->isIntegerType()) + if (Ex->isGLValue() || Loc::isLocType(T) || + T->isIntegralOrEnumerationType()) return getSVal(S, LCtx); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index f7e49a3..bbb5688 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -78,7 +78,8 @@ public: // FIXME: Remove the second disjunct when we support symbolic // truncation/extension. return (Context.getCanonicalType(Ty1) == Context.getCanonicalType(Ty2) || - (Ty1->isIntegerType() && Ty2->isIntegerType())); + (Ty1->isIntegralOrEnumerationType() && + Ty2->isIntegralOrEnumerationType())); } SVal evalCast(SVal val, QualType castTy, QualType originalType); @@ -201,6 +202,12 @@ public: DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext); + /// Returns the value of \p E, if it can be determined in a non-path-sensitive + /// manner. + /// + /// If \p E is not a constant or cannot be modeled, returns \c None. + Optional<SVal> getConstantVal(const Expr *E); + NonLoc makeCompoundVal(QualType type, llvm::ImmutableList<SVal> vals) { return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals)); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 1c5519e..326e784 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -144,16 +144,24 @@ public: /// Otherwise return 0. const FunctionDecl *getAsFunctionDecl() const; - /// If this SVal is a location (subclasses Loc) and - /// wraps a symbol, return that SymbolRef. Otherwise return 0. - SymbolRef getAsLocSymbol() const; + /// \brief If this SVal is a location and wraps a symbol, return that + /// SymbolRef. Otherwise return 0. + /// + /// Casts are ignored during lookup. + /// \param IncludeBaseRegions The boolean that controls whether the search + /// should continue to the base regions if the region is not symbolic. + SymbolRef getAsLocSymbol(bool IncludeBaseRegions = false) const; /// Get the symbol in the SVal or its base region. SymbolRef getLocSymbolInBase() const; - /// If this SVal wraps a symbol return that SymbolRef. + /// \brief If this SVal wraps a symbol return that SymbolRef. /// Otherwise, return 0. - SymbolRef getAsSymbol() const; + /// + /// Casts are ignored during lookup. + /// \param IncludeBaseRegions The boolean that controls whether the search + /// should continue to the base regions if the region is not symbolic. + SymbolRef getAsSymbol(bool IncludeBaseRegions = false) const; /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then /// return that expression. Otherwise return NULL. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index bbfd579..b219495 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -76,21 +76,6 @@ public: /// \param L the location whose binding should be removed. virtual StoreRef killBinding(Store ST, Loc L) = 0; - /// \brief Create a new store that binds a value to a compound literal. - /// - /// \param ST The original store whose bindings are the basis for the new - /// store. - /// - /// \param CL The compound literal to bind (the binding key). - /// - /// \param LC The LocationContext for the binding. - /// - /// \param V The value to bind to the compound literal. - virtual StoreRef bindCompoundLiteral(Store ST, - const CompoundLiteralExpr *CL, - const LocationContext *LC, - SVal V) = 0; - /// getInitialStore - Returns the initial "empty" store representing the /// value bindings upon entry to an analyzed function. virtual StoreRef getInitialStore(const LocationContext *InitLoc) = 0; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index 56afca2..914b2be 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -49,7 +49,10 @@ public: MetadataKind, BEGIN_SYMBOLS = RegionValueKind, END_SYMBOLS = MetadataKind, - SymIntKind, IntSymKind, SymSymKind, CastSymbolKind }; + SymIntKind, IntSymKind, SymSymKind, + BEGIN_BINARYSYMEXPRS = SymIntKind, + END_BINARYSYMEXPRS = SymSymKind, + CastSymbolKind }; private: Kind K; @@ -341,24 +344,39 @@ public: } }; -/// SymIntExpr - Represents symbolic expression like 'x' + 3. -class SymIntExpr : public SymExpr { - const SymExpr *LHS; +/// \brief Represents a symbolic expression involving a binary operator +class BinarySymExpr : public SymExpr { BinaryOperator::Opcode Op; - const llvm::APSInt& RHS; QualType T; -public: - SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t) - : SymExpr(SymIntKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} +protected: + BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t) + : SymExpr(k), Op(op), T(t) {} +public: // FIXME: We probably need to make this out-of-line to avoid redundant // generation of virtual functions. QualType getType() const { return T; } BinaryOperator::Opcode getOpcode() const { return Op; } + // Implement isa<T> support. + static inline bool classof(const SymExpr *SE) { + Kind k = SE->getKind(); + return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS; + } +}; + +/// \brief Represents a symbolic expression like 'x' + 3. +class SymIntExpr : public BinarySymExpr { + const SymExpr *LHS; + const llvm::APSInt& RHS; + +public: + SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, + const llvm::APSInt& rhs, QualType t) + : BinarySymExpr(SymIntKind, op, t), LHS(lhs), RHS(rhs) {} + virtual void dumpToStream(raw_ostream &os) const; const SymExpr *getLHS() const { return LHS; } @@ -375,7 +393,7 @@ public: } void Profile(llvm::FoldingSetNodeID& ID) { - Profile(ID, LHS, Op, RHS, T); + Profile(ID, LHS, getOpcode(), RHS, getType()); } // Implement isa<T> support. @@ -384,21 +402,15 @@ public: } }; -/// IntSymExpr - Represents symbolic expression like 3 - 'x'. -class IntSymExpr : public SymExpr { +/// \brief Represents a symbolic expression like 3 - 'x'. +class IntSymExpr : public BinarySymExpr { const llvm::APSInt& LHS; - BinaryOperator::Opcode Op; const SymExpr *RHS; - QualType T; public: IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) - : SymExpr(IntSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} - - QualType getType() const { return T; } - - BinaryOperator::Opcode getOpcode() const { return Op; } + : BinarySymExpr(IntSymKind, op, t), LHS(lhs), RHS(rhs) {} virtual void dumpToStream(raw_ostream &os) const; @@ -416,7 +428,7 @@ public: } void Profile(llvm::FoldingSetNodeID& ID) { - Profile(ID, LHS, Op, RHS, T); + Profile(ID, LHS, getOpcode(), RHS, getType()); } // Implement isa<T> support. @@ -425,26 +437,19 @@ public: } }; -/// SymSymExpr - Represents symbolic expression like 'x' + 'y'. -class SymSymExpr : public SymExpr { +/// \brief Represents a symbolic expression like 'x' + 'y'. +class SymSymExpr : public BinarySymExpr { const SymExpr *LHS; - BinaryOperator::Opcode Op; const SymExpr *RHS; - QualType T; public: SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) - : SymExpr(SymSymKind), LHS(lhs), Op(op), RHS(rhs), T(t) {} + : BinarySymExpr(SymSymKind, op, t), LHS(lhs), RHS(rhs) {} - BinaryOperator::Opcode getOpcode() const { return Op; } const SymExpr *getLHS() const { return LHS; } const SymExpr *getRHS() const { return RHS; } - // FIXME: We probably need to make this out-of-line to avoid redundant - // generation of virtual functions. - QualType getType() const { return T; } - virtual void dumpToStream(raw_ostream &os) const; static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, @@ -457,7 +462,7 @@ public: } void Profile(llvm::FoldingSetNodeID& ID) { - Profile(ID, LHS, Op, RHS, T); + Profile(ID, LHS, getOpcode(), RHS, getType()); } // Implement isa<T> support. diff --git a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h index 492edd4..1df8c09 100644 --- a/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h +++ b/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h @@ -21,7 +21,7 @@ namespace clang { namespace ento { class CheckerManager; -CheckerManager *createCheckerManager(const AnalyzerOptions &opts, +CheckerManager *createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts, ArrayRef<std::string> plugins, DiagnosticsEngine &diags); |