From 51ece4aae5857052d224ce52277924c74685714e Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 7 Aug 2015 23:02:44 +0000 Subject: Vendor import of clang trunk r242221: https://llvm.org/svn/llvm-project/cfe/trunk@242221 --- include/clang-c/BuildSystem.h | 12 +- include/clang/AST/ASTContext.h | 30 +++ include/clang/AST/DataRecursiveASTVisitor.h | 33 ++- include/clang/AST/DeclObjC.h | 292 ++++++++++++++++++-- include/clang/AST/ExprObjC.h | 38 +-- include/clang/AST/RecursiveASTVisitor.h | 32 ++- include/clang/AST/Type.h | 296 +++++++++++++++++++-- include/clang/AST/TypeLoc.h | 118 ++++++-- include/clang/ASTMatchers/ASTMatchers.h | 2 +- include/clang/ASTMatchers/ASTMatchersInternal.h | 3 +- include/clang/ASTMatchers/Dynamic/VariantValue.h | 6 +- include/clang/Basic/Attr.td | 10 +- include/clang/Basic/AttrDocs.td | 19 ++ include/clang/Basic/BuiltinsPPC.def | 46 ++++ include/clang/Basic/BuiltinsX86.def | 60 +++++ include/clang/Basic/DeclNodes.td | 1 + include/clang/Basic/DiagnosticCommonKinds.td | 2 + include/clang/Basic/DiagnosticDriverKinds.td | 2 - include/clang/Basic/DiagnosticGroups.td | 1 + include/clang/Basic/DiagnosticParseKinds.td | 16 +- include/clang/Basic/DiagnosticSemaKinds.td | 99 +++++++ include/clang/Basic/IdentifierTable.h | 4 +- include/clang/Basic/LangOptions.def | 1 + include/clang/Basic/Sanitizers.h | 21 +- include/clang/Basic/TargetInfo.h | 16 ++ include/clang/Basic/TokenKinds.def | 5 + .../CodeGen/ObjectFilePCHContainerOperations.h | 43 +++ include/clang/Driver/Action.h | 57 +++- include/clang/Driver/CLCompatOptions.td | 6 +- include/clang/Driver/Driver.h | 4 +- include/clang/Driver/Job.h | 3 + include/clang/Driver/Options.td | 46 +++- include/clang/Driver/SanitizerArgs.h | 1 + include/clang/Driver/Types.def | 1 + include/clang/Driver/Types.h | 3 + include/clang/Format/Format.h | 11 + include/clang/Frontend/CodeGenOptions.def | 4 + include/clang/Frontend/CodeGenOptions.h | 1 + include/clang/Frontend/CompilerInstance.h | 21 +- include/clang/Lex/ModuleMap.h | 6 +- include/clang/Lex/Preprocessor.h | 16 ++ include/clang/Parse/Parser.h | 56 +++- include/clang/Sema/CodeCompleteConsumer.h | 2 + include/clang/Sema/DeclSpec.h | 31 +-- include/clang/Sema/Sema.h | 107 +++++++- include/clang/Sema/Template.h | 1 + include/clang/Serialization/ASTBitCodes.h | 4 +- include/clang/Serialization/ASTReader.h | 66 +++-- include/clang/Serialization/ASTWriter.h | 2 +- .../clang/StaticAnalyzer/Core/CheckerRegistry.h | 7 + 50 files changed, 1429 insertions(+), 235 deletions(-) create mode 100644 include/clang/CodeGen/ObjectFilePCHContainerOperations.h (limited to 'include') diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h index 7aa01914cf24..8d323a4e6cae 100644 --- a/include/clang-c/BuildSystem.h +++ b/include/clang-c/BuildSystem.h @@ -73,7 +73,7 @@ clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay, * * \param options is reserved, always pass 0. * \param out_buffer_ptr pointer to receive the buffer pointer, which should be - * disposed using \c free(). + * disposed using \c clang_free(). * \param out_buffer_size pointer to receive the buffer size. * \returns 0 for success, non-zero to indicate an error. */ @@ -82,6 +82,14 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options, char **out_buffer_ptr, unsigned *out_buffer_size); +/** + * \brief free memory allocated by libclang, such as the buffer returned by + * \c CXVirtualFileOverlay() or \c clang_ModuleMapDescriptor_writeToBuffer(). + * + * \param buffer memory pointer to free. + */ +CINDEX_LINKAGE void clang_free(void *buffer); + /** * \brief Dispose a \c CXVirtualFileOverlay object. */ @@ -122,7 +130,7 @@ clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor, * * \param options is reserved, always pass 0. * \param out_buffer_ptr pointer to receive the buffer pointer, which should be - * disposed using \c free(). + * disposed using \c clang_free(). * \param out_buffer_size pointer to receive the buffer size. * \returns 0 for success, non-zero to indicate an error. */ diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 682be3d41513..a2bd55a089ed 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -236,6 +236,12 @@ class ASTContext : public RefCountedBase { QualType ObjCClassRedefinitionType; QualType ObjCSelRedefinitionType; + /// The identifier 'NSObject'. + IdentifierInfo *NSObjectName = nullptr; + + /// The identifier 'NSCopying'. + IdentifierInfo *NSCopyingName = nullptr; + QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; @@ -1189,9 +1195,15 @@ public: QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl = nullptr) const; + /// Legacy interface: cannot provide type arguments or __kindof. QualType getObjCObjectType(QualType Base, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) const; + + QualType getObjCObjectType(QualType Base, + ArrayRef typeArgs, + ArrayRef protocols, + bool isKindOf) const; bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in @@ -1351,6 +1363,24 @@ public: ObjCSelRedefinitionType = RedefType; } + /// Retrieve the identifier 'NSObject'. + IdentifierInfo *getNSObjectName() { + if (!NSObjectName) { + NSObjectName = &Idents.get("NSObject"); + } + + return NSObjectName; + } + + /// Retrieve the identifier 'NSCopying'. + IdentifierInfo *getNSCopyingName() { + if (!NSCopyingName) { + NSCopyingName = &Idents.get("NSCopying"); + } + + return NSCopyingName; + } + /// \brief Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; QualType getObjCInstanceType() { diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h index 923d98fb1664..dd167fe27c02 100644 --- a/include/clang/AST/DataRecursiveASTVisitor.h +++ b/include/clang/AST/DataRecursiveASTVisitor.h @@ -940,6 +940,9 @@ DEF_TRAVERSE_TYPE(ObjCObjectType, { // type is itself. if (T->getBaseType().getTypePtr() != T) TRY_TO(TraverseType(T->getBaseType())); + for (auto typeArg : T->getTypeArgsAsWritten()) { + TRY_TO(TraverseType(typeArg)); + } }) DEF_TRAVERSE_TYPE(ObjCObjectPointerType, @@ -1166,6 +1169,8 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectType, { // type is itself. if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr()) TRY_TO(TraverseTypeLoc(TL.getBaseLoc())); + for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) + TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc())); }) DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, @@ -1307,7 +1312,13 @@ DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement }) DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement - }) + if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) { + for (auto typeParam : *typeParamList) { + TRY_TO(TraverseObjCTypeParamDecl(typeParam)); + } + } + return true; +}) DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement }) @@ -1316,7 +1327,16 @@ DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement }) DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement - }) + if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) { + for (auto typeParam : *typeParamList) { + TRY_TO(TraverseObjCTypeParamDecl(typeParam)); + } + } + + if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) { + TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc())); + } +}) DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement }) @@ -1335,6 +1355,15 @@ DEF_TRAVERSE_DECL(ObjCMethodDecl, { return true; }) +DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { + if (D->hasExplicitBound()) { + TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); + // We shouldn't traverse D->getTypeForDecl(); it's a result of + // declaring the type alias, not something that was written in the + // source. + } +}) + DEF_TRAVERSE_DECL(ObjCPropertyDecl, { if (D->getTypeSourceInfo()) TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index c3fb57770245..c42764b6f3bf 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -332,10 +332,14 @@ public: SourceRange getReturnTypeSourceRange() const; /// \brief Determine the type of an expression that sends a message to this - /// function. - QualType getSendResultType() const { - return getReturnType().getNonLValueExprType(getASTContext()); - } + /// function. This replaces the type parameters with the types they would + /// get if the receiver was parameterless (e.g. it may replace the type + /// parameter with 'id'). + QualType getSendResultType() const; + + /// Determine the type of an expression that sends a message to this + /// function with the given receiver type. + QualType getSendResultType(QualType receiverType) const; TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; } void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; } @@ -399,6 +403,11 @@ public: /// have already been created. void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); + /// \return the type for \c self and set \arg selfIsPseudoStrong and + /// \arg selfIsConsumed accordingly. + QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID, + bool &selfIsPseudoStrong, bool &selfIsConsumed); + ImplicitParamDecl * getSelfDecl() const { return SelfDecl; } void setSelfDecl(ImplicitParamDecl *SD) { SelfDecl = SD; } ImplicitParamDecl * getCmdDecl() const { return CmdDecl; } @@ -501,6 +510,183 @@ public: friend class ASTDeclWriter; }; +/// Describes the variance of a given generic parameter. +enum class ObjCTypeParamVariance : uint8_t { + /// The parameter is invariant: must match exactly. + Invariant, + /// The parameter is covariant, e.g., X is a subtype of X when + /// the type parameter is covariant and T is a subtype of U. + Covariant, + /// The parameter is contravariant, e.g., X is a subtype of X + /// when the type parameter is covariant and U is a subtype of T. + Contravariant, +}; + +/// Represents the declaration of an Objective-C type parameter. +/// +/// \code +/// @interface NSDictionary, Value> +/// @end +/// \endcode +/// +/// In the example above, both \c Key and \c Value are represented by +/// \c ObjCTypeParamDecl. \c Key has an explicit bound of \c id, +/// while \c Value gets an implicit bound of \c id. +/// +/// Objective-C type parameters are typedef-names in the grammar, +class ObjCTypeParamDecl : public TypedefNameDecl { + void anchor() override; + + /// Index of this type parameter in the type parameter list. + unsigned Index : 14; + + /// The variance of the type parameter. + unsigned Variance : 2; + + /// The location of the variance, if any. + SourceLocation VarianceLoc; + + /// The location of the ':', which will be valid when the bound was + /// explicitly specified. + SourceLocation ColonLoc; + + ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc, + ObjCTypeParamVariance variance, SourceLocation varianceLoc, + unsigned index, + SourceLocation nameLoc, IdentifierInfo *name, + SourceLocation colonLoc, TypeSourceInfo *boundInfo) + : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name, + boundInfo), + Index(index), Variance(static_cast(variance)), + VarianceLoc(varianceLoc), ColonLoc(colonLoc) { } + +public: + static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc, + ObjCTypeParamVariance variance, + SourceLocation varianceLoc, + unsigned index, + SourceLocation nameLoc, + IdentifierInfo *name, + SourceLocation colonLoc, + TypeSourceInfo *boundInfo); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, unsigned ID); + + SourceRange getSourceRange() const override LLVM_READONLY; + + /// Determine the variance of this type parameter. + ObjCTypeParamVariance getVariance() const { + return static_cast(Variance); + } + + /// Set the variance of this type parameter. + void setVariance(ObjCTypeParamVariance variance) { + Variance = static_cast(variance); + } + + /// Retrieve the location of the variance keyword. + SourceLocation getVarianceLoc() const { return VarianceLoc; } + + /// Retrieve the index into its type parameter list. + unsigned getIndex() const { return Index; } + + /// Whether this type parameter has an explicitly-written type bound, e.g., + /// "T : NSView". + bool hasExplicitBound() const { return ColonLoc.isValid(); } + + /// Retrieve the location of the ':' separating the type parameter name + /// from the explicitly-specified bound. + SourceLocation getColonLoc() const { return ColonLoc; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ObjCTypeParam; } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// Stores a list of Objective-C type parameters for a parameterized class +/// or a category/extension thereof. +/// +/// \code +/// @interface NSArray // stores the +/// @end +/// \endcode +class ObjCTypeParamList { + /// Stores the components of a SourceRange as a POD. + struct PODSourceRange { + unsigned Begin; + unsigned End; + }; + + union { + /// Location of the left and right angle brackets. + PODSourceRange Brackets; + + // Used only for alignment. + ObjCTypeParamDecl *AlignmentHack; + }; + + /// The number of parameters in the list, which are tail-allocated. + unsigned NumParams; + + ObjCTypeParamList(SourceLocation lAngleLoc, + ArrayRef typeParams, + SourceLocation rAngleLoc); + +public: + /// Create a new Objective-C type parameter list. + static ObjCTypeParamList *create(ASTContext &ctx, + SourceLocation lAngleLoc, + ArrayRef typeParams, + SourceLocation rAngleLoc); + + /// Iterate through the type parameters in the list. + typedef ObjCTypeParamDecl **iterator; + + iterator begin() { return reinterpret_cast(this + 1); } + + iterator end() { return begin() + size(); } + + /// Determine the number of type parameters in this list. + unsigned size() const { return NumParams; } + + // Iterate through the type parameters in the list. + typedef ObjCTypeParamDecl * const *const_iterator; + + const_iterator begin() const { + return reinterpret_cast(this + 1); + } + + const_iterator end() const { + return begin() + size(); + } + + ObjCTypeParamDecl *front() const { + assert(size() > 0 && "empty Objective-C type parameter list"); + return *begin(); + } + + ObjCTypeParamDecl *back() const { + assert(size() > 0 && "empty Objective-C type parameter list"); + return *(end() - 1); + } + + SourceLocation getLAngleLoc() const { + return SourceLocation::getFromRawEncoding(Brackets.Begin); + } + SourceLocation getRAngleLoc() const { + return SourceLocation::getFromRawEncoding(Brackets.End); + } + SourceRange getSourceRange() const { + return SourceRange(getLAngleLoc(), getRAngleLoc()); + } + + /// Gather the default set of type arguments to be substituted for + /// these type parameters when dealing with an unspecialized type. + void gatherDefaultTypeArgs(SmallVectorImpl &typeArgs) const; +}; + /// ObjCContainerDecl - Represents a container for method declarations. /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, /// ObjCProtocolDecl, and ObjCImplDecl. @@ -676,9 +862,9 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// declaration. ObjCInterfaceDecl *Definition; - /// Class's super class. - ObjCInterfaceDecl *SuperClass; - + /// When non-null, this is always an ObjCObjectType. + TypeSourceInfo *SuperClassTInfo; + /// Protocols referenced in the \@interface declaration ObjCProtocolList ReferencedProtocols; @@ -719,16 +905,13 @@ class ObjCInterfaceDecl : public ObjCContainerDecl }; /// One of the \c InheritedDesignatedInitializersState enumeratos. mutable unsigned InheritedDesignatedInitializers : 2; - - /// \brief The location of the superclass, if any. - SourceLocation SuperClassLoc; /// \brief The location of the last location in this declaration, before /// the properties/methods. For example, this will be the '>', '}', or /// identifier, SourceLocation EndLoc; - DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(), + DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(), ExternallyCompleted(), IvarListMissingImplementation(true), HasDesignatedInitializers(), @@ -736,11 +919,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl }; ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, - IdentifierInfo *Id, SourceLocation CLoc, - ObjCInterfaceDecl *PrevDecl, bool IsInternal); + IdentifierInfo *Id, ObjCTypeParamList *typeParamList, + SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, + bool IsInternal); void LoadExternalDefinition() const; + /// The type parameters associated with this class, if any. + ObjCTypeParamList *TypeParamList; + /// \brief Contains a pointer to the data associated with this class, /// which will be NULL if this class has not yet been defined. /// @@ -771,12 +958,33 @@ public: static ObjCInterfaceDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id, + ObjCTypeParamList *typeParamList, ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID); + /// Retrieve the type parameters of this class. + /// + /// This function looks for a type parameter list for the given + /// class; if the class has been declared (with \c \@class) but not + /// defined (with \c \@interface), it will search for a declaration that + /// has type parameters, skipping any declarations that do not. + ObjCTypeParamList *getTypeParamList() const; + + /// Set the type parameters of this class. + /// + /// This function is used by the AST importer, which must import the type + /// parameters after creating their DeclContext to avoid loops. + void setTypeParamList(ObjCTypeParamList *TPL); + + /// Retrieve the type parameters written on this particular declaration of + /// the class. + ObjCTypeParamList *getTypeParamListAsWritten() const { + return TypeParamList; + } + SourceRange getSourceRange() const override LLVM_READONLY { if (isThisDeclarationADefinition()) return ObjCContainerDecl::getSourceRange(); @@ -1023,7 +1231,16 @@ public: /// a forward declaration (\@class) to a definition (\@interface). void startDefinition(); - ObjCInterfaceDecl *getSuperClass() const { + /// Retrieve the superclass type. + const ObjCObjectType *getSuperClassType() const { + if (TypeSourceInfo *TInfo = getSuperClassTInfo()) + return TInfo->getType()->castAs(); + + return nullptr; + } + + // Retrieve the type source information for the superclass. + TypeSourceInfo *getSuperClassTInfo() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return nullptr; @@ -1031,13 +1248,15 @@ public: if (data().ExternallyCompleted) LoadExternalDefinition(); - return data().SuperClass; + return data().SuperClassTInfo; } - void setSuperClass(ObjCInterfaceDecl * superCls) { - data().SuperClass = - (superCls && superCls->hasDefinition()) ? superCls->getDefinition() - : superCls; + // Retrieve the declaration for the superclass of this class, which + // does not include any type arguments that apply to the superclass. + ObjCInterfaceDecl *getSuperClass() const; + + void setSuperClass(TypeSourceInfo *superClass) { + data().SuperClassTInfo = superClass; } /// \brief Iterator that walks over the list of categories, filtering out @@ -1329,8 +1548,8 @@ public: void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; } - void setSuperClassLoc(SourceLocation Loc) { data().SuperClassLoc = Loc; } - SourceLocation getSuperClassLoc() const { return data().SuperClassLoc; } + /// Retrieve the starting location of the superclass. + SourceLocation getSuperClassLoc() const; /// isImplicitInterfaceDecl - check that this is an implicitly declared /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation @@ -1438,6 +1657,10 @@ public: void setSynthesize(bool synth) { Synthesized = synth; } bool getSynthesize() const { return Synthesized; } + /// Retrieve the type of this instance variable when viewed as a member of a + /// specific object type. + QualType getUsageType(QualType objectType) const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCIvar; } @@ -1719,6 +1942,9 @@ class ObjCCategoryDecl : public ObjCContainerDecl { /// Interface belonging to this category ObjCInterfaceDecl *ClassInterface; + /// The type parameters associated with this category, if any. + ObjCTypeParamList *TypeParamList; + /// referenced protocols in this category. ObjCProtocolList ReferencedProtocols; @@ -1736,13 +1962,9 @@ class ObjCCategoryDecl : public ObjCContainerDecl { ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), - SourceLocation IvarRBraceLoc=SourceLocation()) - : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc), - ClassInterface(IDecl), NextClassCategory(nullptr), - CategoryNameLoc(CategoryNameLoc), - IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) { - } + SourceLocation IvarRBraceLoc=SourceLocation()); public: @@ -1752,6 +1974,7 @@ public: SourceLocation CategoryNameLoc, IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, + ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1759,6 +1982,17 @@ public: ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } + /// Retrieve the type parameter list associated with this category or + /// extension. + ObjCTypeParamList *getTypeParamList() const { return TypeParamList; } + + /// Set the type parameters of this category. + /// + /// This function is used by the AST importer, which must import the type + /// parameters after creating their DeclContext to avoid loops. + void setTypeParamList(ObjCTypeParamList *TPL); + + ObjCCategoryImplDecl *getImplementation() const; void setImplementation(ObjCCategoryImplDecl *ImplD); @@ -2275,6 +2509,10 @@ public: DeclTypeSourceInfo = TSI; } + /// Retrieve the type when this property is used with a specific base object + /// type. + QualType getUsageType(QualType objectType) const; + PropertyAttributeKind getPropertyAttributes() const { return PropertyAttributeKind(PropertyAttributes); } diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 899e6487f737..f28e5196c7a4 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -687,40 +687,7 @@ public: QualType getSuperReceiverType() const { return QualType(Receiver.get(), 0); } - QualType getGetterResultType() const { - QualType ResultType; - if (isExplicitProperty()) { - const ObjCPropertyDecl *PDecl = getExplicitProperty(); - if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl()) - ResultType = Getter->getReturnType(); - else - ResultType = PDecl->getType(); - } else { - const ObjCMethodDecl *Getter = getImplicitPropertyGetter(); - if (Getter) - ResultType = Getter->getReturnType(); // with reference! - } - return ResultType; - } - - QualType getSetterArgType() const { - QualType ArgType; - if (isImplicitProperty()) { - const ObjCMethodDecl *Setter = getImplicitPropertySetter(); - ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); - ArgType = (*P)->getType(); - } else { - if (ObjCPropertyDecl *PDecl = getExplicitProperty()) - if (const ObjCMethodDecl *Setter = PDecl->getSetterMethodDecl()) { - ObjCMethodDecl::param_const_iterator P = Setter->param_begin(); - ArgType = (*P)->getType(); - } - if (ArgType.isNull()) - ArgType = getType(); - } - return ArgType; - } - + ObjCInterfaceDecl *getClassReceiver() const { return Receiver.get(); } @@ -728,6 +695,9 @@ public: bool isSuperReceiver() const { return Receiver.is(); } bool isClassReceiver() const { return Receiver.is(); } + /// Determine the type of the base, regardless of the kind of receiver. + QualType getReceiverType(const ASTContext &ctx) const; + SourceLocation getLocStart() const LLVM_READONLY { return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation(); } diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index b118503b674b..1017656b662c 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1008,6 +1008,9 @@ DEF_TRAVERSE_TYPE(ObjCObjectType, { // type is itself. if (T->getBaseType().getTypePtr() != T) TRY_TO(TraverseType(T->getBaseType())); + for (auto typeArg : T->getTypeArgsAsWritten()) { + TRY_TO(TraverseType(typeArg)); + } }) DEF_TRAVERSE_TYPE(ObjCObjectPointerType, @@ -1234,6 +1237,8 @@ DEF_TRAVERSE_TYPELOC(ObjCObjectType, { // type is itself. if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr()) TRY_TO(TraverseTypeLoc(TL.getBaseLoc())); + for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) + TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc())); }) DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, @@ -1382,7 +1387,12 @@ DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement }) DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement - }) + if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) { + for (auto typeParam : *typeParamList) { + TRY_TO(TraverseObjCTypeParamDecl(typeParam)); + } + } +}) DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement }) @@ -1391,7 +1401,16 @@ DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement }) DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement - }) + if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) { + for (auto typeParam : *typeParamList) { + TRY_TO(TraverseObjCTypeParamDecl(typeParam)); + } + } + + if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) { + TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc())); + } +}) DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement }) @@ -1410,6 +1429,15 @@ DEF_TRAVERSE_DECL(ObjCMethodDecl, { return true; }) +DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { + if (D->hasExplicitBound()) { + TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); + // We shouldn't traverse D->getTypeForDecl(); it's a result of + // declaring the type alias, not something that was written in the + // source. + } +}) + DEF_TRAVERSE_DECL(ObjCPropertyDecl, { if (D->getTypeSourceInfo()) TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 97f13313b339..632d4b95e376 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -533,6 +533,24 @@ struct SplitQualType { } }; +/// The kind of type we are substituting Objective-C type arguments into. +/// +/// The kind of substitution affects the replacement of type parameters when +/// no concrete type information is provided, e.g., when dealing with an +/// unspecialized type. +enum class ObjCSubstitutionContext { + /// An ordinary type. + Ordinary, + /// The result type of a method or function. + Result, + /// The parameter type of a method or function. + Parameter, + /// The type of a property. + Property, + /// The superclass of a type. + Superclass, +}; + /// QualType - For efficiency, we don't store CV-qualified types as nodes on /// their own: instead each reference to a type stores the qualifiers. This /// greatly reduces the number of nodes we need to allocate for types (for @@ -994,6 +1012,51 @@ public: /// type other than void. bool isCForbiddenLValueType() const; + /// Substitute type arguments for the Objective-C type parameters used in the + /// subject type. + /// + /// \param ctx ASTContext in which the type exists. + /// + /// \param typeArgs The type arguments that will be substituted for the + /// Objective-C type parameters in the subject type, which are generally + /// computed via \c Type::getObjCSubstitutions. If empty, the type + /// parameters will be replaced with their bounds or id/Class, as appropriate + /// for the context. + /// + /// \param context The context in which the subject type was written. + /// + /// \returns the resulting type. + QualType substObjCTypeArgs(ASTContext &ctx, + ArrayRef typeArgs, + ObjCSubstitutionContext context) const; + + /// Substitute type arguments from an object type for the Objective-C type + /// parameters used in the subject type. + /// + /// This operation combines the computation of type arguments for + /// substitution (\c Type::getObjCSubstitutions) with the actual process of + /// substitution (\c QualType::substObjCTypeArgs) for the convenience of + /// callers that need to perform a single substitution in isolation. + /// + /// \param objectType The type of the object whose member type we're + /// substituting into. For example, this might be the receiver of a message + /// or the base of a property access. + /// + /// \param dc The declaration context from which the subject type was + /// retrieved, which indicates (for example) which type parameters should + /// be substituted. + /// + /// \param context The context in which the subject type was written. + /// + /// \returns the subject type after replacing all of the Objective-C type + /// parameters with their corresponding arguments. + QualType substObjCMemberType(QualType objectType, + const DeclContext *dc, + ObjCSubstitutionContext context) const; + + /// Strip Objective-C "__kindof" types from the given type. + QualType stripObjCKindOfType(const ASTContext &ctx) const; + private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the @@ -1288,10 +1351,17 @@ protected: unsigned : NumTypeBits; + /// The number of type arguments stored directly on this object type. + unsigned NumTypeArgs : 7; + /// NumProtocols - The number of protocols stored directly on this /// object type. - unsigned NumProtocols : 32 - NumTypeBits; + unsigned NumProtocols : 6; + + /// Whether this is a "kindof" type. + unsigned IsKindOf : 1; }; + static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned"); class ReferenceTypeBitfields { friend class ReferenceType; @@ -1585,7 +1655,28 @@ public: bool isObjCQualifiedClassType() const; // Class bool isObjCObjectOrInterfaceType() const; bool isObjCIdType() const; // id + + /// Whether the type is Objective-C 'id' or a __kindof type of an + /// object type, e.g., __kindof NSView * or __kindof id + /// . + /// + /// \param bound Will be set to the bound on non-id subtype types, + /// which will be (possibly specialized) Objective-C class type, or + /// null for 'id. + bool isObjCIdOrObjectKindOfType(const ASTContext &ctx, + const ObjCObjectType *&bound) const; + bool isObjCClassType() const; // Class + + /// Whether the type is Objective-C 'Class' or a __kindof type of an + /// Class type, e.g., __kindof Class . + /// + /// Unlike \c isObjCIdOrObjectKindOfType, there is no relevant bound + /// here because Objective-C's type system cannot express "a class + /// object for a subclass of NSFoo". + bool isObjCClassOrClassKindOfType() const; + + bool isBlockCompatibleObjCPointerType(ASTContext &ctx) const; bool isObjCSelType() const; // Class bool isObjCBuiltinType() const; // 'id' or 'Class' bool isObjCARCBridgableType() const; @@ -1697,6 +1788,7 @@ public: /// NOTE: getAs*ArrayType are methods on ASTContext. const RecordType *getAsUnionType() const; const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. + const ObjCObjectType *getAsObjCInterfaceType() const; // The following is a convenience method that returns an ObjCObjectPointerType // for object declared using an interface. const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; @@ -1832,6 +1924,28 @@ public: /// pointer type. bool canHaveNullability() const; + /// Retrieve the set of substitutions required when accessing a member + /// of the Objective-C receiver type that is declared in the given context. + /// + /// \c *this is the type of the object we're operating on, e.g., the + /// receiver for a message send or the base of a property access, and is + /// expected to be of some object or object pointer type. + /// + /// \param dc The declaration context for which we are building up a + /// substitution mapping, which should be an Objective-C class, extension, + /// category, or method within. + /// + /// \returns an array of type arguments that can be substituted for + /// the type parameters of the given declaration context in any type described + /// within that context, or an empty optional to indicate that no + /// substitution is required. + Optional> + getObjCSubstitutions(const DeclContext *dc) const; + + /// Determines if this is an ObjC interface type that may accept type + /// parameters. + bool acceptsObjCTypeParams() const; + const char *getTypeClassName() const; QualType getCanonicalTypeInternal() const { @@ -3497,6 +3611,7 @@ public: attr_nonnull, attr_nullable, attr_null_unspecified, + attr_objc_kindof, }; private: @@ -4369,19 +4484,25 @@ public: }; /// ObjCObjectType - Represents a class type in Objective C. -/// Every Objective C type is a combination of a base type and a -/// list of protocols. +/// +/// Every Objective C type is a combination of a base type, a set of +/// type arguments (optional, for parameterized classes) and a list of +/// protocols. /// /// Given the following declarations: /// \code -/// \@class C; +/// \@class C; /// \@protocol P; /// \endcode /// /// 'C' is an ObjCInterfaceType C. It is sugar for an ObjCObjectType /// with base C and no protocols. /// -/// 'C

' is an ObjCObjectType with base C and protocol list [P]. +/// 'C

' is an unspecialized ObjCObjectType with base C and protocol list [P]. +/// 'C' is a specialized ObjCObjectType with type arguments 'C*' and no +/// protocol list. +/// 'C

' is a specialized ObjCObjectType with base C, type arguments 'C*', +/// and protocol list [P]. /// /// 'id' is a TypedefType which is sugar for an ObjCObjectPointerType whose /// pointee is an ObjCObjectType with base BuiltinType::ObjCIdType @@ -4391,8 +4512,10 @@ public: /// with base BuiltinType::ObjCIdType and protocol list [P]. Eventually /// this should get its own sugar class to better represent the source. class ObjCObjectType : public Type { - // ObjCObjectType.NumProtocols - the number of protocols stored + // ObjCObjectType.NumTypeArgs - the number of type arguments stored // after the ObjCObjectPointerType node. + // ObjCObjectType.NumProtocols - the number of protocols stored + // after the type arguments of ObjCObjectPointerType node. // // These protocols are those written directly on the type. If // protocol qualifiers ever become additive, the iterators will need @@ -4404,23 +4527,38 @@ class ObjCObjectType : public Type { /// Either a BuiltinType or an InterfaceType or sugar for either. QualType BaseType; + /// Cached superclass type. + mutable llvm::PointerIntPair + CachedSuperClassType; + ObjCProtocolDecl * const *getProtocolStorage() const { return const_cast(this)->getProtocolStorage(); } + QualType *getTypeArgStorage(); + const QualType *getTypeArgStorage() const { + return const_cast(this)->getTypeArgStorage(); + } + ObjCProtocolDecl **getProtocolStorage(); protected: ObjCObjectType(QualType Canonical, QualType Base, - ObjCProtocolDecl * const *Protocols, unsigned NumProtocols); + ArrayRef typeArgs, + ArrayRef protocols, + bool isKindOf); enum Nonce_ObjCInterface { Nonce_ObjCInterface }; ObjCObjectType(enum Nonce_ObjCInterface) : Type(ObjCInterface, QualType(), false, false, false, false), BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; + ObjCObjectTypeBits.NumTypeArgs = 0; + ObjCObjectTypeBits.IsKindOf = 0; } + void computeSuperClassTypeSlow() const; + public: /// getBaseType - Gets the base type of this object type. This is /// always (possibly sugar for) one of: @@ -4452,6 +4590,33 @@ public: /// really is an interface. ObjCInterfaceDecl *getInterface() const; + /// Determine whether this object type is "specialized", meaning + /// that it has type arguments. + bool isSpecialized() const; + + /// Determine whether this object type was written with type arguments. + bool isSpecializedAsWritten() const { + return ObjCObjectTypeBits.NumTypeArgs > 0; + } + + /// Determine whether this object type is "unspecialized", meaning + /// that it has no type arguments. + bool isUnspecialized() const { return !isSpecialized(); } + + /// Determine whether this object type is "unspecialized" as + /// written, meaning that it has no type arguments. + bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } + + /// Retrieve the type arguments of this object type (semantically). + ArrayRef getTypeArgs() const; + + /// Retrieve the type arguments of this object type as they were + /// written. + ArrayRef getTypeArgsAsWritten() const { + return ArrayRef(getTypeArgStorage(), + ObjCObjectTypeBits.NumTypeArgs); + } + typedef ObjCProtocolDecl * const *qual_iterator; typedef llvm::iterator_range qual_range; @@ -4471,6 +4636,35 @@ public: return qual_begin()[I]; } + /// Retrieve all of the protocol qualifiers. + ArrayRef getProtocols() const { + return ArrayRef(qual_begin(), getNumProtocols()); + } + + /// Whether this is a "__kindof" type as written. + bool isKindOfTypeAsWritten() const { return ObjCObjectTypeBits.IsKindOf; } + + /// Whether this ia a "__kindof" type (semantically). + bool isKindOfType() const; + + /// Retrieve the type of the superclass of this object type. + /// + /// This operation substitutes any type arguments into the + /// superclass of the current class type, potentially producing a + /// specialization of the superclass type. Produces a null type if + /// there is no superclass. + QualType getSuperClassType() const { + if (!CachedSuperClassType.getInt()) + computeSuperClassTypeSlow(); + + assert(CachedSuperClassType.getInt() && "Superclass not set?"); + return QualType(CachedSuperClassType.getPointer(), 0); + } + + /// Strip off the Objective-C "kindof" type and (with it) any + /// protocol qualifiers. + QualType stripObjCKindOfTypeAndQuals(const ASTContext &ctx) const; + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -4491,21 +4685,27 @@ class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { // will need to be modified. ObjCObjectTypeImpl(QualType Canonical, QualType Base, - ObjCProtocolDecl * const *Protocols, - unsigned NumProtocols) - : ObjCObjectType(Canonical, Base, Protocols, NumProtocols) {} + ArrayRef typeArgs, + ArrayRef protocols, + bool isKindOf) + : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {} public: void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, QualType Base, - ObjCProtocolDecl *const *protocols, - unsigned NumProtocols); + ArrayRef typeArgs, + ArrayRef protocols, + bool isKindOf); }; +inline QualType *ObjCObjectType::getTypeArgStorage() { + return reinterpret_cast(static_cast(this)+1); +} + inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { - return reinterpret_cast( - static_cast(this) + 1); + return reinterpret_cast( + getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs); } /// ObjCInterfaceType - Interfaces are the core concept in Objective-C for @@ -4556,9 +4756,14 @@ public: }; inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { - if (const ObjCInterfaceType *T = - getBaseType()->getAs()) - return T->getDecl(); + QualType baseType = getBaseType(); + while (const ObjCObjectType *ObjT = baseType->getAs()) { + if (const ObjCInterfaceType *T = dyn_cast(ObjT)) + return T->getDecl(); + + baseType = ObjT->getBaseType(); + } + return nullptr; } @@ -4575,7 +4780,11 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, false, false, false, false), + : Type(ObjCObjectPointer, Canonical, + Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), + Pointee->isVariablyModifiedType(), + Pointee->containsUnexpandedParameterPack()), PointeeType(Pointee) {} friend class ASTContext; // ASTContext creates these. @@ -4617,9 +4826,7 @@ public: /// qualifiers on the interface are ignored. /// /// \return null if the base type for this pointer is 'id' or 'Class' - const ObjCInterfaceType *getInterfaceType() const { - return getObjectType()->getBaseType()->getAs(); - } + const ObjCInterfaceType *getInterfaceType() const; /// getInterfaceDecl - If this pointer points to an Objective \@interface /// type, gets the declaration for that interface. @@ -4641,6 +4848,12 @@ public: return getObjectType()->isObjCUnqualifiedClass(); } + /// isObjCIdOrClassType - True if this is equivalent to the 'id' or + /// 'Class' type, + bool isObjCIdOrClassType() const { + return getObjectType()->isObjCUnqualifiedIdOrClass(); + } + /// isObjCQualifiedIdType - True if this is equivalent to 'id

' for some /// non-empty set of protocols. bool isObjCQualifiedIdType() const { @@ -4653,6 +4866,34 @@ public: return getObjectType()->isObjCQualifiedClass(); } + /// Whether this is a "__kindof" type. + bool isKindOfType() const { return getObjectType()->isKindOfType(); } + + /// Whether this type is specialized, meaning that it has type arguments. + bool isSpecialized() const { return getObjectType()->isSpecialized(); } + + /// Whether this type is specialized, meaning that it has type arguments. + bool isSpecializedAsWritten() const { + return getObjectType()->isSpecializedAsWritten(); + } + + /// Whether this type is unspecialized, meaning that is has no type arguments. + bool isUnspecialized() const { return getObjectType()->isUnspecialized(); } + + /// Determine whether this object type is "unspecialized" as + /// written, meaning that it has no type arguments. + bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } + + /// Retrieve the type arguments for this type. + ArrayRef getTypeArgs() const { + return getObjectType()->getTypeArgs(); + } + + /// Retrieve the type arguments for this type. + ArrayRef getTypeArgsAsWritten() const { + return getObjectType()->getTypeArgsAsWritten(); + } + /// An iterator over the qualifiers on the object type. Provided /// for convenience. This will always iterate over the full set of /// protocols on a type, not just those provided directly. @@ -4683,6 +4924,19 @@ public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } + /// Retrieve the type of the superclass of this object pointer type. + /// + /// This operation substitutes any type arguments into the + /// superclass of the current class type, potentially producing a + /// pointer to a specialization of the superclass type. Produces a + /// null type if there is no superclass. + QualType getSuperClassType() const; + + /// Strip off the Objective-C "kindof" type and (with it) any + /// protocol qualifiers. + const ObjCObjectPointerType *stripObjCKindOfTypeAndQuals( + const ASTContext &ctx) const; + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); } diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index e29fa4903282..f4d20b8d526a 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -177,6 +177,9 @@ public: memcpy(getOpaqueData(), Other.getOpaqueData(), Size); } + /// Copies the other type loc into this one. + void copy(TypeLoc other); + friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; } @@ -185,6 +188,10 @@ public: return !(LHS == RHS); } + /// Find the location of the nullability specifier (__nonnull, + /// __nullable, or __null_unspecifier), if there is one. + SourceLocation findNullabilityLoc() const; + private: static bool isKind(const TypeLoc&) { return true; @@ -249,6 +256,10 @@ public: // do nothing } + void copyLocal(TypeLoc other) { + // do nothing + } + TypeLoc getNextTypeLoc() const { return getUnqualifiedLoc(); } @@ -339,6 +350,20 @@ public: return size; } + void copyLocal(Derived other) { + // Some subclasses have no data to copy. + if (asDerived()->getLocalDataSize() == 0) return; + + // Copy the fixed-sized local data. + memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData)); + + // Copy the variable-sized local data. We need to do this + // separately because the padding in the source and the padding in + // the destination might be different. + memcpy(getExtraLocalData(), other.getExtraLocalData(), + asDerived()->getExtraLocalDataSize()); + } + TypeLoc getNextTypeLoc() const { return getNextTypeLoc(asDerived()->getInnerType()); } @@ -799,9 +824,11 @@ public: }; -struct ObjCProtocolListLocInfo { - SourceLocation LAngleLoc; - SourceLocation RAngleLoc; +struct ObjCObjectTypeLocInfo { + SourceLocation TypeArgsLAngleLoc; + SourceLocation TypeArgsRAngleLoc; + SourceLocation ProtocolLAngleLoc; + SourceLocation ProtocolRAngleLoc; bool HasBaseTypeAsWritten; }; @@ -813,25 +840,59 @@ struct ObjCProtocolListLocInfo { class ObjCObjectTypeLoc : public ConcreteTypeLoc { - // SourceLocations are stored after Info, one for each Protocol. + ObjCObjectTypeLocInfo> { + // TypeSourceInfo*'s are stored after Info, one for each type argument. + TypeSourceInfo **getTypeArgLocArray() const { + return (TypeSourceInfo**)this->getExtraLocalData(); + } + + // SourceLocations are stored after the type argument information, one for + // each Protocol. SourceLocation *getProtocolLocArray() const { - return (SourceLocation*) this->getExtraLocalData(); + return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs()); } public: - SourceLocation getLAngleLoc() const { - return this->getLocalData()->LAngleLoc; + SourceLocation getTypeArgsLAngleLoc() const { + return this->getLocalData()->TypeArgsLAngleLoc; } - void setLAngleLoc(SourceLocation Loc) { - this->getLocalData()->LAngleLoc = Loc; + void setTypeArgsLAngleLoc(SourceLocation Loc) { + this->getLocalData()->TypeArgsLAngleLoc = Loc; } - SourceLocation getRAngleLoc() const { - return this->getLocalData()->RAngleLoc; + SourceLocation getTypeArgsRAngleLoc() const { + return this->getLocalData()->TypeArgsRAngleLoc; } - void setRAngleLoc(SourceLocation Loc) { - this->getLocalData()->RAngleLoc = Loc; + void setTypeArgsRAngleLoc(SourceLocation Loc) { + this->getLocalData()->TypeArgsRAngleLoc = Loc; + } + + unsigned getNumTypeArgs() const { + return this->getTypePtr()->getTypeArgsAsWritten().size(); + } + + TypeSourceInfo *getTypeArgTInfo(unsigned i) const { + assert(i < getNumTypeArgs() && "Index is out of bounds!"); + return getTypeArgLocArray()[i]; + } + + void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) { + assert(i < getNumTypeArgs() && "Index is out of bounds!"); + getTypeArgLocArray()[i] = TInfo; + } + + SourceLocation getProtocolLAngleLoc() const { + return this->getLocalData()->ProtocolLAngleLoc; + } + void setProtocolLAngleLoc(SourceLocation Loc) { + this->getLocalData()->ProtocolLAngleLoc = Loc; + } + + SourceLocation getProtocolRAngleLoc() const { + return this->getLocalData()->ProtocolRAngleLoc; + } + void setProtocolRAngleLoc(SourceLocation Loc) { + this->getLocalData()->ProtocolRAngleLoc = Loc; } unsigned getNumProtocols() const { @@ -852,6 +913,11 @@ public: return *(this->getTypePtr()->qual_begin() + i); } + + ArrayRef getProtocolLocs() const { + return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols()); + } + bool hasBaseTypeAsWritten() const { return getLocalData()->HasBaseTypeAsWritten; } @@ -865,23 +931,27 @@ public: } SourceRange getLocalSourceRange() const { - return SourceRange(getLAngleLoc(), getRAngleLoc()); + SourceLocation start = getTypeArgsLAngleLoc(); + if (start.isInvalid()) + start = getProtocolLAngleLoc(); + SourceLocation end = getProtocolRAngleLoc(); + if (end.isInvalid()) + end = getTypeArgsRAngleLoc(); + return SourceRange(start, end); } - void initializeLocal(ASTContext &Context, SourceLocation Loc) { - setHasBaseTypeAsWritten(true); - setLAngleLoc(Loc); - setRAngleLoc(Loc); - for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) - setProtocolLoc(i, Loc); - } + void initializeLocal(ASTContext &Context, SourceLocation Loc); unsigned getExtraLocalDataSize() const { - return this->getNumProtocols() * sizeof(SourceLocation); + return this->getNumTypeArgs() * sizeof(TypeSourceInfo *) + + this->getNumProtocols() * sizeof(SourceLocation); } unsigned getExtraLocalDataAlignment() const { - return llvm::alignOf(); + assert(llvm::alignOf() + >= llvm::alignOf() && + "not enough alignment for tail-allocated data"); + return llvm::alignOf(); } QualType getInnerType() const { diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index e7a97a7ff745..281d6370e5c8 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -112,7 +112,7 @@ private: /// /// FIXME: Do we want to support this now that we have bind()? template -internal::Matcher id(const std::string &ID, +internal::Matcher id(StringRef ID, const internal::BindableMatcher &InnerMatcher) { return InnerMatcher.bind(ID); } diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index cbaa4ba27ce7..b494647d79bc 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -140,8 +140,7 @@ public: }; /// \brief Add a binding from an id to a node. - void setBinding(const std::string &Id, - const ast_type_traits::DynTypedNode &DynNode) { + void setBinding(StringRef Id, const ast_type_traits::DynTypedNode &DynNode) { if (Bindings.empty()) Bindings.emplace_back(); for (BoundNodesMap &Binding : Bindings) diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h index 78aa9dc82a98..c391b24a3330 100644 --- a/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -242,7 +242,7 @@ struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps { /// /// Supported types: /// - \c unsigned -/// - \c std::string +/// - \c llvm::StringRef /// - \c VariantMatcher (\c DynTypedMatcher / \c Matcher) class VariantValue { public: @@ -254,7 +254,7 @@ public: /// \brief Specific constructors for each supported type. VariantValue(unsigned Unsigned); - VariantValue(const std::string &String); + VariantValue(StringRef String); VariantValue(const VariantMatcher &Matchers); /// \brief Returns true iff this is not an empty value. @@ -269,7 +269,7 @@ public: /// \brief String value functions. bool isString() const; const std::string &getString() const; - void setString(const std::string &String); + void setString(StringRef String); /// \brief Matcher value functions. bool isMatcher() const; diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 2bbce37e57bb..fb1eb58dcc70 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -976,6 +976,11 @@ def TypeNullUnspecified : TypeAttr { let Documentation = [TypeNullUnspecifiedDocs]; } +def ObjCKindOf : TypeAttr { + let Spellings = [Keyword<"__kindof">]; + let Documentation = [Undocumented]; +} + def AssumeAligned : InheritableAttr { let Spellings = [GCC<"assume_aligned">]; let Subjects = SubjectList<[ObjCMethod, Function]>; @@ -1276,9 +1281,8 @@ def Pascal : InheritableAttr { def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"features">]; - let Subjects = - SubjectList<[Function], ErrorDiag, "ExpectedFunctionMethodOrClass">; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[Function], ErrorDiag>; + let Documentation = [TargetDocs]; } def TransparentUnion : InheritableAttr { diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 107458e46145..e4ca0cb4778e 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -678,6 +678,25 @@ The semantics are as follows: }]; } +def TargetDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute. +This attribute may be attached to a function definition and instructs +the backend to use different code generation options than were passed on the +command line. + +The current set of options correspond to the existing "subtarget features" for +the target with or without a "-mno-" in front corresponding to the absence +of the feature, as well as ``arch="CPU"`` which will change the default "CPU" +for the function. + +Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", +"avx", "xop" and largely correspond to the machine specific options handled by +the front end. +}]; +} + def DocCatAMDGPURegisterAttributes : DocumentationCategory<"AMD GPU Register Attributes"> { let Content = [{ diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def index 02e52947ed6c..fdf1cb0b5a40 100644 --- a/include/clang/Basic/BuiltinsPPC.def +++ b/include/clang/Basic/BuiltinsPPC.def @@ -248,6 +248,11 @@ BUILTIN(__builtin_altivec_crypto_vpmsumh, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_crypto_vpmsumw, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_crypto_vpmsumd, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vclzb, "V16UcV16Uc", "") +BUILTIN(__builtin_altivec_vclzh, "V8UsV8Us", "") +BUILTIN(__builtin_altivec_vclzw, "V4UiV4Ui", "") +BUILTIN(__builtin_altivec_vclzd, "V2ULLiV2ULLi", "") + // VSX built-ins. BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "") @@ -279,6 +284,47 @@ BUILTIN(__builtin_vsx_xvcmpgesp, "V4UiV4fV4f", "") BUILTIN(__builtin_vsx_xvcmpgtdp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpgtsp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvrdpim, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvrspim, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xvrdpi, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvrspi, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xvrdpic, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvrspic, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xvrdpiz, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvrspiz, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xvmaddadp, "V2dV2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvmaddasp, "V4fV4fV4fV4f", "") + +BUILTIN(__builtin_vsx_xvmsubadp, "V2dV2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvmsubasp, "V4fV4fV4fV4f", "") + +BUILTIN(__builtin_vsx_xvmuldp, "V2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvmulsp, "V4fV4fV4f", "") + +BUILTIN(__builtin_vsx_xvnmaddadp, "V2dV2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvnmaddasp, "V4fV4fV4fV4f", "") + +BUILTIN(__builtin_vsx_xvnmsubadp, "V2dV2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvnmsubasp, "V4fV4fV4fV4f", "") + +BUILTIN(__builtin_vsx_xvredp, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvresp, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xvrsqrtedp, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvrsqrtesp, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xvsqrtdp, "V2dV2d", "") +BUILTIN(__builtin_vsx_xvsqrtsp, "V4fV4f", "") + +BUILTIN(__builtin_vsx_xxleqv, "V4UiV4UiV4Ui", "") + +BUILTIN(__builtin_vsx_xvcpsgndp, "V2dV2dV2d", "") +BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "") + // HTM builtins BUILTIN(__builtin_tbegin, "UiUIi", "") BUILTIN(__builtin_tend, "UiUIi", "") diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index aaf279f3713f..1cd8973cbd6d 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -1157,5 +1157,65 @@ BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "") BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "") BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "") BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_blendmb_128_mask, "V16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_blendmb_256_mask, "V32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_blendmw_128_mask, "V8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_blendmw_256_mask, "V16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pabsb128_mask, "V16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pabsb256_mask, "V32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_pabsw128_mask, "V8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pabsw256_mask, "V16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_packssdw128_mask, "V8sV4iV4iV8sUc", "") +BUILTIN(__builtin_ia32_packssdw256_mask, "V16sV8iV8iV16sUs", "") +BUILTIN(__builtin_ia32_packsswb128_mask, "V16cV8sV8sV16cUs", "") +BUILTIN(__builtin_ia32_packsswb256_mask, "V32cV16sV16sV32cUi", "") +BUILTIN(__builtin_ia32_packusdw128_mask, "V8sV4iV4iV8sUc", "") +BUILTIN(__builtin_ia32_packusdw256_mask, "V16sV8iV8iV16sUs", "") +BUILTIN(__builtin_ia32_packuswb128_mask, "V16cV8sV8sV16cUs", "") +BUILTIN(__builtin_ia32_packuswb256_mask, "V32cV16sV16sV32cUi", "") +BUILTIN(__builtin_ia32_paddsb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_paddsb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_paddsw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_paddsw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_paddusb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_paddusb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_paddusw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_paddusw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pavgb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pavgb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_pavgw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pavgw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pmaxsb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pmaxsb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_pmaxsw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pmaxsw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pmaxub128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pmaxub256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_pmaxuw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pmaxuw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pminsb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pminsb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_pminsw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pminsw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pminub128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pminub256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_pminuw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pminuw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pshufb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_pshufb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_psubsb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_psubsb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_psubsw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_psubsw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_psubusb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_psubusb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_psubusw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_psubusw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_vpermi2varhi128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_vpermi2varhi256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_vpermt2varhi128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_vpermt2varhi128_maskz, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_vpermt2varhi256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_vpermt2varhi256_maskz, "V16sV16sV16sV16sUs", "") #undef BUILTIN diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index dece8f9ed2ec..e1a23120c186 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -21,6 +21,7 @@ def Named : Decl<1>; def TypedefName : DDecl; def Typedef : DDecl; def TypeAlias : DDecl; + def ObjCTypeParam : DDecl; def UnresolvedUsingTypename : DDecl; def Tag : DDecl, DeclContext; def Enum : DDecl; diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index 24813c67c2f5..ff42683ecdde 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -179,6 +179,8 @@ def err_target_unsupported_fpmath : Error< "the '%0' unit is not supported with this instruction set">; def err_target_unsupported_unaligned : Error< "the %0 sub-architecture does not support unaligned accesses">; +def err_opt_not_valid_with_opt : Error< + "option '%0' cannot be specified with '%1'">; // Source manager def err_cannot_open_file : Error<"cannot open file '%0': %1">, DefaultFatal; diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 7c0696a1b922..f7f09da4ea6e 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -69,8 +69,6 @@ def err_drv_no_module_support : Error< "'%0': unable to use module files with this tool">; def err_drv_clang_unsupported : Error< "the clang compiler does not support '%0'">; -def err_drv_clang_unsupported_per_platform : Error< - "the clang compiler does not support '%0' on this platform">; def err_drv_clang_unsupported_opt_cxx_darwin_i386 : Error< "the clang compiler does not support '%0' for C++ on Darwin/i386">; def err_drv_command_failed : Error< diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 85796cc0d325..4ecd5d5e1842 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -280,6 +280,7 @@ def FunctionDefInObjCContainer : DiagGroup<"function-def-in-objc-container">; def BadFunctionCast : DiagGroup<"bad-function-cast">; def ObjCPropertyImpl : DiagGroup<"objc-property-implementation">; def ObjCPropertyNoAttribute : DiagGroup<"objc-property-no-attribute">; +def ObjCProtocolQualifiers : DiagGroup<"objc-protocol-qualifiers">; def ObjCMissingSuperCalls : DiagGroup<"objc-missing-super-calls">; def ObjCDesignatedInit : DiagGroup<"objc-designated-initializers">; def ObjCRetainBlockProperty : DiagGroup<"objc-noncopy-retain-block-property">; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 6a11d240c63c..1364b982ecf1 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -1004,10 +1004,6 @@ def err_pragma_invalid_keyword : Error< def warn_pragma_unroll_cuda_value_in_parens : Warning< "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">, InGroup; - -def err_empty_attribute_block : Error< - "Microsoft attribute block cannot be empty">; - } // end of Parse Issue category. let CategoryName = "Modules Issue" in { @@ -1017,4 +1013,16 @@ def err_module_expected_semi : Error< "expected ';' after module name">; } +let CategoryName = "Generics Issue" in { + +def err_objc_expected_type_parameter : Error< + "expected type parameter name">; + +def err_objc_parameterized_implementation : Error< + "@implementation cannot have type parameters">; + +def err_objc_type_args_after_protocols : Error< + "protocol qualifiers must precede type arguments">; +} + } // end of Parser diagnostics diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 750219483c6c..fb1e3f1cb46e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -188,6 +188,8 @@ def ext_flexible_array_init : Extension< "flexible array initialization is a GNU extension">, InGroup; // Declarations. +def err_redeclaration_different_type : Error< + "redeclaration of %0 with a different type%diff{: $ vs $|}1,2">; def err_bad_variable_name : Error< "%0 cannot be the name of a variable or data member">; def err_bad_parameter_name : Error< @@ -978,6 +980,12 @@ def warning_multiple_selectors: Warning< "several methods with selector %0 of mismatched types are found " "for the @selector expression">, InGroup, DefaultIgnore; + +def err_objc_kindof_nonobject : Error< + "'__kindof' specifier cannot be applied to non-object type %0">; +def err_objc_kindof_wrong_position : Error< + "'__kindof' type specifier must precede the declarator">; + // C++ declarations def err_static_assert_expression_is_not_constant : Error< "static_assert expression is not an integral constant expression">; @@ -2131,6 +2139,11 @@ def warn_concatenated_nsarray_literal : Warning< InGroup; def note_objc_literal_comparison_isequal : Note< "use 'isEqual:' instead">; +def warn_objc_collection_literal_element : Warning< + "object of type %0 is not compatible with " + "%select{array element type|dictionary key type|dictionary value type}1 %2">, + InGroup; + def err_attribute_argument_is_zero : Error< "%0 attribute must be greater than 0">; def warn_attribute_argument_n_negative : Warning< @@ -2148,6 +2161,10 @@ def warn_objc_redundant_literal_use : Warning< def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", " "\"local-dynamic\", \"initial-exec\" or \"local-exec\"">; +def err_tls_var_aligned_over_maximum : Error< + "alignment (%0) of thread-local variable %1 is greater than the maximum supported " + "alignment (%2) for a thread-local variable on this target">; + def err_only_annotate_after_access_spec : Error< "access specifier can only have annotation attributes">; @@ -4740,6 +4757,8 @@ def warn_division_by_zero : Warning<"division by zero is undefined">, InGroup; def warn_remainder_by_zero : Warning<"remainder by zero is undefined">, InGroup; +def warn_shift_lhs_negative : Warning<"shifting a negative signed value is undefined">, + InGroup>; def warn_shift_negative : Warning<"shift count is negative">, InGroup>; def warn_shift_gt_typewidth : Warning<"shift count >= width of type">, @@ -5576,6 +5595,8 @@ def err_seh_try_outside_functions : Error< "cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">; def err_mixing_cxx_try_seh_try : Error< "cannot use C++ 'try' in the same function as SEH '__try'">; +def err_seh_try_unsupported : Error< + "SEH '__try' is not supported on this target">; def note_conflicting_try_here : Note< "conflicting %0 here">; def warn_jump_out_of_seh_finally : Warning< @@ -7740,6 +7761,84 @@ def warn_nullability_missing : Warning< "type specifier (_Nonnull, _Nullable, or _Null_unspecified)">, InGroup; +def err_type_arg_explicit_nullability : Error< + "type argument %0 cannot explicitly specify nullability">; + +def err_type_param_bound_explicit_nullability : Error< + "type parameter %0 bound %1 cannot explicitly specify nullability">; + } +let CategoryName = "Generics Issue" in { + +def err_objc_type_param_bound_nonobject : Error< + "type bound %0 for type parameter %1 is not an Objective-C pointer type">; + +def err_objc_type_param_bound_missing_pointer : Error< + "missing '*' in type bound %0 for type parameter %1">; + +def err_objc_type_param_redecl : Error< + "redeclaration of type parameter %0">; + +def err_objc_type_param_arity_mismatch : Error< + "%select{forward class declaration|class definition|category|extension}0 has " + "too %select{few|many}1 type parameters (expected %2, have %3)">; + +def err_objc_type_param_bound_conflict : Error< + "type bound %0 for type parameter %1 conflicts with " + "%select{implicit|previous}2 bound %3%select{for type parameter %5|}4">; + +def err_objc_type_param_variance_conflict : Error< + "%select{in|co|contra}0variant type parameter %1 conflicts with previous " + "%select{in|co|contra}2variant type parameter %3">; + +def note_objc_type_param_here : Note<"type parameter %0 declared here">; + +def err_objc_type_param_bound_missing : Error< + "missing type bound %0 for type parameter %1 in %select{@interface|@class}2">; + +def err_objc_parameterized_category_nonclass : Error< + "%select{extension|category}0 of non-parameterized class %1 cannot have type " + "parameters">; + +def err_objc_parameterized_forward_class : Error< + "forward declaration of non-parameterized class %0 cannot have type " + "parameters">; + +def err_objc_parameterized_forward_class_first : Error< + "class %0 previously declared with type parameters">; + +def err_objc_type_arg_missing_star : Error< + "type argument %0 must be a pointer (requires a '*')">; + +def err_objc_type_arg_missing : Error< + "no type or protocol named %0">; + +def err_objc_type_args_and_protocols : Error< + "angle brackets contain both a %select{type|protocol}0 (%1) and a " + "%select{protocol|type}0 (%2)">; + +def err_objc_type_args_non_class : Error< + "type arguments cannot be applied to non-class type %0">; + +def err_objc_type_args_non_parameterized_class : Error< + "type arguments cannot be applied to non-parameterized class %0">; + +def err_objc_type_args_specialized_class : Error< + "type arguments cannot be applied to already-specialized class type %0">; + +def err_objc_type_args_wrong_arity : Error< + "too %select{many|few}0 type arguments for class %1 (have %2, expected %3)">; +} + +def err_objc_type_arg_not_id_compatible : Error< + "type argument %0 is neither an Objective-C object nor a block type">; + +def err_objc_type_arg_does_not_match_bound : Error< + "type argument %0 does not satisfy the bound (%1) of type parameter %2">; + +def warn_objc_redundant_qualified_class_type : Warning< + "parameterized class %0 already conforms to the protocols listed; did you " + "forget a '*'?">, InGroup; + } // end of sema component. diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 33a8b747c62d..1785e04b91ca 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -49,7 +49,7 @@ class IdentifierInfo { // Objective-C keyword ('protocol' in '@protocol') or builtin (__builtin_inf). // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values // are for builtins. - unsigned ObjCOrBuiltinID :11; + unsigned ObjCOrBuiltinID :13; bool HasMacro : 1; // True if there is a #define for this. bool HadMacro : 1; // True if there was a #define for this. bool IsExtension : 1; // True if identifier is a lang extension. @@ -69,7 +69,7 @@ class IdentifierInfo { // stored externally. bool IsModulesImport : 1; // True if this is the 'import' contextual // keyword. - // 32-bit word is filled. + // 30 bit left in 64-bit word. void *FETokenInfo; // Managed by the language front-end. llvm::StringMapEntry *Entry; diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index b27605b15d28..8d606a12d046 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -161,6 +161,7 @@ LANGOPT(NativeHalfType , 1, 0, "Native half type support") LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns") LANGOPT(CUDA , 1, 0, "CUDA") LANGOPT(OpenMP , 1, 0, "OpenMP support") +LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls") LANGOPT(CUDAIsDevice , 1, 0, "Compiling for CUDA device") LANGOPT(CUDAAllowHostCallsFromHostDevice, 1, 0, "Allow host device functions to call host functions") LANGOPT(CUDADisableTargetCallChecks, 1, 0, "Disable checks for call targets (host, device, etc.)") diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h index 78c1ddb56f9b..98e70dee45e5 100644 --- a/include/clang/Basic/Sanitizers.h +++ b/include/clang/Basic/Sanitizers.h @@ -17,8 +17,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/StringRef.h" - -#include +#include "llvm/Support/MathExtras.h" namespace clang { @@ -47,22 +46,28 @@ enum SanitizerOrdinal : uint64_t { } struct SanitizerSet { - SanitizerSet(); + SanitizerSet() : Mask(0) {} /// \brief Check if a certain (single) sanitizer is enabled. - bool has(SanitizerMask K) const; + bool has(SanitizerMask K) const { + assert(llvm::isPowerOf2_64(K)); + return Mask & K; + } /// \brief Check if one or more sanitizers are enabled. - bool hasOneOf(SanitizerMask K) const; + bool hasOneOf(SanitizerMask K) const { return Mask & K; } /// \brief Enable or disable a certain (single) sanitizer. - void set(SanitizerMask K, bool Value); + void set(SanitizerMask K, bool Value) { + assert(llvm::isPowerOf2_64(K)); + Mask = Value ? (Mask | K) : (Mask & ~K); + } /// \brief Disable all sanitizers. - void clear(); + void clear() { Mask = 0; } /// \brief Returns true if at least one sanitizer is enabled. - bool empty() const; + bool empty() const { return Mask == 0; } /// \brief Bitmask of enabled sanitizers. SanitizerMask Mask; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index a3bb535fa26f..39f575f90ef8 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -70,6 +70,7 @@ protected: unsigned char MinGlobalAlign; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short MaxVectorAlign; + unsigned short MaxTLSAlign; unsigned short SimdDefaultAlign; const char *DescriptionString; const char *UserLabelPrefix; @@ -809,6 +810,21 @@ public: return TLSSupported; } + /// \brief Return the maximum alignment (in bits) of a TLS variable + /// + /// Gets the maximum alignment (in bits) of a TLS variable on this target. + /// Returns zero if there is no such constraint. + unsigned short getMaxTLSAlign() const { + return MaxTLSAlign; + } + + /// \brief Whether the target supports SEH __try. + bool isSEHTrySupported() const { + return getTriple().isOSWindows() && + (getTriple().getArch() == llvm::Triple::x86 || + getTriple().getArch() == llvm::Triple::x86_64); + } + /// \brief Return true if {|} are normal characters in the asm string. /// /// If this returns false (the default), then {abc|xyz} is syntax diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index ed2aa82d17e1..7a91c9f502b7 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -526,6 +526,11 @@ KEYWORD(__bridge_transfer , KEYARC) KEYWORD(__bridge_retained , KEYARC) KEYWORD(__bridge_retain , KEYARC) +// Objective-C keywords. +KEYWORD(__covariant , KEYOBJC2) +KEYWORD(__contravariant , KEYOBJC2) +KEYWORD(__kindof , KEYOBJC2) + // Alternate spelling for various tokens. There are GCC extensions in all // languages, but should not be disabled in strict conformance mode. ALIAS("__alignof__" , __alignof , KEYALL) diff --git a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h new file mode 100644 index 000000000000..4540efb29781 --- /dev/null +++ b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h @@ -0,0 +1,43 @@ +//===-- CodeGen/ObjectFilePCHContainerOperations.h - ------------*- 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_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H +#define LLVM_CLANG_CODEGEN_OBJECT_FILE_PCH_CONTAINER_OPERATIONS_H + +#include "clang/Frontend/PCHContainerOperations.h" + +namespace clang { + +/// \brief A PCHContainerOperations implementation that uses LLVM to +/// wraps Clang modules inside a COFF, ELF, or Mach-O container. +class ObjectFilePCHContainerOperations + : public PCHContainerOperations { + /// \brief Return an ASTConsumer that can be chained with a + /// PCHGenerator that produces a wrapper file format + /// that also contains full debug info for the module. + std::unique_ptr + CreatePCHContainerGenerator( + DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, const TargetOptions &TO, + const LangOptions &LO, const std::string &MainFileName, + const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, + std::shared_ptr Buffer) const override; + + /// \brief Initialize an llvm::BitstreamReader with the serialized + /// AST inside the PCH container Buffer. + void ExtractPCH(llvm::MemoryBufferRef Buffer, + llvm::BitstreamReader &StreamFile) const override; + + +}; + +} + + +#endif diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h index dd0261c2f3a1..fddd15885e18 100644 --- a/include/clang/Driver/Action.h +++ b/include/clang/Driver/Action.h @@ -41,6 +41,8 @@ public: enum ActionClass { InputClass = 0, BindArchClass, + CudaDeviceClass, + CudaHostClass, PreprocessJobClass, PrecompileJobClass, AnalyzeJobClass, @@ -71,16 +73,16 @@ private: unsigned OwnsInputs : 1; protected: - Action(ActionClass _Kind, types::ID _Type) - : Kind(_Kind), Type(_Type), OwnsInputs(true) {} - Action(ActionClass _Kind, std::unique_ptr Input, types::ID _Type) - : Kind(_Kind), Type(_Type), Inputs(1, Input.release()), OwnsInputs(true) { + Action(ActionClass Kind, types::ID Type) + : Kind(Kind), Type(Type), OwnsInputs(true) {} + Action(ActionClass Kind, std::unique_ptr Input, types::ID Type) + : Kind(Kind), Type(Type), Inputs(1, Input.release()), OwnsInputs(true) { } - Action(ActionClass _Kind, std::unique_ptr Input) - : Kind(_Kind), Type(Input->getType()), Inputs(1, Input.release()), + Action(ActionClass Kind, std::unique_ptr Input) + : Kind(Kind), Type(Input->getType()), Inputs(1, Input.release()), OwnsInputs(true) {} - Action(ActionClass _Kind, const ActionList &_Inputs, types::ID _Type) - : Kind(_Kind), Type(_Type), Inputs(_Inputs), OwnsInputs(true) {} + Action(ActionClass Kind, const ActionList &Inputs, types::ID Type) + : Kind(Kind), Type(Type), Inputs(Inputs), OwnsInputs(true) {} public: virtual ~Action(); @@ -108,7 +110,7 @@ class InputAction : public Action { const llvm::opt::Arg &Input; public: - InputAction(const llvm::opt::Arg &_Input, types::ID _Type); + InputAction(const llvm::opt::Arg &Input, types::ID Type); const llvm::opt::Arg &getInputArg() const { return Input; } @@ -124,7 +126,7 @@ class BindArchAction : public Action { const char *ArchName; public: - BindArchAction(std::unique_ptr Input, const char *_ArchName); + BindArchAction(std::unique_ptr Input, const char *ArchName); const char *getArchName() const { return ArchName; } @@ -133,6 +135,41 @@ public: } }; +class CudaDeviceAction : public Action { + virtual void anchor(); + /// GPU architecture to bind -- e.g 'sm_35'. + const char *GpuArchName; + /// True when action results are not consumed by the host action (e.g when + /// -fsyntax-only or --cuda-device-only options are used). + bool AtTopLevel; + +public: + CudaDeviceAction(std::unique_ptr Input, const char *ArchName, + bool AtTopLevel); + + const char *getGpuArchName() const { return GpuArchName; } + bool isAtTopLevel() const { return AtTopLevel; } + + static bool classof(const Action *A) { + return A->getKind() == CudaDeviceClass; + } +}; + +class CudaHostAction : public Action { + virtual void anchor(); + ActionList DeviceActions; + +public: + CudaHostAction(std::unique_ptr Input, + const ActionList &DeviceActions); + ~CudaHostAction() override; + + ActionList &getDeviceActions() { return DeviceActions; } + const ActionList &getDeviceActions() const { return DeviceActions; } + + static bool classof(const Action *A) { return A->getKind() == CudaHostClass; } +}; + class JobAction : public Action { virtual void anchor(); protected: diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td index cf6b76bf29f2..907b16fd5caf 100644 --- a/include/clang/Driver/CLCompatOptions.td +++ b/include/clang/Driver/CLCompatOptions.td @@ -188,7 +188,7 @@ def _SLASH_EP : CLFlag<"EP">, def _SLASH_FA : CLFlag<"FA">, HelpText<"Output assembly code file during compilation">; def _SLASH_Fa : CLJoined<"Fa">, - HelpText<"Output assembly code to this file during compilation">, + HelpText<"Output assembly code to this file during compilation (with /FA)">, MetaVarName<"">; def _SLASH_fallback : CLCompileFlag<"fallback">, HelpText<"Fall back to cl.exe if clang-cl fails to compile">; @@ -198,10 +198,10 @@ def _SLASH_Fe : CLJoined<"Fe">, HelpText<"Set output executable file or directory (ends in / or \\)">, MetaVarName<"">; def _SLASH_Fi : CLCompileJoined<"Fi">, - HelpText<"Set preprocess output file name">, + HelpText<"Set preprocess output file name (with /P)">, MetaVarName<"">; def _SLASH_Fo : CLCompileJoined<"Fo">, - HelpText<"Set output object file, or directory (ends in / or \\)">, + HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">, MetaVarName<"">; def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 15c194b09848..4a67fdb6532a 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -405,12 +405,12 @@ public: bool IsUsingLTO(const llvm::opt::ArgList &Args) const; private: - /// \brief Retrieves a ToolChain for a particular target triple. + /// \brief Retrieves a ToolChain for a particular \p Target triple. /// /// Will cache ToolChains for the life of the driver object, and create them /// on-demand. const ToolChain &getToolChain(const llvm::opt::ArgList &Args, - StringRef DarwinArchName = "") const; + const llvm::Triple &Target) const; /// @} diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h index 8fc2e8d3a5b9..186244bacf31 100644 --- a/include/clang/Driver/Job.h +++ b/include/clang/Driver/Job.h @@ -106,6 +106,9 @@ public: const char *getExecutable() const { return Executable; } const llvm::opt::ArgStringList &getArguments() const { return Arguments; } + + /// Print a command argument, and optionally quote it. + static void printArg(llvm::raw_ostream &OS, const char *Arg, bool Quote); }; /// Like Command, but with a fallback which is executed in case diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 6a75b7c2c157..6e5dbf225bb6 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -351,6 +351,12 @@ def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group, MetaVarName<"">; def c : Flag<["-"], "c">, Flags<[DriverOption]>, HelpText<"Only run preprocess, compile, and assemble steps">; +def cuda_device_only : Flag<["--"], "cuda-device-only">, + HelpText<"Do device-side CUDA compilation only">; +def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, + Flags<[DriverOption, HelpHidden]>, HelpText<"CUDA GPU architecture">; +def cuda_host_only : Flag<["--"], "cuda-host-only">, + HelpText<"Do host-side CUDA compilation only">; def dA : Flag<["-"], "dA">, Group; def dD : Flag<["-"], "dD">, Group, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode in addition to normal output">; @@ -422,13 +428,24 @@ def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">, def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">, Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Generate instrumented code to collect execution counts into (overridden by LLVM_PROFILE_FILE env var)">; -def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group; +def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group, + Flags<[DriverOption]>; def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">, Group, Flags<[CC1Option]>, HelpText<"Use instrumentation data for profile-guided optimization">; def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">, Group, Flags<[CC1Option]>, HelpText<"Generate coverage mapping to enable code coverage analysis">; +def fprofile_generate : Flag<["-"], "fprofile-generate">, + Alias; +def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">, + Group, Flags<[DriverOption]>, MetaVarName<"">, + HelpText<"Generate instrumented code to collect execution counts into /default.profraw (overridden by LLVM_PROFILE_FILE env var)">; +def fprofile_use : Flag<["-"], "fprofile-use">, Group, + Alias; +def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, + Group, Flags<[DriverOption]>, MetaVarName<"">, + HelpText<"Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from /default.profdata. Otherwise, it reads from file .">; def fblocks : Flag<["-"], "fblocks">, Group, Flags<[CC1Option]>, HelpText<"Enable the 'blocks' language feature">; @@ -522,7 +539,8 @@ def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group, Flags<[CC1Option, CoreOption]>, MetaVarName<"">, HelpText<"Turn on runtime checks for various forms of undefined " "or suspicious behavior. See user manual for available checks ">; -def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group; +def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group, + Flags<[CoreOption]>; def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Path to blacklist file for sanitizers">; @@ -547,24 +565,29 @@ def fsanitize_memory_track_origins : Flag<["-"], "fsanitize-memory-track-origins def fno_sanitize_memory_track_origins : Flag<["-"], "fno-sanitize-memory-track-origins">, Group, Flags<[CC1Option]>, HelpText<"Disable origins tracking in MemorySanitizer">; +def fsanitize_memory_use_after_dtor : Flag<["-"], "fsanitize-memory-use-after-dtor">, + Group, Flags<[CC1Option]>, + HelpText<"Enable use-after-destroy detection in MemorySanitizer">; def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">, Group, Flags<[CC1Option]>, HelpText<"Level of field padding for AddressSanitizer">; -def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group; +def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group, + Flags<[CoreOption]>; def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, - Group; + Group, Flags<[CoreOption]>; def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">, Group, - Flags<[CC1Option]>, + Flags<[CC1Option, CoreOption]>, HelpText<"Enable recovery for specified sanitizers">; def fno_sanitize_recover_EQ : CommaJoined<["-"], "fno-sanitize-recover=">, - Group, + Group, Flags<[CoreOption]>, HelpText<"Disable recovery for specified sanitizers">; def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Enable trapping for specified sanitizers">; def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group, + Flags<[CoreOption]>, HelpText<"Disable trapping for specified sanitizers">; def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">, Group; @@ -641,7 +664,7 @@ def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group; def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group; def flto_EQ : Joined<["-"], "flto=">, Group; -def flto : Flag<["-"], "flto">, Group; +def flto : Flag<["-"], "flto">, Flags<[CC1Option]>, Group; def fno_lto : Flag<["-"], "fno-lto">, Group; def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, Group, Flags<[DriverOption, CoreOption]>; @@ -879,6 +902,8 @@ def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group; def fopenmp : Flag<["-"], "fopenmp">, Group, Flags<[CC1Option, NoArgumentUnused]>; def fno_openmp : Flag<["-"], "fno-openmp">, Group, Flags<[NoArgumentUnused]>; def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group; +def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group, Flags<[NoArgumentUnused]>; +def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group, Flags<[CC1Option, NoArgumentUnused]>; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group; def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group; def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">; @@ -904,7 +929,6 @@ def fpie : Flag<["-"], "fpie">, Group; def fno_pie : Flag<["-"], "fno-pie">, Group; def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group; def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group; -def fprofile_generate : Flag<["-"], "fprofile-generate">, Group; def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>; def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group; def freg_struct_return : Flag<["-"], "freg-struct-return">, Group, Flags<[CC1Option]>, @@ -1518,7 +1542,8 @@ def print_libgcc_file_name : Flag<["-", "--"], "print-libgcc-file-name">, HelpText<"Print the library path for \"libgcc.a\"">; def print_multi_directory : Flag<["-", "--"], "print-multi-directory">; def print_multi_lib : Flag<["-", "--"], "print-multi-lib">; -def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">; +def print_multi_os_directory : Flag<["-", "--"], "print-multi-os-directory">, + Flags<[Unsupported]>; def print_prog_name_EQ : Joined<["-", "--"], "print-prog-name=">, HelpText<"Print the full program path of ">, MetaVarName<"">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, @@ -1527,6 +1552,7 @@ def private__bundle : Flag<["-"], "private_bundle">; def pthreads : Flag<["-"], "pthreads">; def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>, HelpText<"Support POSIX threads in generated code">; +def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>; def p : Flag<["-"], "p">; def pie : Flag<["-"], "pie">; def read__only__relocs : Separate<["-"], "read_only_relocs">; @@ -1793,8 +1819,6 @@ defm : BooleanFFlag<"keep-inline-functions">, Group, Group; -def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group; def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group; defm align_functions : BooleanFFlag<"align-functions">, Group; diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index 11bfd417e1ea..82b668ac883a 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -29,6 +29,7 @@ class SanitizerArgs { std::vector BlacklistFiles; int CoverageFeatures; int MsanTrackOrigins; + bool MsanUseAfterDtor; int AsanFieldPadding; bool AsanZeroBaseShadow; bool AsanSharedRuntime; diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def index 4b696ae5e053..d1b69151b062 100644 --- a/include/clang/Driver/Types.def +++ b/include/clang/Driver/Types.def @@ -44,6 +44,7 @@ TYPE("c", C, PP_C, "c", "u") TYPE("cl", CL, PP_C, "cl", "u") TYPE("cuda-cpp-output", PP_CUDA, INVALID, "cui", "u") TYPE("cuda", CUDA, PP_CUDA, "cu", "u") +TYPE("cuda", CUDA_DEVICE, PP_CUDA, "cu", "") TYPE("objective-c-cpp-output", PP_ObjC, INVALID, "mi", "u") TYPE("objc-cpp-output", PP_ObjC_Alias, INVALID, "mi", "u") TYPE("objective-c", ObjC, PP_ObjC, "m", "u") diff --git a/include/clang/Driver/Types.h b/include/clang/Driver/Types.h index 34442eb6379f..dd95d6599156 100644 --- a/include/clang/Driver/Types.h +++ b/include/clang/Driver/Types.h @@ -63,6 +63,9 @@ namespace types { /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers). bool isCXX(ID Id); + /// isCuda - Is this a CUDA input. + bool isCuda(ID Id); + /// isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers). bool isObjC(ID Id); diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 6f9523cdc1ba..f8c8c373e143 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -166,6 +166,9 @@ struct FormatStyle { /// Like \c Attach, but break before braces on function, namespace and /// class definitions. BS_Linux, + /// Like ``Attach``, but break before braces on enum, function, and record + /// definitions. + BS_Mozilla, /// Like \c Attach, but break before function definitions, and 'else'. BS_Stroustrup, /// Always break before braces. @@ -290,6 +293,12 @@ struct FormatStyle { /// \brief Language, this format style is targeted at. LanguageKind Language; + /// \brief A regular expression matching macros that start a block. + std::string MacroBlockBegin; + + /// \brief A regular expression matching macros that end a block. + std::string MacroBlockEnd; + /// \brief The maximum number of consecutive empty lines to keep. unsigned MaxEmptyLinesToKeep; @@ -479,6 +488,8 @@ struct FormatStyle { IndentWrappedFunctionNames == R.IndentWrappedFunctionNames && KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && + MacroBlockBegin == R.MacroBlockBegin && + MacroBlockEnd == R.MacroBlockEnd && MaxEmptyLinesToKeep == R.MaxEmptyLinesToKeep && NamespaceIndentation == R.NamespaceIndentation && ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index d34cf0cad1c9..803d0233046d 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -67,6 +67,8 @@ CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to ///< be generated. +CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the + ///< compile step. CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled. CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled. @@ -110,6 +112,8 @@ CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero ///< offset in AddressSanitizer. CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer +CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection + ///< in MemorySanitizer CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage ///< instrumentation. CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 66597bd0af8e..53246bcf22c1 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -155,6 +155,7 @@ public: std::vector DependentLibraries; /// Name of the profile file to use as output for -fprofile-instr-generate + /// and -fprofile-generate. std::string InstrProfileOutput; /// Name of the profile file to use with -fprofile-sample-use. diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 9cd806c99b85..2f3e1b6cebb1 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -30,6 +30,7 @@ namespace llvm { class raw_fd_ostream; class Timer; +class TimerGroup; } namespace clang { @@ -101,7 +102,10 @@ class CompilerInstance : public ModuleLoader { /// \brief The semantic analysis object. std::unique_ptr TheSema; - /// \brief The frontend timer + /// \brief The frontend timer group. + std::unique_ptr FrontendTimerGroup; + + /// \brief The frontend timer. std::unique_ptr FrontendTimer; /// \brief The ASTReader, if one exists. @@ -157,9 +161,10 @@ class CompilerInstance : public ModuleLoader { std::string TempFilename; std::unique_ptr OS; - OutputFile(const std::string &filename, const std::string &tempFilename, + OutputFile(std::string filename, std::string tempFilename, std::unique_ptr OS) - : Filename(filename), TempFilename(tempFilename), OS(std::move(OS)) {} + : Filename(std::move(filename)), TempFilename(std::move(tempFilename)), + OS(std::move(OS)) {} OutputFile(OutputFile &&O) : Filename(std::move(O.Filename)), TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {} @@ -614,7 +619,7 @@ public: /// /// \return - The new object on success, or null on failure. static IntrusiveRefCntPtr createPCHExternalASTSource( - StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, + StringRef Path, StringRef Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, const PCHContainerOperations &PCHContainerOps, void *DeserializationListener, bool OwnDeserializationListener, @@ -627,11 +632,9 @@ public: /// Create a code completion consumer to print code completion results, at /// \p Filename, \p Line, and \p Column, to the given output stream \p OS. - static CodeCompleteConsumer * - createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, - unsigned Line, unsigned Column, - const CodeCompleteOptions &Opts, - raw_ostream &OS); + static CodeCompleteConsumer *createCodeCompletionConsumer( + Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column, + const CodeCompleteOptions &Opts, raw_ostream &OS); /// \brief Create the Sema object to be used for parsing. void createSema(TranslationUnitKind TUKind, diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 2b18a7df53dd..0b03c4aa1cd7 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -452,9 +452,13 @@ public: /// \param HomeDir The directory in which relative paths within this module /// map file will be resolved. /// + /// \param ExternModuleLoc The location of the "extern module" declaration + /// that caused us to load this module map file, if any. + /// /// \returns true if an error occurred, false otherwise. bool parseModuleMapFile(const FileEntry *File, bool IsSystem, - const DirectoryEntry *HomeDir); + const DirectoryEntry *HomeDir, + SourceLocation ExternModuleLoc = SourceLocation()); /// \brief Dump the contents of the module map, for debugging purposes. void dump(); diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index bba0c38cec77..b2f58ead0e75 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -786,6 +786,22 @@ public: (!getLangOpts().Modules || (bool)getMacroDefinition(II)); } + /// \brief Determine whether II is defined as a macro within the module M, + /// if that is a module that we've already preprocessed. Does not check for + /// macros imported into M. + bool isMacroDefinedInLocalModule(const IdentifierInfo *II, Module *M) { + if (!II->hasMacroDefinition()) + return false; + auto I = Submodules.find(M); + if (I == Submodules.end()) + return false; + auto J = I->second.Macros.find(II); + if (J == I->second.Macros.end()) + return false; + auto *MD = J->second.getLatest(); + return MD && MD->isDefined(); + } + MacroDefinition getMacroDefinition(const IdentifierInfo *II) { if (!II->hasMacroDefinition()) return MacroDefinition(); diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 97a0aa482d2b..fb9eb8ff5af8 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -46,6 +46,8 @@ namespace clang { class PoisonSEHIdentifiersRAIIObject; class VersionTuple; class OMPClause; + class ObjCTypeParamList; + class ObjCTypeParameter; /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has @@ -1246,6 +1248,13 @@ private: DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, ParsedAttributes &prefixAttrs); + ObjCTypeParamList *parseObjCTypeParamList(); + ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs( + SourceLocation &lAngleLoc, + SmallVectorImpl &protocolIdents, + SourceLocation &rAngleLoc, + bool mayBeProtocolList = true); + void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc, BalancedDelimiterTracker &T, SmallVectorImpl &AllIvarDecls, @@ -1258,8 +1267,48 @@ private: bool WarnOnDeclarations, bool ForObjCContainer, SourceLocation &LAngleLoc, - SourceLocation &EndProtoLoc); - bool ParseObjCProtocolQualifiers(DeclSpec &DS); + SourceLocation &EndProtoLoc, + bool consumeLastToken); + + /// Parse the first angle-bracket-delimited clause for an + /// Objective-C object or object pointer type, which may be either + /// type arguments or protocol qualifiers. + void parseObjCTypeArgsOrProtocolQualifiers( + ParsedType baseType, + SourceLocation &typeArgsLAngleLoc, + SmallVectorImpl &typeArgs, + SourceLocation &typeArgsRAngleLoc, + SourceLocation &protocolLAngleLoc, + SmallVectorImpl &protocols, + SmallVectorImpl &protocolLocs, + SourceLocation &protocolRAngleLoc, + bool consumeLastToken, + bool warnOnIncompleteProtocols); + + /// Parse either Objective-C type arguments or protocol qualifiers; if the + /// former, also parse protocol qualifiers afterward. + void parseObjCTypeArgsAndProtocolQualifiers( + ParsedType baseType, + SourceLocation &typeArgsLAngleLoc, + SmallVectorImpl &typeArgs, + SourceLocation &typeArgsRAngleLoc, + SourceLocation &protocolLAngleLoc, + SmallVectorImpl &protocols, + SmallVectorImpl &protocolLocs, + SourceLocation &protocolRAngleLoc, + bool consumeLastToken); + + /// Parse a protocol qualifier type such as '', which is + /// an anachronistic way of writing 'id'. + TypeResult parseObjCProtocolQualifierType(SourceLocation &rAngleLoc); + + /// Parse Objective-C type arguments and protocol qualifiers, extending the + /// current type with the parsed result. + TypeResult parseObjCTypeArgsAndProtocolQualifiers(SourceLocation loc, + ParsedType type, + bool consumeLastToken, + SourceLocation &endLoc); + void ParseObjCInterfaceDeclList(tok::ObjCKeywordKind contextKey, Decl *CDecl); DeclGroupPtrTy ParseObjCAtProtocolDeclaration(SourceLocation atLoc, @@ -2469,7 +2518,8 @@ private: typedef SmallVector TemplateArgList; bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, - bool ConsumeLastToken); + bool ConsumeLastToken, + bool ObjCGenericList); bool ParseTemplateIdAfterTemplateName(TemplateTy Template, SourceLocation TemplateNameLoc, const CXXScopeSpec &SS, diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index de65c43c76b2..97022738d03e 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -765,11 +765,13 @@ public: /// \param Allocator The allocator that will be used to allocate the /// string itself. CodeCompletionString *CreateCodeCompletionString(Sema &S, + const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments); CodeCompletionString *CreateCodeCompletionString(ASTContext &Ctx, Preprocessor &PP, + const CodeCompletionContext &CCContext, CodeCompletionAllocator &Allocator, CodeCompletionTUInfo &CCTUInfo, bool IncludeBriefComments); diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index d375ec303785..41d490063299 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -373,14 +373,6 @@ private: // Scope specifier for the type spec, if applicable. CXXScopeSpec TypeScope; - // List of protocol qualifiers for objective-c classes. Used for - // protocol-qualified interfaces "NString" and protocol-qualified id - // "id". - Decl * const *ProtocolQualifiers; - unsigned NumProtocolQualifiers; - SourceLocation ProtocolLAngleLoc; - SourceLocation *ProtocolLocs; - // SourceLocation info. These are null if the item wasn't specified or if // the setting was synthesized. SourceRange Range; @@ -442,16 +434,10 @@ public: Constexpr_specified(false), Concept_specified(false), Attrs(attrFactory), - ProtocolQualifiers(nullptr), - NumProtocolQualifiers(0), - ProtocolLocs(nullptr), writtenBS(), ObjCQualifiers(nullptr) { } - ~DeclSpec() { - delete [] ProtocolQualifiers; - delete [] ProtocolLocs; - } + // storage-class-specifier SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } TSCS getThreadStorageClassSpec() const { @@ -490,6 +476,8 @@ public: bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; } bool isTypeAltiVecBool() const { return TypeAltiVecBool; } bool isTypeSpecOwned() const { return TypeSpecOwned; } + bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); } + ParsedType getRepAsType() const { assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); return TypeRep; @@ -751,19 +739,6 @@ public: Attrs.takeAllFrom(attrs); } - typedef Decl * const *ProtocolQualifierListTy; - ProtocolQualifierListTy getProtocolQualifiers() const { - return ProtocolQualifiers; - } - SourceLocation *getProtocolLocs() const { return ProtocolLocs; } - unsigned getNumProtocolQualifiers() const { - return NumProtocolQualifiers; - } - SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; } - void setProtocolQualifiers(Decl * const *Protos, unsigned NP, - SourceLocation *ProtoLocs, - SourceLocation LAngleLoc); - /// Finish - This does final analysis of the declspec, issuing diagnostics for /// things like "_Imaginary" (lacking an FP type). After calling this method, /// DeclSpec is guaranteed self-consistent, even if an error occurred. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 72a0e0b19e3d..db7b6f954c1b 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1387,7 +1387,8 @@ public: /// Determine if \p D has a visible definition. If not, suggest a declaration /// that should be made visible to expose the definition. - bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested); + bool hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, + bool OnlyNeedComplete = false); bool hasVisibleDefinition(const NamedDecl *D) { NamedDecl *Hidden; return hasVisibleDefinition(const_cast(D), &Hidden); @@ -1848,7 +1849,7 @@ public: bool isAcceptableTagRedeclaration(const TagDecl *Previous, TagTypeKind NewTag, bool isDefinition, SourceLocation NewTagLoc, - const IdentifierInfo &Name); + const IdentifierInfo *Name); enum TagUseKind { TUK_Reference, // Reference to a tag: 'struct foo *X;' @@ -2187,6 +2188,7 @@ public: void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType); + void maybeExtendBlockObject(ExprResult &E); CastKind PrepareCastToObjCObjectPointer(ExprResult &E); bool CheckPointerConversion(Expr *From, QualType ToType, CastKind &Kind, @@ -7088,16 +7090,44 @@ public: }; ObjCContainerKind getObjCContainerKind() const; - Decl *ActOnStartClassInterface(SourceLocation AtInterfaceLoc, + DeclResult actOnObjCTypeParam(Scope *S, + ObjCTypeParamVariance variance, + SourceLocation varianceLoc, + unsigned index, + IdentifierInfo *paramName, + SourceLocation paramLoc, + SourceLocation colonLoc, + ParsedType typeBound); + + ObjCTypeParamList *actOnObjCTypeParamList(Scope *S, SourceLocation lAngleLoc, + ArrayRef typeParams, + SourceLocation rAngleLoc); + void popObjCTypeParamList(Scope *S, ObjCTypeParamList *typeParamList); + + Decl *ActOnStartClassInterface(Scope *S, + SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, + ObjCTypeParamList *typeParamList, IdentifierInfo *SuperName, SourceLocation SuperLoc, + ArrayRef SuperTypeArgs, + SourceRange SuperTypeArgsRange, Decl * const *ProtoRefs, unsigned NumProtoRefs, const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); + + void ActOnSuperClassOfClassInterface(Scope *S, + SourceLocation AtInterfaceLoc, + ObjCInterfaceDecl *IDecl, + IdentifierInfo *ClassName, + SourceLocation ClassLoc, + IdentifierInfo *SuperName, + SourceLocation SuperLoc, + ArrayRef SuperTypeArgs, + SourceRange SuperTypeArgsRange); void ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, IdentifierInfo *SuperName, @@ -7124,6 +7154,7 @@ public: Decl *ActOnStartCategoryInterface(SourceLocation AtInterfaceLoc, IdentifierInfo *ClassName, SourceLocation ClassLoc, + ObjCTypeParamList *typeParamList, IdentifierInfo *CategoryName, SourceLocation CategoryLoc, Decl * const *ProtoRefs, @@ -7147,9 +7178,10 @@ public: ArrayRef Decls); DeclGroupPtrTy ActOnForwardClassDeclaration(SourceLocation Loc, - IdentifierInfo **IdentList, - SourceLocation *IdentLocs, - unsigned NumElts); + IdentifierInfo **IdentList, + SourceLocation *IdentLocs, + ArrayRef TypeParamLists, + unsigned NumElts); DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, const IdentifierLocPair *IdentList, @@ -7161,6 +7193,61 @@ public: unsigned NumProtocols, SmallVectorImpl &Protocols); + /// Given a list of identifiers (and their locations), resolve the + /// names to either Objective-C protocol qualifiers or type + /// arguments, as appropriate. + void actOnObjCTypeArgsOrProtocolQualifiers( + Scope *S, + ParsedType baseType, + SourceLocation lAngleLoc, + ArrayRef identifiers, + ArrayRef identifierLocs, + SourceLocation rAngleLoc, + SourceLocation &typeArgsLAngleLoc, + SmallVectorImpl &typeArgs, + SourceLocation &typeArgsRAngleLoc, + SourceLocation &protocolLAngleLoc, + SmallVectorImpl &protocols, + SourceLocation &protocolRAngleLoc, + bool warnOnIncompleteProtocols); + + /// Build a an Objective-C protocol-qualified 'id' type where no + /// base type was specified. + TypeResult actOnObjCProtocolQualifierType( + SourceLocation lAngleLoc, + ArrayRef protocols, + ArrayRef protocolLocs, + SourceLocation rAngleLoc); + + /// Build a specialized and/or protocol-qualified Objective-C type. + TypeResult actOnObjCTypeArgsAndProtocolQualifiers( + Scope *S, + SourceLocation Loc, + ParsedType BaseType, + SourceLocation TypeArgsLAngleLoc, + ArrayRef TypeArgs, + SourceLocation TypeArgsRAngleLoc, + SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, + ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc); + + /// Build an Objective-C object pointer type. + QualType BuildObjCObjectType(QualType BaseType, + SourceLocation Loc, + SourceLocation TypeArgsLAngleLoc, + ArrayRef TypeArgs, + SourceLocation TypeArgsRAngleLoc, + SourceLocation ProtocolLAngleLoc, + ArrayRef Protocols, + ArrayRef ProtocolLocs, + SourceLocation ProtocolRAngleLoc, + bool FailOnError = false); + + /// Check the application of the Objective-C '__kindof' qualifier to + /// the given type. + bool checkObjCKindOfType(QualType &type, SourceLocation loc); + /// Ensure attributes are consistent with type. /// \param [in, out] Attributes The attributes to check; they will /// be modified to be consistent with \p PropertyTy. @@ -7610,13 +7697,13 @@ private: void DestroyDataSharingAttributesStack(); ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind); - /// \brief Checks if the specified variable is used in one of the private +public: + /// \brief Check if the specified variable is used in a private clause in + /// Checks if the specified variable is used in one of the private /// clauses in OpenMP constructs. bool IsOpenMPCapturedVar(VarDecl *VD); -public: - /// \brief Check if the specified variable is used in one of the private - /// clauses in OpenMP constructs. + /// OpenMP constructs. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level); diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index b822b11126ea..416ef7b1a682 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -413,6 +413,7 @@ namespace clang { #define LINKAGESPEC(DERIVED, BASE) #define OBJCCOMPATIBLEALIAS(DERIVED, BASE) #define OBJCMETHOD(DERIVED, BASE) +#define OBJCTYPEPARAM(DERIVED, BASE) #define OBJCIVAR(DERIVED, BASE) #define OBJCPROPERTY(DERIVED, BASE) #define OBJCPROPERTYIMPL(DERIVED, BASE) diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index ee8e3f4c6712..4b662077c3c8 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -1105,7 +1105,9 @@ namespace clang { /// \brief An OMPThreadPrivateDecl record. DECL_OMP_THREADPRIVATE, /// \brief An EmptyDecl record. - DECL_EMPTY + DECL_EMPTY, + /// \brief An ObjCTypeParamDecl record. + DECL_OBJC_TYPE_PARAM, }; /// \brief Record codes for each kind of statement or expression. diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index ef5b107a2fda..9377dfac99cc 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -42,6 +42,7 @@ #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/Timer.h" #include #include #include @@ -380,6 +381,9 @@ private: /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; + /// \brief A timer used to track the time spent deserializing. + std::unique_ptr ReadTimer; + /// \brief The location where the module file will be considered as /// imported from. For non-module AST types it should be invalid. SourceLocation CurrentImportLoc; @@ -976,12 +980,14 @@ private: MergedLookups; typedef llvm::DenseMap > - MergedDeclsMap; + KeyDeclsMap; - /// \brief A mapping from canonical declarations to the set of additional - /// (global, previously-canonical) declaration IDs that have been merged with - /// that canonical declaration. - MergedDeclsMap MergedDecls; + /// \brief A mapping from canonical declarations to the set of global + /// declaration IDs for key declaration that have been merged with that + /// canonical declaration. A key declaration is a formerly-canonical + /// declaration whose module did not import any other key declaration for that + /// entity. These are the IDs that we use as keys when finding redecl chains. + KeyDeclsMap KeyDecls; /// \brief A mapping from DeclContexts to the semantic DeclContext that we /// are treating as the definition of the entity. This is used, for instance, @@ -1054,6 +1060,36 @@ public: void ResolveImportedPath(ModuleFile &M, std::string &Filename); static void ResolveImportedPath(std::string &Filename, StringRef Prefix); + /// \brief Returns the first key declaration for the given declaration. This + /// is one that is formerly-canonical (or still canonical) and whose module + /// did not import any other key declaration of the entity. + Decl *getKeyDeclaration(Decl *D) { + D = D->getCanonicalDecl(); + if (D->isFromASTFile()) + return D; + + auto I = KeyDecls.find(D); + if (I == KeyDecls.end() || I->second.empty()) + return D; + return GetExistingDecl(I->second[0]); + } + const Decl *getKeyDeclaration(const Decl *D) { + return getKeyDeclaration(const_cast(D)); + } + + /// \brief Run a callback on each imported key declaration of \p D. + template + void forEachImportedKeyDecl(const Decl *D, Fn Visit) { + D = D->getCanonicalDecl(); + if (D->isFromASTFile()) + Visit(D); + + auto It = KeyDecls.find(const_cast(D)); + if (It != KeyDecls.end()) + for (auto ID : It->second) + Visit(GetExistingDecl(ID)); + } + private: struct ImportedModule { ModuleFile *Mod; @@ -1124,18 +1160,6 @@ private: /// merged into its redecl chain. Decl *getMostRecentExistingDecl(Decl *D); - template - void forEachFormerlyCanonicalImportedDecl(const Decl *D, Fn Visit) { - D = D->getCanonicalDecl(); - if (D->isFromASTFile()) - Visit(D); - - auto It = MergedDecls.find(const_cast(D)); - if (It != MergedDecls.end()) - for (auto ID : It->second) - Visit(GetExistingDecl(ID)); - } - RecordLocation DeclCursorForID(serialization::DeclID ID, unsigned &RawLocation); void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); @@ -1261,12 +1285,16 @@ public: /// /// \param UseGlobalIndex If true, the AST reader will try to load and use /// the global module index. + /// + /// \param ReadTimer If non-null, a timer used to track the time spent + /// deserializing. ASTReader(Preprocessor &PP, ASTContext &Context, const PCHContainerOperations &PCHContainerOps, StringRef isysroot = "", bool DisableValidation = false, bool AllowASTWithCompilerErrors = false, bool AllowConfigurationMismatch = false, - bool ValidateSystemInputs = false, bool UseGlobalIndex = true); + bool ValidateSystemInputs = false, bool UseGlobalIndex = true, + std::unique_ptr ReadTimer = {}); ~ASTReader() override; @@ -1690,7 +1718,7 @@ public: /// \brief Notify ASTReader that we started deserialization of /// a decl or type so until FinishedDeserializing is called there may be /// decls that are initializing. Must be paired with FinishedDeserializing. - void StartedDeserializing() override { ++NumCurrentElementsDeserializing; } + void StartedDeserializing() override; /// \brief Notify ASTReader that we finished the deserialization of /// a decl or type. Must be paired with StartedDeserializing. diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index c966d3edeb9f..e830fdcf8f20 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -398,7 +398,7 @@ private: /// \brief The set of declarations that may have redeclaration chains that /// need to be serialized. - llvm::SmallSetVector Redeclarations; + llvm::SmallVector Redeclarations; /// \brief Statements that we've encountered while serializing a /// declaration or type. diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h index ca68a74fef96..c9724c08da2d 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -64,6 +64,9 @@ #endif namespace clang { +class DiagnosticsEngine; +class AnalyzerOptions; + namespace ento { class CheckerOptInfo; @@ -118,6 +121,10 @@ public: void initializeManager(CheckerManager &mgr, SmallVectorImpl &opts) const; + /// Check if every option corresponds to a specific checker or package. + void validateCheckerOptions(const AnalyzerOptions &opts, + DiagnosticsEngine &diags) const; + /// Prints the name and description of all checkers in this registry. /// This output is not intended to be machine-parseable. void printHelp(raw_ostream &out, size_t maxNameChars = 30) const ; -- cgit v1.2.3