diff options
Diffstat (limited to 'include/clang')
201 files changed, 5442 insertions, 2949 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 736a10b..b2730e4 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -129,11 +129,7 @@ public: /// required. /// /// \param RD The class whose vtable was used. - /// - /// \param DefinitionRequired Whether a definition of this vtable is - /// required in this translation unit; otherwise, it is only needed if - /// it was actually used. - virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {} + virtual void HandleVTable(CXXRecordDecl *RD) {} /// \brief If the consumer is interested in entities getting modified after /// their initial creation, it should return a pointer to diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 195d748..049221a 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -284,6 +284,11 @@ class ASTContext : public RefCountedBase<ASTContext> { /// merged into. llvm::DenseMap<Decl*, Decl*> MergedDecls; + /// \brief A mapping from a defining declaration to a list of modules (other + /// than the owning module of the declaration) that contain merged + /// definitions of that entity. + llvm::DenseMap<NamedDecl*, llvm::TinyPtrVector<Module*>> MergedDefModules; + public: /// \brief A type synonym for the TemplateOrInstantiation mapping. typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *> @@ -383,6 +388,7 @@ private: ImportDecl *LastLocalImport; TranslationUnitDecl *TUDecl; + mutable ExternCContextDecl *ExternCContext; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -780,8 +786,26 @@ public: MergedDecls[D] = Primary; } + /// \brief Note that the definition \p ND has been merged into module \p M, + /// and should be visible whenever \p M is visible. + void mergeDefinitionIntoModule(NamedDecl *ND, Module *M, + bool NotifyListeners = true); + /// \brief Clean up the merged definition list. Call this if you might have + /// added duplicates into the list. + void deduplicateMergedDefinitonsFor(NamedDecl *ND); + + /// \brief Get the additional modules in which the definition \p Def has + /// been merged. + ArrayRef<Module*> getModulesWithMergedDefinition(NamedDecl *Def) { + auto MergedIt = MergedDefModules.find(Def); + if (MergedIt == MergedDefModules.end()) + return None; + return MergedIt->second; + } + TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } + ExternCContextDecl *getExternCContextDecl() const; // Builtin Types. CanQualType VoidTy; @@ -1689,6 +1713,10 @@ public: /// beneficial for performance to overalign a data type. unsigned getPreferredTypeAlign(const Type *T) const; + /// \brief Return the default alignment for __attribute__((aligned)) on + /// this target, to be used if no alignment value is specified. + unsigned getTargetDefaultAlignForAttributeAligned(void) const; + /// \brief Return the alignment in bits that should be given to a /// global variable with type \p T. unsigned getAlignOfGlobalVar(QualType T) const; @@ -1936,6 +1964,8 @@ public: /// cv-qualifiers. QualType getSignatureParameterType(QualType T) const; + QualType getExceptionObjectType(QualType T) const; + /// \brief Return the properly qualified result of decaying the specified /// array type to a pointer. /// @@ -2191,6 +2221,18 @@ public: /// it is not used. bool DeclMustBeEmitted(const Decl *D); + const CXXConstructorDecl * + getCopyConstructorForExceptionObject(CXXRecordDecl *RD); + + void addCopyConstructorForExceptionObject(CXXRecordDecl *RD, + CXXConstructorDecl *CD); + + void addDefaultArgExprForConstructor(const CXXConstructorDecl *CD, + unsigned ParmIdx, Expr *DAE); + + Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, + unsigned ParmIdx); + void setManglingNumber(const NamedDecl *ND, unsigned Number); unsigned getManglingNumber(const NamedDecl *ND) const; @@ -2263,8 +2305,8 @@ public: static unsigned NumImplicitDestructorsDeclared; private: - ASTContext(const ASTContext &) LLVM_DELETED_FUNCTION; - void operator=(const ASTContext &) LLVM_DELETED_FUNCTION; + ASTContext(const ASTContext &) = delete; + void operator=(const ASTContext &) = delete; public: /// \brief Initialize built-in types. diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index a335f98..ee48955 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -121,6 +121,11 @@ namespace clang { /// if an error occurred. Decl *Import(Decl *FromD); + /// \brief Return the copy of the given declaration in the "to" context if + /// it has already been imported from the "from" context. Otherwise return + /// NULL. + Decl *GetAlreadyImportedOrNull(Decl *FromD); + /// \brief Import the given declaration context from the "from" /// AST context into the "to" AST context. /// diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index 48eb629..4f3acc3 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -13,16 +13,17 @@ #ifndef LLVM_CLANG_AST_ASTMUTATIONLISTENER_H #define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H -#include "clang/Basic/SourceLocation.h" - namespace clang { - class CXXRecordDecl; class ClassTemplateDecl; class ClassTemplateSpecializationDecl; + class CXXDestructorDecl; + class CXXRecordDecl; class Decl; class DeclContext; class FunctionDecl; class FunctionTemplateDecl; + class Module; + class NamedDecl; class ObjCCategoryDecl; class ObjCContainerDecl; class ObjCInterfaceDecl; @@ -72,6 +73,10 @@ public: /// \brief A function's return type has been deduced. virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType); + /// \brief A virtual destructor's operator delete has been resolved. + virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD, + const FunctionDecl *Delete) {} + /// \brief An implicit member got a definition. virtual void CompletedImplicitDefinition(const FunctionDecl *D) {} @@ -108,6 +113,13 @@ public: /// \param D the declaration marked OpenMP threadprivate. virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {} + /// \brief A definition has been made visible by being redefined locally. + /// + /// \param D The definition that was previously not visible. + /// \param M The containing module in which the definition was made visible, + /// if any. + virtual void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {} + // NOTE: If new methods are added they should also be added to // MultiplexASTMutationListener. }; diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h index 84b0842..9078a0e 100644 --- a/include/clang/AST/ASTUnresolvedSet.h +++ b/include/clang/AST/ASTUnresolvedSet.h @@ -76,7 +76,7 @@ public: } void append(ASTContext &C, iterator I, iterator E) { - Decls.append(C, I.ir, E.ir); + Decls.append(C, I.I, E.I); } DeclAccessPair &operator[](unsigned I) { return Decls[I]; } diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 787843e..4e282d6 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -20,6 +20,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" #include "llvm/ADT/SmallVector.h" @@ -52,8 +53,8 @@ protected: bool Inherited : 1; bool IsPackExpansion : 1; bool Implicit : 1; - - virtual ~Attr(); + bool IsLateParsed : 1; + bool DuplicatesAllowed : 1; void* operator new(size_t bytes) throw() { llvm_unreachable("Attrs cannot be allocated with regular 'new'."); @@ -65,7 +66,7 @@ protected: public: // Forward so that the regular new and delete do not hide global ones. void* operator new(size_t Bytes, ASTContext &C, - size_t Alignment = 16) throw() { + size_t Alignment = 8) throw() { return ::operator new(Bytes, C, Alignment); } void operator delete(void *Ptr, ASTContext &C, @@ -74,9 +75,11 @@ public: } protected: - Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) + Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, + bool IsLateParsed, bool DuplicatesAllowed) : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex), - Inherited(false), IsPackExpansion(false), Implicit(false) {} + Inherited(false), IsPackExpansion(false), Implicit(false), + IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {} public: @@ -85,7 +88,7 @@ public: } unsigned getSpellingListIndex() const { return SpellingListIndex; } - virtual const char *getSpelling() const = 0; + const char *getSpelling() const; SourceLocation getLocation() const { return Range.getBegin(); } SourceRange getRange() const { return Range; } @@ -102,25 +105,24 @@ public: bool isPackExpansion() const { return IsPackExpansion; } // Clone this attribute. - virtual Attr *clone(ASTContext &C) const = 0; + Attr *clone(ASTContext &C) const; - virtual bool isLateParsed() const { return false; } + bool isLateParsed() const { return IsLateParsed; } // Pretty print this attribute. - virtual void printPretty(raw_ostream &OS, - const PrintingPolicy &Policy) const = 0; + void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const; /// \brief By default, attributes cannot be duplicated when being merged; /// however, an attribute can override this. Returns true if the attribute /// can be duplicated when merging. - virtual bool duplicatesAllowed() const { return false; } + bool duplicatesAllowed() const { return DuplicatesAllowed; } }; class InheritableAttr : public Attr { - virtual void anchor(); protected: - InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0) - : Attr(AK, R, SpellingListIndex) {} + InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, + bool IsLateParsed, bool DuplicatesAllowed) + : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {} public: void setInherited(bool I) { Inherited = I; } @@ -132,11 +134,11 @@ public: }; class InheritableParamAttr : public InheritableAttr { - void anchor() override; protected: - InheritableParamAttr(attr::Kind AK, SourceRange R, - unsigned SpellingListIndex = 0) - : InheritableAttr(AK, R, SpellingListIndex) {} + InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, + bool IsLateParsed, bool DuplicatesAllowed) + : InheritableAttr(AK, R, SpellingListIndex, IsLateParsed, + DuplicatesAllowed) {} public: // Implement isa/cast/dyncast/etc. diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h index 39ee81f..a0c8030 100644 --- a/include/clang/AST/AttrIterator.h +++ b/include/clang/AST/AttrIterator.h @@ -24,7 +24,7 @@ namespace clang { // Defined in ASTContext.h void *operator new(size_t Bytes, const clang::ASTContext &C, - size_t Alignment = 16); + size_t Alignment = 8); // FIXME: Being forced to not have a default argument here due to redeclaration // rules on default arguments sucks void *operator new[](size_t Bytes, const clang::ASTContext &C, diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 37f6748..f7612f2 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -333,12 +333,12 @@ public: /// struct D : B, C { }; /// \endcode /// -/// This data structure contaings a mapping from every virtual +/// This data structure contains a mapping from every virtual /// function *that does not override an existing virtual function* and /// in every subobject where that virtual function occurs to the set /// of virtual functions that override it. Thus, the same virtual /// function \c A::f can actually occur in multiple subobjects of type -/// \c A due to multiple inheritance, and may be overriden by +/// \c A due to multiple inheritance, and may be overridden by /// different virtual functions in each, as in the following example: /// /// \code @@ -354,7 +354,7 @@ public: /// \c A::f but in *different* subobjects of type A. This is /// represented by numbering the subobjects in which the overridden /// and the overriding virtual member functions are located. Subobject -/// 0 represents the virtua base class subobject of that type, while +/// 0 represents the virtual base class subobject of that type, while /// subobject numbers greater than 0 refer to non-virtual base class /// subobjects of that type. class CXXFinalOverriderMap diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index aa3c846..b25800b 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -16,8 +16,8 @@ #define LLVM_CLANG_AST_CANONICALTYPE_H #include "clang/AST/Type.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/Casting.h" -#include <iterator> namespace clang { @@ -80,7 +80,7 @@ public: operator QualType() const { return Stored; } /// \brief Implicit conversion to bool. - LLVM_EXPLICIT operator bool() const { return !isNull(); } + explicit operator bool() const { return !isNull(); } bool isNull() const { return Stored.isNull(); @@ -381,93 +381,20 @@ namespace clang { /// \brief Iterator adaptor that turns an iterator over canonical QualTypes /// into an iterator over CanQualTypes. -template<typename InputIterator> -class CanTypeIterator { - InputIterator Iter; - -public: - typedef CanQualType value_type; - typedef value_type reference; - typedef CanProxy<Type> pointer; - typedef typename std::iterator_traits<InputIterator>::difference_type - difference_type; - typedef typename std::iterator_traits<InputIterator>::iterator_category - iterator_category; - - CanTypeIterator() : Iter() { } - explicit CanTypeIterator(InputIterator Iter) : Iter(Iter) { } - - // Input iterator - reference operator*() const { - return CanQualType::CreateUnsafe(*Iter); - } - - pointer operator->() const; - - CanTypeIterator &operator++() { - ++Iter; - return *this; - } - - CanTypeIterator operator++(int) { - CanTypeIterator Tmp(*this); - ++Iter; - return Tmp; - } - - friend bool operator==(const CanTypeIterator& X, const CanTypeIterator &Y) { - return X.Iter == Y.Iter; - } - friend bool operator!=(const CanTypeIterator& X, const CanTypeIterator &Y) { - return X.Iter != Y.Iter; - } - - // Bidirectional iterator - CanTypeIterator &operator--() { - --Iter; - return *this; - } - - CanTypeIterator operator--(int) { - CanTypeIterator Tmp(*this); - --Iter; - return Tmp; - } - - // Random access iterator - reference operator[](difference_type n) const { - return CanQualType::CreateUnsafe(Iter[n]); - } - - CanTypeIterator &operator+=(difference_type n) { - Iter += n; - return *this; - } - - CanTypeIterator &operator-=(difference_type n) { - Iter -= n; - return *this; - } - - friend CanTypeIterator operator+(CanTypeIterator X, difference_type n) { - X += n; - return X; - } - - friend CanTypeIterator operator+(difference_type n, CanTypeIterator X) { - X += n; - return X; - } - - friend CanTypeIterator operator-(CanTypeIterator X, difference_type n) { - X -= n; - return X; - } - - friend difference_type operator-(const CanTypeIterator &X, - const CanTypeIterator &Y) { - return X - Y; - } +template <typename InputIterator> +struct CanTypeIterator + : llvm::iterator_adaptor_base< + CanTypeIterator<InputIterator>, InputIterator, + typename std::iterator_traits<InputIterator>::iterator_category, + CanQualType, + typename std::iterator_traits<InputIterator>::difference_type, + CanProxy<Type>, CanQualType> { + CanTypeIterator() {} + explicit CanTypeIterator(InputIterator Iter) + : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {} + + CanQualType operator*() const { return CanQualType::CreateUnsafe(*this->I); } + CanProxy<Type> operator->() const; }; template<> @@ -727,9 +654,8 @@ CanProxy<T> CanQual<T>::operator->() const { return CanProxy<T>(*this); } -template<typename InputIterator> -typename CanTypeIterator<InputIterator>::pointer -CanTypeIterator<InputIterator>::operator->() const { +template <typename InputIterator> +CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const { return CanProxy<Type>(*this); } diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index ec6d83c..289f2fd 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -166,8 +166,8 @@ public: static const CommandInfo *getBuiltinCommandInfo(unsigned CommandID); private: - CommandTraits(const CommandTraits &) LLVM_DELETED_FUNCTION; - void operator=(const CommandTraits &) LLVM_DELETED_FUNCTION; + CommandTraits(const CommandTraits &) = delete; + void operator=(const CommandTraits &) = delete; const CommandInfo *getRegisteredCommandInfo(StringRef Name) const; const CommandInfo *getRegisteredCommandInfo(unsigned CommandID) const; diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index d995df9..f190b93 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -221,8 +221,8 @@ public: /// \brief Comment lexer. class Lexer { private: - Lexer(const Lexer &) LLVM_DELETED_FUNCTION; - void operator=(const Lexer &) LLVM_DELETED_FUNCTION; + Lexer(const Lexer &) = delete; + void operator=(const Lexer &) = delete; /// Allocator for strings that are semantic values of tokens and have to be /// computed (for example, resolved decimal character references). diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h index 2c444f0..42bf4c9 100644 --- a/include/clang/AST/CommentParser.h +++ b/include/clang/AST/CommentParser.h @@ -28,8 +28,8 @@ class CommandTraits; /// Doxygen comment parser. class Parser { - Parser(const Parser &) LLVM_DELETED_FUNCTION; - void operator=(const Parser &) LLVM_DELETED_FUNCTION; + Parser(const Parser &) = delete; + void operator=(const Parser &) = delete; friend class TextTokenRetokenizer; diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 4ae6fe0..9b05d39 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -31,8 +31,8 @@ namespace comments { class CommandTraits; class Sema { - Sema(const Sema &) LLVM_DELETED_FUNCTION; - void operator=(const Sema &) LLVM_DELETED_FUNCTION; + Sema(const Sema &) = delete; + void operator=(const Sema &) = delete; /// Allocator for AST nodes. llvm::BumpPtrAllocator &Allocator; diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h index c0526e1..971841e 100644 --- a/include/clang/AST/DataRecursiveASTVisitor.h +++ b/include/clang/AST/DataRecursiveASTVisitor.h @@ -791,7 +791,7 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) { - if (C->isInitCapture()) + if (LE->isInitCapture(C)) TRY_TO(TraverseDecl(C->getCapturedVar())); return true; } @@ -1284,6 +1284,8 @@ DEF_TRAVERSE_DECL( // D->getAnonymousNamespace(). }) +DEF_TRAVERSE_DECL(ExternCContextDecl, {}) + DEF_TRAVERSE_DECL(NamespaceAliasDecl, { // We shouldn't traverse an aliased namespace, since it will be // defined (and, therefore, traversed) somewhere else. @@ -2433,6 +2435,7 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { TRY_TO(TraverseStmt(C->getChunkSize())); + TRY_TO(TraverseStmt(C->getHelperChunkSize())); return true; } @@ -2517,6 +2520,18 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause( OMPLastprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->private_copies()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->source_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->destination_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->assignment_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2529,7 +2544,17 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) { template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) { TRY_TO(TraverseStmt(C->getStep())); + TRY_TO(TraverseStmt(C->getCalcStep())); TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->inits()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->updates()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->finals()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2543,6 +2568,15 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) { template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) { TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->source_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->destination_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->assignment_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2550,6 +2584,15 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause( OMPCopyprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->source_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->destination_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->assignment_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2559,6 +2602,15 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->lhs_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->rhs_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->reduction_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index a39888f..451f9da 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -39,6 +39,7 @@ class LabelStmt; class MemberSpecializationInfo; class Module; class NestedNameSpecifier; +class ParmVarDecl; class Stmt; class StringLiteral; class TemplateArgumentList; @@ -82,10 +83,7 @@ class TranslationUnitDecl : public Decl, public DeclContext { /// translation unit, if one has been created. NamespaceDecl *AnonymousNamespace; - explicit TranslationUnitDecl(ASTContext &ctx) - : Decl(TranslationUnit, nullptr, SourceLocation()), - DeclContext(TranslationUnit), - Ctx(ctx), AnonymousNamespace(nullptr) {} + explicit TranslationUnitDecl(ASTContext &ctx); public: ASTContext &getASTContext() const { return Ctx; } @@ -104,6 +102,43 @@ public: } }; +/// \brief Declaration context for names declared as extern "C" in C++. This +/// is neither the semantic nor lexical context for such declarations, but is +/// used to check for conflicts with other extern "C" declarations. Example: +/// +/// \code +/// namespace N { extern "C" void f(); } // #1 +/// void N::f() {} // #2 +/// namespace M { extern "C" void f(); } // #3 +/// \endcode +/// +/// The semantic context of #1 is namespace N and its lexical context is the +/// LinkageSpecDecl; the semantic context of #2 is namespace N and its lexical +/// context is the TU. However, both declarations are also visible in the +/// extern "C" context. +/// +/// The declaration at #3 finds it is a redeclaration of \c N::f through +/// lookup in the extern "C" context. +class ExternCContextDecl : public Decl, public DeclContext { + virtual void anchor(); + + explicit ExternCContextDecl(TranslationUnitDecl *TU) + : Decl(ExternCContext, TU, SourceLocation()), + DeclContext(ExternCContext) {} +public: + static ExternCContextDecl *Create(const ASTContext &C, + TranslationUnitDecl *TU); + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ExternCContext; } + static DeclContext *castToDeclContext(const ExternCContextDecl *D) { + return static_cast<DeclContext *>(const_cast<ExternCContextDecl*>(D)); + } + static ExternCContextDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast<ExternCContextDecl *>(const_cast<DeclContext*>(DC)); + } +}; + /// NamedDecl - This represents a decl with a name. Many decls have names such /// as ObjCMethodDecl, but not \@class, etc. class NamedDecl : public Decl { @@ -179,14 +214,17 @@ public: const PrintingPolicy &Policy, bool Qualified) const; - /// declarationReplaces - Determine whether this declaration, if + /// \brief Determine whether this declaration, if /// known to be well-formed within its context, will replace the /// declaration OldD if introduced into scope. A declaration will /// replace another declaration if, for example, it is a /// redeclaration of the same variable or function, but not if it is /// a declaration of a different kind (function vs. class) or an /// overloaded function. - bool declarationReplaces(NamedDecl *OldD) const; + /// + /// \param IsKnownNewer \c true if this declaration is known to be newer + /// than \p OldD (for instance, if this declaration is newly-created). + bool declarationReplaces(NamedDecl *OldD, bool IsKnownNewer = true) const; /// \brief Determine whether this declaration has linkage. bool hasLinkage() const; @@ -535,8 +573,8 @@ struct QualifierInfo { private: // Copy constructor and copy assignment are disabled. - QualifierInfo(const QualifierInfo&) LLVM_DELETED_FUNCTION; - QualifierInfo& operator=(const QualifierInfo&) LLVM_DELETED_FUNCTION; + QualifierInfo(const QualifierInfo&) = delete; + QualifierInfo& operator=(const QualifierInfo&) = delete; }; /// \brief Represents a ValueDecl that came out of a declarator. @@ -710,37 +748,8 @@ private: unsigned SClass : 3; unsigned TSCSpec : 2; unsigned InitStyle : 2; - - /// \brief Whether this variable is the exception variable in a C++ catch - /// or an Objective-C @catch statement. - unsigned ExceptionVar : 1; - - /// \brief Whether this local variable could be allocated in the return - /// slot of its function, enabling the named return value optimization - /// (NRVO). - unsigned NRVOVariable : 1; - - /// \brief Whether this variable is the for-range-declaration in a C++0x - /// for-range statement. - unsigned CXXForRangeDecl : 1; - - /// \brief Whether this variable is an ARC pseudo-__strong - /// variable; see isARCPseudoStrong() for details. - unsigned ARCPseudoStrong : 1; - - /// \brief Whether this variable is (C++0x) constexpr. - unsigned IsConstexpr : 1; - - /// \brief Whether this variable is the implicit variable for a lambda - /// init-capture. - unsigned IsInitCapture : 1; - - /// \brief Whether this local extern variable's previous declaration was - /// declared in the same block scope. This controls whether we should merge - /// the type of this declaration with its previous declaration. - unsigned PreviousDeclInSameBlockScope : 1; }; - enum { NumVarDeclBits = 14 }; + enum { NumVarDeclBits = 7 }; friend class ASTDeclReader; friend class StmtIteratorBase; @@ -776,10 +785,47 @@ protected: unsigned ParameterIndex : NumParameterIndexBits; }; + class NonParmVarDeclBitfields { + friend class VarDecl; + friend class ASTDeclReader; + + unsigned : NumVarDeclBits; + + /// \brief Whether this variable is the exception variable in a C++ catch + /// or an Objective-C @catch statement. + unsigned ExceptionVar : 1; + + /// \brief Whether this local variable could be allocated in the return + /// slot of its function, enabling the named return value optimization + /// (NRVO). + unsigned NRVOVariable : 1; + + /// \brief Whether this variable is the for-range-declaration in a C++0x + /// for-range statement. + unsigned CXXForRangeDecl : 1; + + /// \brief Whether this variable is an ARC pseudo-__strong + /// variable; see isARCPseudoStrong() for details. + unsigned ARCPseudoStrong : 1; + + /// \brief Whether this variable is (C++0x) constexpr. + unsigned IsConstexpr : 1; + + /// \brief Whether this variable is the implicit variable for a lambda + /// init-capture. + unsigned IsInitCapture : 1; + + /// \brief Whether this local extern variable's previous declaration was + /// declared in the same block scope. This controls whether we should merge + /// the type of this declaration with its previous declaration. + unsigned PreviousDeclInSameBlockScope : 1; + }; + union { unsigned AllBits; VarDeclBitfields VarDeclBits; ParmVarDeclBitfields ParmVarDeclBits; + NonParmVarDeclBitfields NonParmVarDeclBits; }; VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, @@ -840,7 +886,7 @@ public: return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified; // Global Named Register (GNU extension) - if (getStorageClass() == SC_Register && !isLocalVarDecl()) + if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm()) return false; // Return true for: Auto, Register. @@ -1132,9 +1178,12 @@ public: /// \brief Determine whether this variable is the exception variable in a /// C++ catch statememt or an Objective-C \@catch statement. bool isExceptionVariable() const { - return VarDeclBits.ExceptionVar; + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ExceptionVar; + } + void setExceptionVariable(bool EV) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.ExceptionVar = EV; } - void setExceptionVariable(bool EV) { VarDeclBits.ExceptionVar = EV; } /// \brief Determine whether this local variable can be used with the named /// return value optimization (NRVO). @@ -1146,36 +1195,64 @@ public: /// return slot when returning from the function. Within the function body, /// each return that returns the NRVO object will have this variable as its /// NRVO candidate. - bool isNRVOVariable() const { return VarDeclBits.NRVOVariable; } - void setNRVOVariable(bool NRVO) { VarDeclBits.NRVOVariable = NRVO; } + bool isNRVOVariable() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.NRVOVariable; + } + void setNRVOVariable(bool NRVO) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.NRVOVariable = NRVO; + } /// \brief Determine whether this variable is the for-range-declaration in /// a C++0x for-range statement. - bool isCXXForRangeDecl() const { return VarDeclBits.CXXForRangeDecl; } - void setCXXForRangeDecl(bool FRD) { VarDeclBits.CXXForRangeDecl = FRD; } + bool isCXXForRangeDecl() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.CXXForRangeDecl; + } + void setCXXForRangeDecl(bool FRD) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.CXXForRangeDecl = FRD; + } /// \brief Determine whether this variable is an ARC pseudo-__strong /// variable. A pseudo-__strong variable has a __strong-qualified /// type but does not actually retain the object written into it. /// Generally such variables are also 'const' for safety. - bool isARCPseudoStrong() const { return VarDeclBits.ARCPseudoStrong; } - void setARCPseudoStrong(bool ps) { VarDeclBits.ARCPseudoStrong = ps; } + bool isARCPseudoStrong() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.ARCPseudoStrong; + } + void setARCPseudoStrong(bool ps) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.ARCPseudoStrong = ps; + } /// Whether this variable is (C++11) constexpr. - bool isConstexpr() const { return VarDeclBits.IsConstexpr; } - void setConstexpr(bool IC) { VarDeclBits.IsConstexpr = IC; } + bool isConstexpr() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr; + } + void setConstexpr(bool IC) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsConstexpr = IC; + } /// Whether this variable is the implicit variable for a lambda init-capture. - bool isInitCapture() const { return VarDeclBits.IsInitCapture; } - void setInitCapture(bool IC) { VarDeclBits.IsInitCapture = IC; } + bool isInitCapture() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture; + } + void setInitCapture(bool IC) { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsInitCapture = IC; + } /// Whether this local extern variable declaration's previous declaration /// was declared in the same block scope. Only correct in C++. bool isPreviousDeclInSameBlockScope() const { - return VarDeclBits.PreviousDeclInSameBlockScope; + return isa<ParmVarDecl>(this) + ? false + : NonParmVarDeclBits.PreviousDeclInSameBlockScope; } void setPreviousDeclInSameBlockScope(bool Same) { - VarDeclBits.PreviousDeclInSameBlockScope = Same; + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.PreviousDeclInSameBlockScope = Same; } /// \brief If this variable is an instantiated static data member of a @@ -1482,6 +1559,9 @@ private: bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; + /// \brief Indicates if the function uses __try. + bool UsesSEHTry : 1; + /// \brief Indicates if the function was a definition but its body was /// skipped. unsigned HasSkippedBody : 1; @@ -1570,8 +1650,8 @@ protected: HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), - IsConstexpr(isConstexprSpecified), HasSkippedBody(false), - EndRangeLoc(NameInfo.getEndLoc()), + IsConstexpr(isConstexprSpecified), UsesSEHTry(false), + HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1751,6 +1831,10 @@ public: bool isConstexpr() const { return IsConstexpr; } void setConstexpr(bool IC) { IsConstexpr = IC; } + /// Whether this is a (C++11) constexpr function or constexpr constructor. + bool usesSEHTry() const { return UsesSEHTry; } + void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } + /// \brief Whether this function has been deleted. /// /// A function that is "deleted" (via the C++0x "= delete" syntax) @@ -1814,11 +1898,6 @@ public: /// allocation function. [...] bool isReplaceableGlobalAllocationFunction() const; - /// \brief Determine whether this function is a sized global deallocation - /// function in C++1y. If so, find and return the corresponding unsized - /// deallocation function. - FunctionDecl *getCorrespondingUnsizedGlobalDeallocationFunction() const; - /// Compute the language linkage. LanguageLinkage getLanguageLinkage() const; @@ -1847,8 +1926,10 @@ public: void setPreviousDeclaration(FunctionDecl * PrevDecl); - virtual const FunctionDecl *getCanonicalDecl() const; FunctionDecl *getCanonicalDecl() override; + const FunctionDecl *getCanonicalDecl() const { + return const_cast<FunctionDecl*>(this)->getCanonicalDecl(); + } unsigned getBuiltinID() const; @@ -1923,6 +2004,13 @@ public: return getType()->getAs<FunctionType>()->getCallResultType(getASTContext()); } + /// \brief Returns true if this function or its return type has the + /// warn_unused_result attribute. If the return type has the attribute and + /// this function is a method of the return type's class, then false will be + /// returned to avoid spurious warnings on member methods such as assignment + /// operators. + bool hasUnusedResultAttr() const; + /// \brief Returns the storage class as written in the source. For the /// computed linkage of symbol, see getLinkage. StorageClass getStorageClass() const { return StorageClass(SClass); } @@ -2537,6 +2625,13 @@ public: TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); } const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); } + /// Retrieves the tag declaration for which this is the typedef name for + /// linkage purposes, if any. + /// + /// \param AnyRedecl Look for the tag declaration in any redeclaration of + /// this typedef declaration. + TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -3696,8 +3791,6 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) { assert(RedeclLink.NextIsLatest() && "setPreviousDecl on a decl already in a redeclaration chain"); - decl_type *First; - if (PrevDecl) { // Point to previous. Make sure that this is actually the most recent // redeclaration, or we can build invalid chains. If the most recent diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 984ab13..5c382b0 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclarationName.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" @@ -316,7 +317,7 @@ protected: : NextInContextAndBits(), DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), Implicit(false), Used(false), Referenced(false), - Access(AS_none), FromASTFile(0), Hidden(0), + Access(AS_none), FromASTFile(0), Hidden(DC && cast<Decl>(DC)->Hidden), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(0) { @@ -638,13 +639,28 @@ private: Module *getOwningModuleSlow() const; public: - Module *getOwningModule() const { + /// \brief Get the imported owning module, if this decl is from an imported + /// (non-local) module. + Module *getImportedOwningModule() const { if (!isFromASTFile()) return nullptr; return getOwningModuleSlow(); } + /// \brief Get the local owning module, if known. Returns nullptr if owner is + /// not yet known or declaration is not from a module. + Module *getLocalOwningModule() const { + if (isFromASTFile() || !Hidden) + return nullptr; + return reinterpret_cast<Module *const *>(this)[-1]; + } + void setLocalOwningModule(Module *M) { + assert(!isFromASTFile() && Hidden && + "should not have a cached owning module"); + reinterpret_cast<Module **>(this)[-1] = M; + } + unsigned getIdentifierNamespace() const { return IdentifierNamespace; } @@ -1005,9 +1021,62 @@ public: void print(raw_ostream &OS) const override; }; -typedef MutableArrayRef<NamedDecl *> DeclContextLookupResult; +/// \brief The results of name lookup within a DeclContext. This is either a +/// single result (with no stable storage) or a collection of results (with +/// stable storage provided by the lookup table). +class DeclContextLookupResult { + typedef ArrayRef<NamedDecl *> ResultTy; + ResultTy Result; + // If there is only one lookup result, it would be invalidated by + // reallocations of the name table, so store it separately. + NamedDecl *Single; + + static NamedDecl *const SingleElementDummyList; -typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult; +public: + DeclContextLookupResult() : Result(), Single() {} + DeclContextLookupResult(ArrayRef<NamedDecl *> Result) + : Result(Result), Single() {} + DeclContextLookupResult(NamedDecl *Single) + : Result(SingleElementDummyList), Single(Single) {} + + class iterator; + typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator, + std::random_access_iterator_tag, + NamedDecl *const> IteratorBase; + class iterator : public IteratorBase { + value_type SingleElement; + + public: + iterator() : IteratorBase(), SingleElement() {} + explicit iterator(pointer Pos, value_type Single = nullptr) + : IteratorBase(Pos), SingleElement(Single) {} + + reference operator*() const { + return SingleElement ? SingleElement : IteratorBase::operator*(); + } + }; + typedef iterator const_iterator; + typedef iterator::pointer pointer; + typedef iterator::reference reference; + + iterator begin() const { return iterator(Result.begin(), Single); } + iterator end() const { return iterator(Result.end(), Single); } + + bool empty() const { return Result.empty(); } + pointer data() const { return Single ? &Single : Result.data(); } + size_t size() const { return Single ? 1 : Result.size(); } + reference front() const { return Single ? Single : Result.front(); } + reference back() const { return Single ? Single : Result.back(); } + reference operator[](size_t N) const { return Single ? Single : Result[N]; } + + // FIXME: Remove this from the interface + DeclContextLookupResult slice(size_t N) const { + DeclContextLookupResult Sliced = Result.slice(N); + Sliced.Single = Single; + return Sliced; + } +}; /// DeclContext - This is used only as base class of specific decl types that /// can act as declaration contexts. These decls are (only the top classes @@ -1042,14 +1111,21 @@ class DeclContext { /// another lookup. mutable bool NeedToReconcileExternalVisibleStorage : 1; + /// \brief If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + mutable bool HasLazyLocalLexicalLookups : 1; + + /// \brief If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + mutable bool HasLazyExternalLexicalLookups : 1; + /// \brief Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a - /// dependent context), and a bool indicating whether we have lazily - /// omitted any declarations from the map. We maintain the invariant - /// that, if the map contains an entry for a DeclarationName (and we - /// haven't lazily omitted anything), then it contains all relevant - /// entries for that name. - mutable llvm::PointerIntPair<StoredDeclsMap*, 1, bool> LookupPtr; + /// dependent context). We maintain the invariant that, if the map + /// contains an entry for a DeclarationName (and we haven't lazily + /// omitted anything), then it contains all relevant entries for that + /// name (modulo the hasExternalDecls() flag). + mutable StoredDeclsMap *LookupPtr; protected: /// FirstDecl - The first declaration stored within this declaration @@ -1075,8 +1151,9 @@ protected: DeclContext(Decl::Kind K) : DeclKind(K), ExternalLexicalStorage(false), ExternalVisibleStorage(false), - NeedToReconcileExternalVisibleStorage(false), LookupPtr(nullptr, false), - FirstDecl(nullptr), LastDecl(nullptr) {} + NeedToReconcileExternalVisibleStorage(false), + HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), + LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {} public: ~DeclContext(); @@ -1147,6 +1224,11 @@ public: } } + /// \brief Test whether the context supports looking up names. + bool isLookupContext() const { + return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec; + } + bool isFileContext() const { return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace; } @@ -1520,26 +1602,15 @@ public: /// @brief Checks whether a declaration is in this context. bool containsDecl(Decl *D) const; - /// lookup_iterator - An iterator that provides access to the results - /// of looking up a name within this context. - typedef NamedDecl **lookup_iterator; - - /// lookup_const_iterator - An iterator that provides non-mutable - /// access to the results of lookup up a name within this context. - typedef NamedDecl * const * lookup_const_iterator; - typedef DeclContextLookupResult lookup_result; - typedef DeclContextLookupConstResult lookup_const_result; + typedef lookup_result::iterator lookup_iterator; /// lookup - Find the declarations (if any) with the given Name in /// this context. Returns a range of iterators that contains all of /// the declarations with this name, with object, function, member, /// and enumerator names preceding any tag name. Note that this /// routine will not look into parent contexts. - lookup_result lookup(DeclarationName Name); - lookup_const_result lookup(DeclarationName Name) const { - return const_cast<DeclContext*>(this)->lookup(Name); - } + lookup_result lookup(DeclarationName Name) const; /// \brief Find the declarations with the given name that are visible /// within this context; don't attempt to retrieve anything from an @@ -1593,7 +1664,16 @@ public: all_lookups_iterator noload_lookups_begin() const; all_lookups_iterator noload_lookups_end() const; - typedef llvm::iterator_range<UsingDirectiveDecl * const *> udir_range; + struct udir_iterator; + typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, + std::random_access_iterator_tag, + UsingDirectiveDecl *> udir_iterator_base; + struct udir_iterator : udir_iterator_base { + udir_iterator(lookup_iterator I) : udir_iterator_base(I) {} + UsingDirectiveDecl *operator*() const; + }; + + typedef llvm::iterator_range<udir_iterator> udir_range; udir_range using_directives() const; @@ -1604,17 +1684,22 @@ public: inline ddiag_range ddiags() const; // Low-level accessors - - /// \brief Mark the lookup table as needing to be built. This should be - /// used only if setHasExternalLexicalStorage() has been called on any - /// decl context for which this is the primary context. + + /// \brief Mark that there are external lexical declarations that we need + /// to include in our lookup table (and that are not available as external + /// visible lookups). These extra lookup results will be found by walking + /// the lexical declarations of this context. This should be used only if + /// setHasExternalLexicalStorage() has been called on any decl context for + /// which this is the primary context. void setMustBuildLookupTable() { - LookupPtr.setInt(true); + assert(this == getPrimaryContext() && + "should only be called on primary context"); + HasLazyExternalLexicalLookups = true; } /// \brief Retrieve the internal representation of the lookup structure. /// This may omit some names if we are lazily building the structure. - StoredDeclsMap *getLookupPtr() const { return LookupPtr.getPointer(); } + StoredDeclsMap *getLookupPtr() const { return LookupPtr; } /// \brief Ensure the lookup structure is fully-built and return it. StoredDeclsMap *buildLookup(); @@ -1637,7 +1722,7 @@ public: /// declarations visible in this context. void setHasExternalVisibleStorage(bool ES = true) { ExternalVisibleStorage = ES; - if (ES && LookupPtr.getPointer()) + if (ES && LookupPtr) NeedToReconcileExternalVisibleStorage = true; } @@ -1657,7 +1742,7 @@ public: private: void reconcileExternalVisibleStorage() const; - void LoadLexicalDeclsFromExternalStorage() const; + bool LoadLexicalDeclsFromExternalStorage() const; /// @brief Makes a declaration visible within this context, but /// suppresses searches for external declarations with the same @@ -1670,9 +1755,7 @@ private: friend class DependentDiagnostic; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; - template<decl_iterator (DeclContext::*Begin)() const, - decl_iterator (DeclContext::*End)() const> - void buildLookupImpl(DeclContext *DCtx); + void buildLookupImpl(DeclContext *DCtx, bool Internal); void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Rediscoverable); void makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal); diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 027b41e..f7cb462 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -651,8 +651,8 @@ public: CXXRecordDecl *getCanonicalDecl() override { return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl()); } - virtual const CXXRecordDecl *getCanonicalDecl() const { - return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl()); + const CXXRecordDecl *getCanonicalDecl() const { + return const_cast<CXXRecordDecl*>(this)->getCanonicalDecl(); } CXXRecordDecl *getPreviousDecl() { @@ -1093,8 +1093,7 @@ public: /// \brief Get all conversion functions visible in current class, /// including conversion function templates. - std::pair<conversion_iterator, conversion_iterator> - getVisibleConversionFunctions(); + llvm::iterator_range<conversion_iterator> getVisibleConversionFunctions(); /// Determine whether this class is an aggregate (C++ [dcl.init.aggr]), /// which is a class with no user-declared constructors, no private @@ -1782,7 +1781,7 @@ public: CXXMethodDecl *getCanonicalDecl() override { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); } - const CXXMethodDecl *getCanonicalDecl() const override { + const CXXMethodDecl *getCanonicalDecl() const { return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl(); } @@ -2085,7 +2084,7 @@ public: /// This can only be called once for each initializer; it cannot be called /// on an initializer having a positive number of (implicit) array indices. /// - /// This assumes that the initialzier was written in the source code, and + /// This assumes that the initializer was written in the source code, and /// ensures that isWritten() returns true. void setSourceOrder(int pos) { assert(!IsWritten && @@ -2150,7 +2149,7 @@ class CXXConstructorDecl : public CXXMethodDecl { /// \name Support for base and member initializers. /// \{ /// \brief The arguments used to initialize the base or member. - CXXCtorInitializer **CtorInitializers; + LazyCXXCtorInitializersPtr CtorInitializers; unsigned NumCtorInitializers; /// \} @@ -2189,7 +2188,7 @@ public: typedef CXXCtorInitializer **init_iterator; /// \brief Iterates through the member/base initializer list. - typedef CXXCtorInitializer * const * init_const_iterator; + typedef CXXCtorInitializer *const *init_const_iterator; typedef llvm::iterator_range<init_iterator> init_range; typedef llvm::iterator_range<init_const_iterator> init_const_range; @@ -2200,17 +2199,20 @@ public: } /// \brief Retrieve an iterator to the first initializer. - init_iterator init_begin() { return CtorInitializers; } + init_iterator init_begin() { + const auto *ConstThis = this; + return const_cast<init_iterator>(ConstThis->init_begin()); + } /// \brief Retrieve an iterator to the first initializer. - init_const_iterator init_begin() const { return CtorInitializers; } + init_const_iterator init_begin() const; /// \brief Retrieve an iterator past the last initializer. init_iterator init_end() { - return CtorInitializers + NumCtorInitializers; + return init_begin() + NumCtorInitializers; } /// \brief Retrieve an iterator past the last initializer. init_const_iterator init_end() const { - return CtorInitializers + NumCtorInitializers; + return init_begin() + NumCtorInitializers; } typedef std::reverse_iterator<init_iterator> init_reverse_iterator; @@ -2241,14 +2243,14 @@ public: NumCtorInitializers = numCtorInitializers; } - void setCtorInitializers(CXXCtorInitializer ** initializers) { - CtorInitializers = initializers; + void setCtorInitializers(CXXCtorInitializer **Initializers) { + CtorInitializers = Initializers; } /// \brief Determine whether this constructor is a delegating constructor. bool isDelegatingConstructor() const { return (getNumCtorInitializers() == 1) && - CtorInitializers[0]->isDelegatingInitializer(); + init_begin()[0]->isDelegatingInitializer(); } /// \brief When this constructor delegates to another, retrieve the target. @@ -2324,12 +2326,12 @@ public: /// \brief Set the constructor that this inheriting constructor is based on. void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); - const CXXConstructorDecl *getCanonicalDecl() const override { - return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); - } CXXConstructorDecl *getCanonicalDecl() override { return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); } + const CXXConstructorDecl *getCanonicalDecl() const { + return const_cast<CXXConstructorDecl*>(this)->getCanonicalDecl(); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2373,9 +2375,7 @@ public: bool isImplicitlyDeclared); static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); - void setOperatorDelete(FunctionDecl *OD) { - cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD; - } + void setOperatorDelete(FunctionDecl *OD); const FunctionDecl *getOperatorDelete() const { return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete; } diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index 9068c00..ff37758 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -142,31 +142,29 @@ public: /// represents. DeclContext::lookup_result getLookupResult() { if (isNull()) - return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr), - DeclContext::lookup_iterator(nullptr)); + return DeclContext::lookup_result(); // If we have a single NamedDecl, return it. - if (getAsDecl()) { + if (NamedDecl *ND = getAsDecl()) { assert(!isNull() && "Empty list isn't allowed"); // Data is a raw pointer to a NamedDecl*, return it. - void *Ptr = &Data; - return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1); + return DeclContext::lookup_result(ND); } assert(getAsVector() && "Must have a vector at this point"); DeclsTy &Vector = *getAsVector(); // Otherwise, we have a range result. - return DeclContext::lookup_result(Vector.begin(), Vector.end()); + return DeclContext::lookup_result(Vector); } /// HandleRedeclaration - If this is a redeclaration of an existing decl, /// replace the old one with D and return true. Otherwise return false. - bool HandleRedeclaration(NamedDecl *D) { + bool HandleRedeclaration(NamedDecl *D, bool IsKnownNewer) { // Most decls only have one entry in their list, special case it. if (NamedDecl *OldD = getAsDecl()) { - if (!D->declarationReplaces(OldD)) + if (!D->declarationReplaces(OldD, IsKnownNewer)) return false; setOnlyValue(D); return true; @@ -177,7 +175,7 @@ public: for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end(); OD != ODEnd; ++OD) { NamedDecl *OldD = *OD; - if (D->declarationReplaces(OldD)) { + if (D->declarationReplaces(OldD, IsKnownNewer)) { *OD = D; return true; } diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 55d4b0f..4a5b4f3 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -33,8 +33,8 @@ class ObjCPropertyImplDecl; class CXXCtorInitializer; class ObjCListBase { - ObjCListBase(const ObjCListBase &) LLVM_DELETED_FUNCTION; - void operator=(const ObjCListBase &) LLVM_DELETED_FUNCTION; + ObjCListBase(const ObjCListBase &) = delete; + void operator=(const ObjCListBase &) = delete; protected: /// List is an array of pointers to objects that are not owned by this object. void **List; @@ -820,8 +820,8 @@ public: ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { - return isInstance ? getInstanceMethod(Sel) - : getClassMethod(Sel); + return isInstance ? getCategoryInstanceMethod(Sel) + : getCategoryClassMethod(Sel); } typedef ObjCProtocolList::iterator protocol_iterator; @@ -2002,8 +2002,8 @@ class ObjCImplementationDecl : public ObjCImplDecl { SourceLocation IvarRBraceLoc; /// Support for ivar initialization. - /// IvarInitializers - The arguments used to initialize the ivars - CXXCtorInitializer **IvarInitializers; + /// \brief The arguments used to initialize the ivars + LazyCXXCtorInitializersPtr IvarInitializers; unsigned NumIvarInitializers; /// Do the ivars of this class require initialization other than @@ -2052,17 +2052,20 @@ public: } /// init_begin() - Retrieve an iterator to the first initializer. - init_iterator init_begin() { return IvarInitializers; } + init_iterator init_begin() { + const auto *ConstThis = this; + return const_cast<init_iterator>(ConstThis->init_begin()); + } /// begin() - Retrieve an iterator to the first initializer. - init_const_iterator init_begin() const { return IvarInitializers; } + init_const_iterator init_begin() const; /// init_end() - Retrieve an iterator past the last initializer. init_iterator init_end() { - return IvarInitializers + NumIvarInitializers; + return init_begin() + NumIvarInitializers; } /// end() - Retrieve an iterator past the last initializer. init_const_iterator init_end() const { - return IvarInitializers + NumIvarInitializers; + return init_begin() + NumIvarInitializers; } /// getNumArgs - Number of ivars which must be initialized. unsigned getNumIvarInitializers() const { diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 9283d2d..90cfb20 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -158,8 +158,8 @@ class TemplateArgumentList { /// argument list. unsigned NumArguments; - TemplateArgumentList(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; - void operator=(const TemplateArgumentList &Other) LLVM_DELETED_FUNCTION; + TemplateArgumentList(const TemplateArgumentList &Other) = delete; + void operator=(const TemplateArgumentList &Other) = delete; TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, bool Owned) @@ -314,7 +314,7 @@ public: /// \brief The function template from which this function template /// specialization was generated. /// - /// The two bits are contain the top 4 values of TemplateSpecializationKind. + /// The two bits contain the top 4 values of TemplateSpecializationKind. llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template; /// \brief The template arguments used to produce the function template @@ -545,47 +545,32 @@ protected: template <typename EntryType> struct SpecEntryTraits { typedef EntryType DeclType; - static DeclType *getMostRecentDecl(EntryType *D) { - return D->getMostRecentDecl(); + static DeclType *getDecl(EntryType *D) { + return D; + } + static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) { + return D->getTemplateArgs().asArray(); } }; - template <typename EntryType, - typename _SETraits = SpecEntryTraits<EntryType>, - typename _DeclType = typename _SETraits::DeclType> - class SpecIterator : public std::iterator<std::forward_iterator_tag, - _DeclType*, ptrdiff_t, - _DeclType*, _DeclType*> { - typedef _SETraits SETraits; - typedef _DeclType DeclType; - - typedef typename llvm::FoldingSetVector<EntryType>::iterator - SetIteratorType; - - SetIteratorType SetIter; - - public: - SpecIterator() : SetIter() {} - SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {} + template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>, + typename DeclType = typename SETraits::DeclType> + struct SpecIterator + : llvm::iterator_adaptor_base< + SpecIterator<EntryType, SETraits, DeclType>, + typename llvm::FoldingSetVector<EntryType>::iterator, + typename std::iterator_traits<typename llvm::FoldingSetVector< + EntryType>::iterator>::iterator_category, + DeclType *, ptrdiff_t, DeclType *, DeclType *> { + SpecIterator() {} + explicit SpecIterator( + typename llvm::FoldingSetVector<EntryType>::iterator SetIter) + : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {} DeclType *operator*() const { - return SETraits::getMostRecentDecl(&*SetIter); + return SETraits::getDecl(&*this->I)->getMostRecentDecl(); } DeclType *operator->() const { return **this; } - - SpecIterator &operator++() { ++SetIter; return *this; } - SpecIterator operator++(int) { - SpecIterator tmp(*this); - ++(*this); - return tmp; - } - - bool operator==(SpecIterator Other) const { - return SetIter == Other.SetIter; - } - bool operator!=(SpecIterator Other) const { - return SetIter != Other.SetIter; - } }; template <typename EntryType> @@ -598,6 +583,10 @@ protected: findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args, void *&InsertPos); + template <class Derived, class EntryType> + void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs, + EntryType *Entry, void *InsertPos); + struct CommonBase { CommonBase() : InstantiatedFromMember(nullptr, false) { } @@ -737,9 +726,12 @@ template <> struct RedeclarableTemplateDecl:: SpecEntryTraits<FunctionTemplateSpecializationInfo> { typedef FunctionDecl DeclType; - static DeclType * - getMostRecentDecl(FunctionTemplateSpecializationInfo *I) { - return I->Function->getMostRecentDecl(); + static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) { + return I->Function; + } + static ArrayRef<TemplateArgument> + getTemplateArgs(FunctionTemplateSpecializationInfo *I) { + return I->TemplateArguments->asArray(); } }; @@ -788,9 +780,6 @@ protected: friend class FunctionDecl; - /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; - /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & @@ -804,6 +793,9 @@ protected: void *InsertPos); public: + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// Get the underlying function declaration of the template. FunctionDecl *getTemplatedDecl() const { return static_cast<FunctionDecl*>(TemplatedDecl); @@ -843,6 +835,15 @@ public: static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } + FunctionTemplateDecl *getMostRecentDecl() { + return cast<FunctionTemplateDecl>( + static_cast<RedeclarableTemplateDecl *>(this) + ->getMostRecentDecl()); + } + const FunctionTemplateDecl *getMostRecentDecl() const { + return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl(); + } + FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { return cast_or_null<FunctionTemplateDecl>( RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); @@ -903,7 +904,7 @@ public: /// This class is inheritedly privately by different kinds of template /// parameters and is not part of the Decl hierarchy. Just a facility. class TemplateParmPosition { - TemplateParmPosition() LLVM_DELETED_FUNCTION; + TemplateParmPosition() = delete; protected: TemplateParmPosition(unsigned D, unsigned P) @@ -1827,9 +1828,6 @@ protected: uint32_t *LazySpecializations; }; - /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; - /// \brief Retrieve the set of specializations of this class template. llvm::FoldingSetVector<ClassTemplateSpecializationDecl> & getSpecializations() const; @@ -1851,6 +1849,9 @@ protected: } public: + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// \brief Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { return static_cast<CXXRecordDecl *>(TemplatedDecl); @@ -2662,9 +2663,6 @@ protected: uint32_t *LazySpecializations; }; - /// \brief Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; - /// \brief Retrieve the set of specializations of this variable template. llvm::FoldingSetVector<VarTemplateSpecializationDecl> & getSpecializations() const; @@ -2686,6 +2684,9 @@ protected: } public: + /// \brief Load any lazily-loaded specializations from the external source. + void LoadLazySpecializations() const; + /// \brief Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { return static_cast<VarDecl *>(TemplatedDecl); @@ -2739,6 +2740,14 @@ public: this)->getPreviousDecl()); } + VarTemplateDecl *getMostRecentDecl() { + return cast<VarTemplateDecl>( + static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl()); + } + const VarTemplateDecl *getMostRecentDecl() const { + return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl(); + } + VarTemplateDecl *getInstantiatedFromMemberTemplate() { return cast_or_null<VarTemplateDecl>( RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 49e51e0..ec0fb0b 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -184,7 +184,7 @@ public: // operator bool() - Evaluates true when this declaration name is // non-empty. - LLVM_EXPLICIT operator bool() const { + explicit operator bool() const { return ((Ptr & PtrMask) != 0) || (reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask)); } @@ -344,8 +344,8 @@ class DeclarationNameTable { CXXOperatorIdName *CXXOperatorNames; // Operator names void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName* - DeclarationNameTable(const DeclarationNameTable&) LLVM_DELETED_FUNCTION; - void operator=(const DeclarationNameTable&) LLVM_DELETED_FUNCTION; + DeclarationNameTable(const DeclarationNameTable&) = delete; + void operator=(const DeclarationNameTable&) = delete; public: DeclarationNameTable(const ASTContext &C); diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index c410f23..a3be7d0 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -276,6 +276,7 @@ public: MLV_LValueCast, // Specialized form of MLV_InvalidExpression. MLV_IncompleteType, MLV_ConstQualified, + MLV_ConstAddrSpace, MLV_ArrayType, MLV_NoSetterProperty, MLV_MemberFunction, @@ -324,6 +325,7 @@ public: CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext CM_NoSetterProperty,// Implicit assignment to ObjC property without setter CM_ConstQualified, + CM_ConstAddrSpace, CM_ArrayType, CM_IncompleteType }; @@ -1239,8 +1241,8 @@ class APNumericStorage { bool hasAllocation() const { return llvm::APInt::getNumWords(BitWidth) > 1; } - APNumericStorage(const APNumericStorage &) LLVM_DELETED_FUNCTION; - void operator=(const APNumericStorage &) LLVM_DELETED_FUNCTION; + APNumericStorage(const APNumericStorage &) = delete; + void operator=(const APNumericStorage &) = delete; protected: APNumericStorage() : VAL(0), BitWidth(0) { } @@ -1997,18 +1999,7 @@ public: UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E, QualType resultType, SourceLocation op, - SourceLocation rp) : - Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary, - false, // Never type-dependent (C++ [temp.dep.expr]p3). - // Value-dependent if the argument is type-dependent. - E->isTypeDependent(), - E->isInstantiationDependent(), - E->containsUnexpandedParameterPack()), - OpLoc(op), RParenLoc(rp) { - UnaryExprOrTypeTraitExprBits.Kind = ExprKind; - UnaryExprOrTypeTraitExprBits.IsType = false; - Argument.Ex = E; - } + SourceLocation rp); /// \brief Construct an empty sizeof/alignof expression. explicit UnaryExprOrTypeTraitExpr(EmptyShell Empty) @@ -2287,7 +2278,7 @@ public: /// getCallReturnType - Get the return type of the call expr. This is not /// always the type of the expr itself, if the return type is a reference /// type. - QualType getCallReturnType() const; + QualType getCallReturnType(const ASTContext &Ctx) const; SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } @@ -2336,6 +2327,9 @@ class MemberExpr : public Expr { /// MemberLoc - This is the location of the member name. SourceLocation MemberLoc; + /// This is the location of the -> or . in the expression. + SourceLocation OperatorLoc; + /// IsArrow - True if this is "X->F", false if this is "X.F". bool IsArrow : 1; @@ -2370,18 +2364,16 @@ class MemberExpr : public Expr { } public: - MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - const DeclarationNameInfo &NameInfo, QualType ty, - ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), - base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), - MemberLoc(NameInfo.getLoc()), IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), - HadMultipleCandidates(false) { + MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, + ValueDecl *memberdecl, const DeclarationNameInfo &NameInfo, + QualType ty, ExprValueKind VK, ExprObjectKind OK) + : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), + base->isValueDependent(), base->isInstantiationDependent(), + base->containsUnexpandedParameterPack()), + Base(base), MemberDecl(memberdecl), MemberDNLoc(NameInfo.getInfo()), + MemberLoc(NameInfo.getLoc()), OperatorLoc(operatorloc), + IsArrow(isarrow), HasQualifierOrFoundDecl(false), + HasTemplateKWAndArgsInfo(false), HadMultipleCandidates(false) { assert(memberdecl->getDeclName() == NameInfo.getName()); } @@ -2389,25 +2381,25 @@ public: // the member name can not provide additional syntactic info // (i.e., source locations for C++ operator names or type source info // for constructors, destructors and conversion operators). - MemberExpr(Expr *base, bool isarrow, ValueDecl *memberdecl, - SourceLocation l, QualType ty, + MemberExpr(Expr *base, bool isarrow, SourceLocation operatorloc, + ValueDecl *memberdecl, SourceLocation l, QualType ty, ExprValueKind VK, ExprObjectKind OK) - : Expr(MemberExprClass, ty, VK, OK, - base->isTypeDependent(), base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l), - IsArrow(isarrow), - HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), - HadMultipleCandidates(false) {} + : Expr(MemberExprClass, ty, VK, OK, base->isTypeDependent(), + base->isValueDependent(), base->isInstantiationDependent(), + base->containsUnexpandedParameterPack()), + Base(base), MemberDecl(memberdecl), MemberDNLoc(), MemberLoc(l), + OperatorLoc(operatorloc), IsArrow(isarrow), + HasQualifierOrFoundDecl(false), HasTemplateKWAndArgsInfo(false), + HadMultipleCandidates(false) {} static MemberExpr *Create(const ASTContext &C, Expr *base, bool isarrow, + SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - ValueDecl *memberdecl, DeclAccessPair founddecl, + SourceLocation TemplateKWLoc, ValueDecl *memberdecl, + DeclAccessPair founddecl, DeclarationNameInfo MemberNameInfo, - const TemplateArgumentListInfo *targs, - QualType ty, ExprValueKind VK, ExprObjectKind OK); + const TemplateArgumentListInfo *targs, QualType ty, + ExprValueKind VK, ExprObjectKind OK); void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast<Expr>(Base); } @@ -2551,6 +2543,8 @@ public: MemberLoc, MemberDNLoc); } + SourceLocation getOperatorLoc() const LLVM_READONLY { return OperatorLoc; } + bool isArrow() const { return IsArrow; } void setArrow(bool A) { IsArrow = A; } diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 1768178..1dbf574 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -86,6 +86,13 @@ public: /// of the right bracket. SourceLocation getOperatorLoc() const { return getRParenLoc(); } + SourceLocation getExprLoc() const LLVM_READONLY { + return (Operator < OO_Plus || Operator >= OO_Arrow || + Operator == OO_PlusPlus || Operator == OO_MinusMinus) + ? getLocStart() + : getOperatorLoc(); + } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const { return Range; } @@ -1127,7 +1134,7 @@ public: ConstructionKind ConstructKind, SourceRange ParenOrBraceRange); - CXXConstructorDecl* getConstructor() const { return Constructor; } + CXXConstructorDecl *getConstructor() const { return Constructor; } void setConstructor(CXXConstructorDecl *C) { Constructor = C; } SourceLocation getLocation() const { return Loc; } @@ -1404,14 +1411,13 @@ class LambdaExpr : public Expr { unsigned *getArrayIndexStarts() const { return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1); } - + /// \brief Retrieve the complete set of array-index variables. VarDecl **getArrayIndexVars() const { - unsigned ArrayIndexSize = - llvm::RoundUpToAlignment(sizeof(unsigned) * (NumCaptures + 1), - llvm::alignOf<VarDecl*>()); + unsigned ArrayIndexSize = llvm::RoundUpToAlignment( + sizeof(unsigned) * (NumCaptures + 1), llvm::alignOf<VarDecl *>()); return reinterpret_cast<VarDecl **>( - reinterpret_cast<char*>(getArrayIndexStarts()) + ArrayIndexSize); + reinterpret_cast<char *>(getArrayIndexStarts()) + ArrayIndexSize); } public: @@ -1446,6 +1452,9 @@ public: return CaptureDefaultLoc; } + /// \brief Determine whether one of this lambda's captures is an init-capture. + bool isInitCapture(const LambdaCapture *Capture) const; + /// \brief An iterator that walks over the captures of the lambda, /// both implicit and explicit. typedef const Capture *capture_iterator; @@ -1686,6 +1695,10 @@ public: /// not be done, the deallocation function shall not be called, /// and the value of the new-expression shall be null. /// + /// C++ DR1748: + /// If the allocation function is a reserved placement allocation + /// function that returns null, the behavior is undefined. + /// /// An allocation function is not allowed to return null unless it /// has a non-throwing exception-specification. The '03 rule is /// identical except that the definition of a non-throwing diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index ff1d180..9a76080 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -22,6 +22,7 @@ namespace clang { class ASTConsumer; class CXXBaseSpecifier; +class CXXCtorInitializer; class DeclarationName; class ExternalSemaSource; // layering violation required for downcasting class FieldDecl; @@ -121,6 +122,12 @@ public: /// The default implementation of this method is a no-op. virtual Stmt *GetExternalDeclStmt(uint64_t Offset); + /// \brief Resolve the offset of a set of C++ constructor initializers in + /// the decl stream into an array of initializers. + /// + /// The default implementation of this method is a no-op. + virtual CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset); + /// \brief Resolve the offset of a set of C++ base specifiers in the decl /// stream into an array of specifiers. /// @@ -344,7 +351,7 @@ public: /// \brief Whether this pointer is non-NULL. /// /// This operation does not require the AST node to be deserialized. - LLVM_EXPLICIT operator bool() const { return Ptr != 0; } + explicit operator bool() const { return Ptr != 0; } /// \brief Whether this pointer is non-NULL. /// @@ -477,132 +484,42 @@ class LazyVector { SmallVector<T, LocalStorage> Local; public: - // Iteration over the elements in the vector. - class iterator { + /// Iteration over the elements in the vector. + /// + /// In a complete iteration, the iterator walks the range [-M, N), + /// where negative values are used to indicate elements + /// loaded from the external source while non-negative values are used to + /// indicate elements added via \c push_back(). + /// However, to provide iteration in source order (for, e.g., chained + /// precompiled headers), dereferencing the iterator flips the negative + /// values (corresponding to loaded entities), so that position -M + /// corresponds to element 0 in the loaded entities vector, position -M+1 + /// corresponds to element 1 in the loaded entities vector, etc. This + /// gives us a reasonably efficient, source-order walk. + /// + /// We define this as a wrapping iterator around an int. The + /// iterator_adaptor_base class forwards the iterator methods to basic integer + /// arithmetic. + class iterator : public llvm::iterator_adaptor_base< + iterator, int, std::random_access_iterator_tag, T, int> { LazyVector *Self; - - /// \brief Position within the vector.. - /// - /// In a complete iteration, the Position field walks the range [-M, N), - /// where negative values are used to indicate elements - /// loaded from the external source while non-negative values are used to - /// indicate elements added via \c push_back(). - /// However, to provide iteration in source order (for, e.g., chained - /// precompiled headers), dereferencing the iterator flips the negative - /// values (corresponding to loaded entities), so that position -M - /// corresponds to element 0 in the loaded entities vector, position -M+1 - /// corresponds to element 1 in the loaded entities vector, etc. This - /// gives us a reasonably efficient, source-order walk. - int Position; - + + iterator(LazyVector *Self, int Position) + : iterator::iterator_adaptor_base(Position), Self(Self) {} + + bool isLoaded() const { return this->I < 0; } friend class LazyVector; - + public: - typedef T value_type; - typedef value_type& reference; - typedef value_type* pointer; - typedef std::random_access_iterator_tag iterator_category; - typedef int difference_type; - - iterator() : Self(0), Position(0) { } - - iterator(LazyVector *Self, int Position) - : Self(Self), Position(Position) { } - - reference operator*() const { - if (Position < 0) - return Self->Loaded.end()[Position]; - return Self->Local[Position]; - } - - pointer operator->() const { - if (Position < 0) - return &Self->Loaded.end()[Position]; - - return &Self->Local[Position]; - } - - reference operator[](difference_type D) { - return *(*this + D); - } - - iterator &operator++() { - ++Position; - return *this; - } - - iterator operator++(int) { - iterator Prev(*this); - ++Position; - return Prev; - } - - iterator &operator--() { - --Position; - return *this; - } - - iterator operator--(int) { - iterator Prev(*this); - --Position; - return Prev; - } - - friend bool operator==(const iterator &X, const iterator &Y) { - return X.Position == Y.Position; - } - - friend bool operator!=(const iterator &X, const iterator &Y) { - return X.Position != Y.Position; - } - - friend bool operator<(const iterator &X, const iterator &Y) { - return X.Position < Y.Position; - } - - friend bool operator>(const iterator &X, const iterator &Y) { - return X.Position > Y.Position; - } - - friend bool operator<=(const iterator &X, const iterator &Y) { - return X.Position < Y.Position; - } - - friend bool operator>=(const iterator &X, const iterator &Y) { - return X.Position > Y.Position; - } - - friend iterator& operator+=(iterator &X, difference_type D) { - X.Position += D; - return X; - } - - friend iterator& operator-=(iterator &X, difference_type D) { - X.Position -= D; - return X; - } - - friend iterator operator+(iterator X, difference_type D) { - X.Position += D; - return X; - } - - friend iterator operator+(difference_type D, iterator X) { - X.Position += D; - return X; - } - - friend difference_type operator-(const iterator &X, const iterator &Y) { - return X.Position - Y.Position; - } - - friend iterator operator-(iterator X, difference_type D) { - X.Position -= D; - return X; + iterator() : iterator(nullptr, 0) {} + + typename iterator::reference operator*() const { + if (isLoaded()) + return Self->Loaded.end()[this->I]; + return Self->Local.begin()[this->I]; } }; - friend class iterator; - + iterator begin(Source *source, bool LocalOnly = false) { if (LocalOnly) return iterator(this, 0); @@ -621,17 +538,17 @@ public: } void erase(iterator From, iterator To) { - if (From.Position < 0 && To.Position < 0) { - Loaded.erase(Loaded.end() + From.Position, Loaded.end() + To.Position); + if (From.isLoaded() && To.isLoaded()) { + Loaded.erase(&*From, &*To); return; } - - if (From.Position < 0) { - Loaded.erase(Loaded.end() + From.Position, Loaded.end()); + + if (From.isLoaded()) { + Loaded.erase(&*From, Loaded.end()); From = begin(nullptr, true); } - - Local.erase(Local.begin() + From.Position, Local.begin() + To.Position); + + Local.erase(&*From, &*To); } }; @@ -643,8 +560,13 @@ typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> LazyDeclPtr; +/// \brief A lazy pointer to a set of CXXCtorInitializers. +typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, + &ExternalASTSource::GetExternalCXXCtorInitializers> + LazyCXXCtorInitializersPtr; + /// \brief A lazy pointer to a set of CXXBaseSpecifiers. -typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, +typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, &ExternalASTSource::GetExternalCXXBaseSpecifiers> LazyCXXBaseSpecifiersPtr; diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h index a7468a0..ddefa88 100644 --- a/include/clang/AST/LambdaCapture.h +++ b/include/clang/AST/LambdaCapture.h @@ -85,11 +85,6 @@ public: (DeclAndBits.getInt() & Capture_ByCopy); } - /// \brief Determine whether this is an init-capture. - bool isInitCapture() const { - return capturesVariable() && getCapturedVar()->isInitCapture(); - } - /// \brief Retrieve the declaration of the local variable being /// captured. /// diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index cbe08a1..c5a7ea1 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -132,12 +132,21 @@ public: virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &) = 0; + virtual void mangleSEHFilterExpression(const NamedDecl *EnclosingDecl, + raw_ostream &Out) = 0; + + virtual void mangleSEHFinallyBlock(const NamedDecl *EnclosingDecl, + raw_ostream &Out) = 0; + /// Generates a unique string for an externally visible type for use with TBAA /// or type uniquing. /// TODO: Extend this to internal types by generating names that are unique /// across translation units so it can be used with LTO. virtual void mangleTypeName(QualType T, raw_ostream &) = 0; + virtual void mangleCXXVTableBitSet(const CXXRecordDecl *RD, + raw_ostream &) = 0; + /// @} }; @@ -188,9 +197,27 @@ public: ArrayRef<const CXXRecordDecl *> BasePath, raw_ostream &Out) = 0; + virtual void mangleThreadSafeStaticGuardVariable(const VarDecl *VD, + unsigned GuardNum, + raw_ostream &Out) = 0; + virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, raw_ostream &) = 0; + virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, + uint32_t NumEntries, raw_ostream &Out) = 0; + + virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, + raw_ostream &Out) = 0; + + virtual void mangleCXXCatchableType(QualType T, const CXXConstructorDecl *CD, + CXXCtorType CT, uint32_t Size, + uint32_t NVOffset, int32_t VBPtrOffset, + uint32_t VBIndex, raw_ostream &Out) = 0; + + virtual void mangleCXXCatchHandlerType(QualType T, uint32_t Flags, + raw_ostream &Out) = 0; + virtual void mangleCXXRTTIBaseClassDescriptor( const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset, uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0; diff --git a/include/clang/AST/NSAPI.h b/include/clang/AST/NSAPI.h index 33fcce2..fc994c1 100644 --- a/include/clang/AST/NSAPI.h +++ b/include/clang/AST/NSAPI.h @@ -33,9 +33,12 @@ public: ClassId_NSMutableArray, ClassId_NSDictionary, ClassId_NSMutableDictionary, - ClassId_NSNumber + ClassId_NSNumber, + ClassId_NSMutableSet, + ClassId_NSCountedSet, + ClassId_NSMutableOrderedSet, }; - static const unsigned NumClassIds = 7; + static const unsigned NumClassIds = 10; enum NSStringMethodKind { NSStr_stringWithString, @@ -67,7 +70,8 @@ public: return isObjCEnumerator(E, "NSASCIIStringEncoding",NSASCIIStringEncodingId); } - /// \brief Enumerates the NSArray methods used to generate literals. + /// \brief Enumerates the NSArray/NSMutableArray methods used to generate + /// literals and to apply some checks. enum NSArrayMethodKind { NSArr_array, NSArr_arrayWithArray, @@ -77,9 +81,12 @@ public: NSArr_initWithArray, NSArr_initWithObjects, NSArr_objectAtIndex, - NSMutableArr_replaceObjectAtIndex + NSMutableArr_replaceObjectAtIndex, + NSMutableArr_addObject, + NSMutableArr_insertObjectAtIndex, + NSMutableArr_setObjectAtIndexedSubscript }; - static const unsigned NumNSArrayMethods = 9; + static const unsigned NumNSArrayMethods = 12; /// \brief The Objective-C NSArray selectors. Selector getNSArraySelector(NSArrayMethodKind MK) const; @@ -87,7 +94,8 @@ public: /// \brief Return NSArrayMethodKind if \p Sel is such a selector. Optional<NSArrayMethodKind> getNSArrayMethodKind(Selector Sel); - /// \brief Enumerates the NSDictionary methods used to generate literals. + /// \brief Enumerates the NSDictionary/NSMutableDictionary methods used + /// to generate literals and to apply some checks. enum NSDictionaryMethodKind { NSDict_dictionary, NSDict_dictionaryWithDictionary, @@ -99,9 +107,11 @@ public: NSDict_initWithObjectsAndKeys, NSDict_initWithObjectsForKeys, NSDict_objectForKey, - NSMutableDict_setObjectForKey + NSMutableDict_setObjectForKey, + NSMutableDict_setObjectForKeyedSubscript, + NSMutableDict_setValueForKey }; - static const unsigned NumNSDictionaryMethods = 12; + static const unsigned NumNSDictionaryMethods = 14; /// \brief The Objective-C NSDictionary selectors. Selector getNSDictionarySelector(NSDictionaryMethodKind MK) const; @@ -109,6 +119,23 @@ public: /// \brief Return NSDictionaryMethodKind if \p Sel is such a selector. Optional<NSDictionaryMethodKind> getNSDictionaryMethodKind(Selector Sel); + /// \brief Enumerates the NSMutableSet/NSOrderedSet methods used + /// to apply some checks. + enum NSSetMethodKind { + NSMutableSet_addObject, + NSOrderedSet_insertObjectAtIndex, + NSOrderedSet_setObjectAtIndex, + NSOrderedSet_setObjectAtIndexedSubscript, + NSOrderedSet_replaceObjectAtIndexWithObject + }; + static const unsigned NumNSSetMethods = 5; + + /// \brief The Objective-C NSSet selectors. + Selector getNSSetSelector(NSSetMethodKind MK) const; + + /// \brief Return NSSetMethodKind if \p Sel is such a selector. + Optional<NSSetMethodKind> getNSSetMethodKind(Selector Sel); + /// \brief Returns selector for "objectForKeyedSubscript:". Selector getObjectForKeyedSubscriptSelector() const { return getOrInitSelector(StringRef("objectForKeyedSubscript"), @@ -189,6 +216,9 @@ public: /// of that name in objective-c. StringRef GetNSIntegralKind(QualType T) const; + /// \brief Returns \c true if \p Id is currently defined as a macro. + bool isMacroDefined(StringRef Id) const; + private: bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const; bool isObjCEnumerator(const Expr *E, @@ -207,6 +237,9 @@ private: /// \brief The selectors for Objective-C NSDictionary methods. mutable Selector NSDictionarySelectors[NumNSDictionaryMethods]; + /// \brief The selectors for Objective-C NSSet methods. + mutable Selector NSSetSelectors[NumNSSetMethods]; + /// \brief The Objective-C NSNumber selectors used to create NSNumber literals. mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods]; mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods]; diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index 518f123..4da17b0 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -102,7 +102,7 @@ private: Specifier(Other.Specifier) { } - void operator=(const NestedNameSpecifier &) LLVM_DELETED_FUNCTION; + void operator=(const NestedNameSpecifier &) = delete; /// \brief Either find or insert the given nested name specifier /// mockup in the given context. @@ -245,7 +245,7 @@ public: /// \brief Evalutes true when this nested-name-specifier location is /// non-empty. - LLVM_EXPLICIT operator bool() const { return Qualifier; } + explicit operator bool() const { return Qualifier; } /// \brief Evalutes true when this nested-name-specifier location is /// empty. diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index 0c3002c..c8ecef8 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -573,8 +573,10 @@ class OMPScheduleClause : public OMPClause { SourceLocation KindLoc; /// \brief Location of ',' (if any). SourceLocation CommaLoc; - /// \brief Chunk size. - Stmt *ChunkSize; + /// \brief Chunk size and a reference to pseudo variable for combined + /// directives. + enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS }; + Stmt *ChunkSizes[NUM_EXPRS]; /// \brief Set schedule kind. /// @@ -600,7 +602,12 @@ class OMPScheduleClause : public OMPClause { /// /// \param E Chunk size. /// - void setChunkSize(Expr *E) { ChunkSize = E; } + void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; } + /// \brief Set helper chunk size. + /// + /// \param E Helper chunk size. + /// + void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; } public: /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size @@ -613,19 +620,26 @@ public: /// \param EndLoc Ending location of the clause. /// \param Kind Schedule kind. /// \param ChunkSize Chunk size. + /// \param HelperChunkSize Helper chunk size for combined directives. /// OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, - Expr *ChunkSize) + Expr *ChunkSize, Expr *HelperChunkSize) : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {} + Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) { + ChunkSizes[CHUNK_SIZE] = ChunkSize; + ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize; + } /// \brief Build an empty clause. /// explicit OMPScheduleClause() : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), - Kind(OMPC_SCHEDULE_unknown), ChunkSize(nullptr) {} + Kind(OMPC_SCHEDULE_unknown) { + ChunkSizes[CHUNK_SIZE] = nullptr; + ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; + } /// \brief Get kind of the clause. /// @@ -641,16 +655,30 @@ public: SourceLocation getCommaLoc() { return CommaLoc; } /// \brief Get chunk size. /// - Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSize); } + Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); } /// \brief Get chunk size. /// - Expr *getChunkSize() const { return dyn_cast_or_null<Expr>(ChunkSize); } + Expr *getChunkSize() const { + return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); + } + /// \brief Get helper chunk size. + /// + Expr *getHelperChunkSize() { + return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]); + } + /// \brief Get helper chunk size. + /// + Expr *getHelperChunkSize() const { + return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]); + } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_schedule; } - StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); } + StmtRange children() { + return StmtRange(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); + } }; /// \brief This represents 'ordered' clause in the '#pragma omp ...' directive. @@ -1137,8 +1165,26 @@ public: /// \endcode /// In this example directive '#pragma omp simd' has clause 'lastprivate' /// with the variables 'a' and 'b'. -/// class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> { + // There are 4 additional tail-allocated arrays at the end of the class: + // 1. Contains list of pseudo variables with the default initialization for + // each non-firstprivate variables. Used in codegen for initialization of + // lastprivate copies. + // 2. List of helper expressions for proper generation of assignment operation + // required for lastprivate clause. This list represents private variables + // (for arrays, single array element). + // 3. List of helper expressions for proper generation of assignment operation + // required for lastprivate clause. This list represents original variables + // (for arrays, single array element). + // 4. List of helper expressions that represents assignment operation: + // \code + // DstExprs = SrcExprs; + // \endcode + // Required for proper codegen of final assignment performed by the + // lastprivate clause. + // + friend class OMPClauseReader; + /// \brief Build clause with number of variables \a N. /// /// \param StartLoc Starting location of the clause. @@ -1160,6 +1206,56 @@ class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> { OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} + /// \brief Get the list of helper expressions for initialization of private + /// copies for lastprivate variables. + MutableArrayRef<Expr *> getPrivateCopies() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getPrivateCopies() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent private variables (for arrays, single + /// array element) in the final assignment statement performed by the + /// lastprivate clause. + void setSourceExprs(ArrayRef<Expr *> SrcExprs); + + /// \brief Get the list of helper source expressions. + MutableArrayRef<Expr *> getSourceExprs() { + return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size()); + } + ArrayRef<const Expr *> getSourceExprs() const { + return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size()); + } + + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent original variables (for arrays, single + /// array element) in the final assignment statement performed by the + /// lastprivate clause. + void setDestinationExprs(ArrayRef<Expr *> DstExprs); + + /// \brief Get the list of helper destination expressions. + MutableArrayRef<Expr *> getDestinationExprs() { + return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getDestinationExprs() const { + return llvm::makeArrayRef(getSourceExprs().end(), varlist_size()); + } + + /// \brief Set list of helper assignment expressions, required for proper + /// codegen of the clause. These expressions are assignment expressions that + /// assign private copy of the variable to original variable. + void setAssignmentOps(ArrayRef<Expr *> AssignmentOps); + + /// \brief Get the list of helper assignment expressions. + MutableArrayRef<Expr *> getAssignmentOps() { + return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getAssignmentOps() const { + return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size()); + } + public: /// \brief Creates clause with a list of variables \a VL. /// @@ -1168,10 +1264,25 @@ public: /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// \param VL List of references to the variables. + /// \param SrcExprs List of helper expressions for proper generation of + /// assignment operation required for lastprivate clause. This list represents + /// private variables (for arrays, single array element). + /// \param DstExprs List of helper expressions for proper generation of + /// assignment operation required for lastprivate clause. This list represents + /// original variables (for arrays, single array element). + /// \param AssignmentOps List of helper expressions that represents assignment + /// operation: + /// \code + /// DstExprs = SrcExprs; + /// \endcode + /// Required for proper codegen of final assignment performed by the + /// lastprivate clause. + /// /// static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL); + SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, + ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1179,6 +1290,48 @@ public: /// static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N); + typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator; + typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator; + typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range; + typedef llvm::iterator_range<helper_expr_const_iterator> + helper_expr_const_range; + + /// \brief Set list of helper expressions, required for generation of private + /// copies of original lastprivate variables. + void setPrivateCopies(ArrayRef<Expr *> PrivateCopies); + + helper_expr_const_range private_copies() const { + return helper_expr_const_range(getPrivateCopies().begin(), + getPrivateCopies().end()); + } + helper_expr_range private_copies() { + return helper_expr_range(getPrivateCopies().begin(), + getPrivateCopies().end()); + } + helper_expr_const_range source_exprs() const { + return helper_expr_const_range(getSourceExprs().begin(), + getSourceExprs().end()); + } + helper_expr_range source_exprs() { + return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); + } + helper_expr_const_range destination_exprs() const { + return helper_expr_const_range(getDestinationExprs().begin(), + getDestinationExprs().end()); + } + helper_expr_range destination_exprs() { + return helper_expr_range(getDestinationExprs().begin(), + getDestinationExprs().end()); + } + helper_expr_const_range assignment_ops() const { + return helper_expr_const_range(getAssignmentOps().begin(), + getAssignmentOps().end()); + } + helper_expr_range assignment_ops() { + return helper_expr_range(getAssignmentOps().begin(), + getAssignmentOps().end()); + } + StmtRange children() { return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); @@ -1301,6 +1454,48 @@ class OMPReductionClause : public OMPVarListClause<OMPReductionClause> { /// \brief Sets the nested name specifier. void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; } + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent LHS expression in the final + /// reduction expression performed by the reduction clause. + void setLHSExprs(ArrayRef<Expr *> LHSExprs); + + /// \brief Get the list of helper LHS expressions. + MutableArrayRef<Expr *> getLHSExprs() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getLHSExprs() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent RHS expression in the final + /// reduction expression performed by the reduction clause. + /// Also, variables in these expressions are used for proper initialization of + /// reduction copies. + void setRHSExprs(ArrayRef<Expr *> RHSExprs); + + /// \brief Get the list of helper destination expressions. + MutableArrayRef<Expr *> getRHSExprs() { + return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getRHSExprs() const { + return llvm::makeArrayRef(getLHSExprs().end(), varlist_size()); + } + + /// \brief Set list of helper reduction expressions, required for proper + /// codegen of the clause. These expressions are binary expressions or + /// operator/custom reduction call that calculates new value from source + /// helper expressions to destination helper expressions. + void setReductionOps(ArrayRef<Expr *> ReductionOps); + + /// \brief Get the list of helper reduction expressions. + MutableArrayRef<Expr *> getReductionOps() { + return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getReductionOps() const { + return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); + } + public: /// \brief Creates clause with a list of variables \a VL. /// @@ -1311,12 +1506,30 @@ public: /// \param VL The variables in the clause. /// \param QualifierLoc The nested-name qualifier with location information /// \param NameInfo The full name info for reduction identifier. + /// \param LHSExprs List of helper expressions for proper generation of + /// assignment operation required for copyprivate clause. This list represents + /// LHSs of the reduction expressions. + /// \param RHSExprs List of helper expressions for proper generation of + /// assignment operation required for copyprivate clause. This list represents + /// RHSs of the reduction expressions. + /// Also, variables in these expressions are used for proper initialization of + /// reduction copies. + /// \param ReductionOps List of helper expressions that represents reduction + /// expressions: + /// \code + /// LHSExprs binop RHSExprs; + /// operator binop(LHSExpr, RHSExpr); + /// <CutomReduction>(LHSExpr, RHSExpr); + /// \endcode + /// Required for proper codegen of final reduction operation performed by the + /// reduction clause. /// static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo); + const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> LHSExprs, + ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1331,6 +1544,33 @@ public: /// \brief Gets the nested name specifier. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator; + typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator; + typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range; + typedef llvm::iterator_range<helper_expr_const_iterator> + helper_expr_const_range; + + helper_expr_const_range lhs_exprs() const { + return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); + } + helper_expr_range lhs_exprs() { + return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); + } + helper_expr_const_range rhs_exprs() const { + return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); + } + helper_expr_range rhs_exprs() { + return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); + } + helper_expr_const_range reduction_ops() const { + return helper_expr_const_range(getReductionOps().begin(), + getReductionOps().end()); + } + helper_expr_range reduction_ops() { + return helper_expr_range(getReductionOps().begin(), + getReductionOps().end()); + } + StmtRange children() { return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); @@ -1356,7 +1596,10 @@ class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { SourceLocation ColonLoc; /// \brief Sets the linear step for clause. - void setStep(Expr *Step) { *varlist_end() = Step; } + void setStep(Expr *Step) { *(getFinals().end()) = Step; } + + /// \brief Sets the expression to calculate linear step for clause. + void setCalcStep(Expr *CalcStep) { *(getFinals().end() + 1) = CalcStep; } /// \brief Build 'linear' clause with given number of variables \a NumVars. /// @@ -1383,6 +1626,46 @@ class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { NumVars), ColonLoc(SourceLocation()) {} + /// \brief Gets the list of initial values for linear variables. + /// + /// There are NumVars expressions with initial values allocated after the + /// varlist, they are followed by NumVars update expressions (used to update + /// the linear variable's value on current iteration) and they are followed by + /// NumVars final expressions (used to calculate the linear variable's + /// value after the loop body). After these lists, there are 2 helper + /// expressions - linear step and a helper to calculate it before the + /// loop body (used when the linear step is not constant): + /// + /// { Vars[] /* in OMPVarListClause */; Inits[]; Updates[]; Finals[]; + /// Step; CalcStep; } + /// + MutableArrayRef<Expr *> getInits() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getInits() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// \brief Sets the list of update expressions for linear variables. + MutableArrayRef<Expr *> getUpdates() { + return MutableArrayRef<Expr *>(getInits().end(), varlist_size()); + } + ArrayRef<const Expr *> getUpdates() const { + return llvm::makeArrayRef(getInits().end(), varlist_size()); + } + + /// \brief Sets the list of final update expressions for linear variables. + MutableArrayRef<Expr *> getFinals() { + return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size()); + } + ArrayRef<const Expr *> getFinals() const { + return llvm::makeArrayRef(getUpdates().end(), varlist_size()); + } + + /// \brief Sets the list of the initial values for linear variables. + /// \param IL List of expressions. + void setInits(ArrayRef<Expr *> IL); + public: /// \brief Creates clause with a list of variables \a VL and a linear step /// \a Step. @@ -1393,11 +1676,14 @@ public: /// \param ColonLoc Location of ':'. /// \param EndLoc Ending location of the clause. /// \param VL List of references to the variables. + /// \param IL List of initial values for the variables. /// \param Step Linear step. + /// \param CalcStep Calculation of the linear step. static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, - ArrayRef<Expr *> VL, Expr *Step); + ArrayRef<Expr *> VL, ArrayRef<Expr *> IL, + Expr *Step, Expr *CalcStep); /// \brief Creates an empty clause with the place for \a NumVars variables. /// @@ -1412,13 +1698,61 @@ public: SourceLocation getColonLoc() const { return ColonLoc; } /// \brief Returns linear step. - Expr *getStep() { return *varlist_end(); } + Expr *getStep() { return *(getFinals().end()); } /// \brief Returns linear step. - const Expr *getStep() const { return *varlist_end(); } + const Expr *getStep() const { return *(getFinals().end()); } + /// \brief Returns expression to calculate linear step. + Expr *getCalcStep() { return *(getFinals().end() + 1); } + /// \brief Returns expression to calculate linear step. + const Expr *getCalcStep() const { return *(getFinals().end() + 1); } + + /// \brief Sets the list of update expressions for linear variables. + /// \param UL List of expressions. + void setUpdates(ArrayRef<Expr *> UL); + + /// \brief Sets the list of final update expressions for linear variables. + /// \param FL List of expressions. + void setFinals(ArrayRef<Expr *> FL); + + typedef MutableArrayRef<Expr *>::iterator inits_iterator; + typedef ArrayRef<const Expr *>::iterator inits_const_iterator; + typedef llvm::iterator_range<inits_iterator> inits_range; + typedef llvm::iterator_range<inits_const_iterator> inits_const_range; + + inits_range inits() { + return inits_range(getInits().begin(), getInits().end()); + } + inits_const_range inits() const { + return inits_const_range(getInits().begin(), getInits().end()); + } + + typedef MutableArrayRef<Expr *>::iterator updates_iterator; + typedef ArrayRef<const Expr *>::iterator updates_const_iterator; + typedef llvm::iterator_range<updates_iterator> updates_range; + typedef llvm::iterator_range<updates_const_iterator> updates_const_range; + + updates_range updates() { + return updates_range(getUpdates().begin(), getUpdates().end()); + } + updates_const_range updates() const { + return updates_const_range(getUpdates().begin(), getUpdates().end()); + } + + typedef MutableArrayRef<Expr *>::iterator finals_iterator; + typedef ArrayRef<const Expr *>::iterator finals_const_iterator; + typedef llvm::iterator_range<finals_iterator> finals_range; + typedef llvm::iterator_range<finals_const_iterator> finals_const_range; + + finals_range finals() { + return finals_range(getFinals().begin(), getFinals().end()); + } + finals_const_range finals() const { + return finals_const_range(getFinals().begin(), getFinals().end()); + } StmtRange children() { return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end() + 1)); + reinterpret_cast<Stmt **>(getFinals().end() + 2)); } static bool classof(const OMPClause *T) { @@ -1520,6 +1854,20 @@ public: /// with the variables 'a' and 'b'. /// class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> { + // Class has 3 additional tail allocated arrays: + // 1. List of helper expressions for proper generation of assignment operation + // required for copyin clause. This list represents sources. + // 2. List of helper expressions for proper generation of assignment operation + // required for copyin clause. This list represents destinations. + // 3. List of helper expressions that represents assignment operation: + // \code + // DstExprs = SrcExprs; + // \endcode + // Required for proper codegen of propagation of master's thread values of + // threadprivate variables to local instances of that variables in other + // implicit threads. + + friend class OMPClauseReader; /// \brief Build clause with number of variables \a N. /// /// \param StartLoc Starting location of the clause. @@ -1541,6 +1889,46 @@ class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> { SourceLocation(), SourceLocation(), N) {} + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent source expression in the final + /// assignment statement performed by the copyin clause. + void setSourceExprs(ArrayRef<Expr *> SrcExprs); + + /// \brief Get the list of helper source expressions. + MutableArrayRef<Expr *> getSourceExprs() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getSourceExprs() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent destination expression in the final + /// assignment statement performed by the copyin clause. + void setDestinationExprs(ArrayRef<Expr *> DstExprs); + + /// \brief Get the list of helper destination expressions. + MutableArrayRef<Expr *> getDestinationExprs() { + return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getDestinationExprs() const { + return llvm::makeArrayRef(getSourceExprs().end(), varlist_size()); + } + + /// \brief Set list of helper assignment expressions, required for proper + /// codegen of the clause. These expressions are assignment expressions that + /// assign source helper expressions to destination helper expressions + /// correspondingly. + void setAssignmentOps(ArrayRef<Expr *> AssignmentOps); + + /// \brief Get the list of helper assignment expressions. + MutableArrayRef<Expr *> getAssignmentOps() { + return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getAssignmentOps() const { + return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size()); + } + public: /// \brief Creates clause with a list of variables \a VL. /// @@ -1549,10 +1937,25 @@ public: /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// \param VL List of references to the variables. - /// - static OMPCopyinClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL); + /// \param SrcExprs List of helper expressions for proper generation of + /// assignment operation required for copyin clause. This list represents + /// sources. + /// \param DstExprs List of helper expressions for proper generation of + /// assignment operation required for copyin clause. This list represents + /// destinations. + /// \param AssignmentOps List of helper expressions that represents assignment + /// operation: + /// \code + /// DstExprs = SrcExprs; + /// \endcode + /// Required for proper codegen of propagation of master's thread values of + /// threadprivate variables to local instances of that variables in other + /// implicit threads. + /// + static OMPCopyinClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, + ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps); /// \brief Creates an empty clause with \a N variables. /// /// \param C AST context. @@ -1560,6 +1963,36 @@ public: /// static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N); + typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator; + typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator; + typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range; + typedef llvm::iterator_range<helper_expr_const_iterator> + helper_expr_const_range; + + helper_expr_const_range source_exprs() const { + return helper_expr_const_range(getSourceExprs().begin(), + getSourceExprs().end()); + } + helper_expr_range source_exprs() { + return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); + } + helper_expr_const_range destination_exprs() const { + return helper_expr_const_range(getDestinationExprs().begin(), + getDestinationExprs().end()); + } + helper_expr_range destination_exprs() { + return helper_expr_range(getDestinationExprs().begin(), + getDestinationExprs().end()); + } + helper_expr_const_range assignment_ops() const { + return helper_expr_const_range(getAssignmentOps().begin(), + getAssignmentOps().end()); + } + helper_expr_range assignment_ops() { + return helper_expr_range(getAssignmentOps().begin(), + getAssignmentOps().end()); + } + StmtRange children() { return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); @@ -1580,6 +2013,7 @@ public: /// with the variables 'a' and 'b'. /// class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> { + friend class OMPClauseReader; /// \brief Build clause with number of variables \a N. /// /// \param StartLoc Starting location of the clause. @@ -1601,6 +2035,46 @@ class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> { OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent source expression in the final + /// assignment statement performed by the copyprivate clause. + void setSourceExprs(ArrayRef<Expr *> SrcExprs); + + /// \brief Get the list of helper source expressions. + MutableArrayRef<Expr *> getSourceExprs() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getSourceExprs() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent destination expression in the final + /// assignment statement performed by the copyprivate clause. + void setDestinationExprs(ArrayRef<Expr *> DstExprs); + + /// \brief Get the list of helper destination expressions. + MutableArrayRef<Expr *> getDestinationExprs() { + return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getDestinationExprs() const { + return llvm::makeArrayRef(getSourceExprs().end(), varlist_size()); + } + + /// \brief Set list of helper assignment expressions, required for proper + /// codegen of the clause. These expressions are assignment expressions that + /// assign source helper expressions to destination helper expressions + /// correspondingly. + void setAssignmentOps(ArrayRef<Expr *> AssignmentOps); + + /// \brief Get the list of helper assignment expressions. + MutableArrayRef<Expr *> getAssignmentOps() { + return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getAssignmentOps() const { + return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size()); + } + public: /// \brief Creates clause with a list of variables \a VL. /// @@ -1609,10 +2083,24 @@ public: /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// \param VL List of references to the variables. + /// \param SrcExprs List of helper expressions for proper generation of + /// assignment operation required for copyprivate clause. This list represents + /// sources. + /// \param DstExprs List of helper expressions for proper generation of + /// assignment operation required for copyprivate clause. This list represents + /// destinations. + /// \param AssignmentOps List of helper expressions that represents assignment + /// operation: + /// \code + /// DstExprs = SrcExprs; + /// \endcode + /// Required for proper codegen of final assignment performed by the + /// copyprivate clause. /// static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL); + SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, + ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps); /// \brief Creates an empty clause with \a N variables. /// /// \param C AST context. @@ -1620,6 +2108,36 @@ public: /// static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N); + typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator; + typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator; + typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range; + typedef llvm::iterator_range<helper_expr_const_iterator> + helper_expr_const_range; + + helper_expr_const_range source_exprs() const { + return helper_expr_const_range(getSourceExprs().begin(), + getSourceExprs().end()); + } + helper_expr_range source_exprs() { + return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end()); + } + helper_expr_const_range destination_exprs() const { + return helper_expr_const_range(getDestinationExprs().begin(), + getDestinationExprs().end()); + } + helper_expr_range destination_exprs() { + return helper_expr_range(getDestinationExprs().begin(), + getDestinationExprs().end()); + } + helper_expr_const_range assignment_ops() const { + return helper_expr_const_range(getAssignmentOps().begin(), + getAssignmentOps().end()); + } + helper_expr_range assignment_ops() { + return helper_expr_range(getAssignmentOps().begin(), + getAssignmentOps().end()); + } + StmtRange children() { return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 7b77998..667f235 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -159,12 +159,12 @@ private: const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets); - ~ASTRecordLayout() {} + ~ASTRecordLayout() = default; void Destroy(ASTContext &Ctx); - ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION; - void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION; + ASTRecordLayout(const ASTRecordLayout &) = delete; + void operator=(const ASTRecordLayout &) = delete; public: /// getAlignment - Get the record alignment in characters. diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index a1d3618..95e0df3 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -857,7 +857,7 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C) { - if (C->isInitCapture()) + if (LE->isInitCapture(C)) TRY_TO(TraverseDecl(C->getCapturedVar())); return true; } @@ -1356,6 +1356,8 @@ DEF_TRAVERSE_DECL( // D->getAnonymousNamespace(). }) +DEF_TRAVERSE_DECL(ExternCContextDecl, {}) + DEF_TRAVERSE_DECL(NamespaceAliasDecl, { // We shouldn't traverse an aliased namespace, since it will be // defined (and, therefore, traversed) somewhere else. @@ -2032,12 +2034,20 @@ DEF_TRAVERSE_STMT(CXXStaticCastExpr, { // to the syntactic form. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { - if (InitListExpr *Syn = S->getSyntacticForm()) - S = Syn; - TRY_TO(WalkUpFromInitListExpr(S)); - // All we need are the default actions. FIXME: use a helper function. - for (Stmt::child_range range = S->children(); range; ++range) { - TRY_TO(TraverseStmt(*range)); + InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S; + if (Syn) { + TRY_TO(WalkUpFromInitListExpr(Syn)); + // All we need are the default actions. FIXME: use a helper function. + for (Stmt::child_range range = Syn->children(); range; ++range) { + TRY_TO(TraverseStmt(*range)); + } + } + InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm(); + if (Sem) { + TRY_TO(WalkUpFromInitListExpr(Sem)); + for (Stmt::child_range range = Sem->children(); range; ++range) { + TRY_TO(TraverseStmt(*range)); + } } return true; } @@ -2455,6 +2465,7 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { TRY_TO(TraverseStmt(C->getChunkSize())); + TRY_TO(TraverseStmt(C->getHelperChunkSize())); return true; } @@ -2539,6 +2550,18 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause( OMPLastprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->private_copies()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->source_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->destination_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->assignment_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2551,7 +2574,17 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) { template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) { TRY_TO(TraverseStmt(C->getStep())); + TRY_TO(TraverseStmt(C->getCalcStep())); TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->inits()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->updates()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->finals()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2565,6 +2598,15 @@ bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) { template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) { TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->source_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->destination_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->assignment_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2572,6 +2614,15 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause( OMPCopyprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->source_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->destination_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->assignment_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } @@ -2581,6 +2632,15 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->lhs_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->rhs_exprs()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->reduction_ops()) { + TRY_TO(TraverseStmt(E)); + } return true; } diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index 7aa11d4..92046d5 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -92,6 +92,13 @@ protected: } void markIncomplete() { Next.get<KnownLatest>().markIncomplete(); } + + Decl *getLatestNotUpdated() const { + assert(NextIsLatest() && "expected a canonical decl"); + if (Next.is<NotKnownLatest>()) + return nullptr; + return Next.get<KnownLatest>().getNotUpdated(); + } }; static DeclLink PreviousDeclLink(decl_type *D) { @@ -114,14 +121,15 @@ protected: /// /// If there is only one declaration, it is <pointer to self, true> DeclLink RedeclLink; + decl_type *First; decl_type *getNextRedeclaration() const { return RedeclLink.getNext(static_cast<const decl_type *>(this)); } public: - Redeclarable(const ASTContext &Ctx) - : RedeclLink(LatestDeclLink(Ctx)) {} + Redeclarable(const ASTContext &Ctx) + : RedeclLink(LatestDeclLink(Ctx)), First(static_cast<decl_type *>(this)) {} /// \brief Return the previous declaration of this declaration or NULL if this /// is the first declaration. @@ -137,21 +145,11 @@ public: /// \brief Return the first declaration of this declaration or itself if this /// is the only declaration. - decl_type *getFirstDecl() { - decl_type *D = static_cast<decl_type*>(this); - while (D->getPreviousDecl()) - D = D->getPreviousDecl(); - return D; - } + decl_type *getFirstDecl() { return First; } /// \brief Return the first declaration of this declaration or itself if this /// is the only declaration. - const decl_type *getFirstDecl() const { - const decl_type *D = static_cast<const decl_type*>(this); - while (D->getPreviousDecl()) - D = D->getPreviousDecl(); - return D; - } + const decl_type *getFirstDecl() const { return First; } /// \brief True if this is the first declaration in its redeclaration chain. bool isFirstDecl() const { return RedeclLink.NextIsLatest(); } diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index eb6836f..ce9449d 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -58,7 +58,9 @@ namespace clang { class Stmt; class Expr; - class ExprIterator { + class ExprIterator : public std::iterator<std::forward_iterator_tag, + Expr *&, ptrdiff_t, + Expr *&, Expr *&> { Stmt** I; public: ExprIterator(Stmt** i) : I(i) {} @@ -77,7 +79,10 @@ namespace clang { bool operator>=(const ExprIterator& R) const { return I >= R.I; } }; - class ConstExprIterator { + class ConstExprIterator : public std::iterator<std::forward_iterator_tag, + const Expr *&, ptrdiff_t, + const Expr *&, + const Expr *&> { const Stmt * const *I; public: ConstExprIterator(const Stmt * const *i) : I(i) {} @@ -101,7 +106,7 @@ namespace clang { /// Stmt - This represents one statement. /// -class Stmt { +class LLVM_ALIGNAS(LLVM_PTR_SIZE) Stmt { public: enum StmtClass { NoStmtClass = 0, @@ -287,9 +292,6 @@ protected: }; union { - // FIXME: this is wasteful on 64-bit platforms. - void *Aligner; - StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; ExprBitfields ExprBits; @@ -341,13 +343,12 @@ private: protected: /// \brief Construct an empty statement. - explicit Stmt(StmtClass SC, EmptyShell) { - StmtBits.sClass = SC; - if (StatisticsEnabled) Stmt::addStmtClass(SC); - } + explicit Stmt(StmtClass SC, EmptyShell) : Stmt(SC) {} public: Stmt(StmtClass SC) { + static_assert(sizeof(*this) % llvm::AlignOf<void *>::Alignment == 0, + "Insufficient alignment!"); StmtBits.sClass = SC; if (StatisticsEnabled) Stmt::addStmtClass(SC); } @@ -374,6 +375,7 @@ public: void dump() const; void dump(SourceManager &SM) const; void dump(raw_ostream &OS, SourceManager &SM) const; + void dump(raw_ostream &OS) const; /// dumpColor - same as dump(), but forces color highlighting. void dumpColor() const; @@ -583,6 +585,7 @@ public: body_range body() { return body_range(body_begin(), body_end()); } body_iterator body_begin() { return Body; } body_iterator body_end() { return Body + size(); } + Stmt *body_front() { return !body_empty() ? Body[0] : nullptr; } Stmt *body_back() { return !body_empty() ? Body[size()-1] : nullptr; } void setLastStmt(Stmt *S) { @@ -598,6 +601,9 @@ public: } const_body_iterator body_begin() const { return Body; } const_body_iterator body_end() const { return Body + size(); } + const Stmt *body_front() const { + return !body_empty() ? Body[0] : nullptr; + } const Stmt *body_back() const { return !body_empty() ? Body[size() - 1] : nullptr; } @@ -684,10 +690,10 @@ public: }; class CaseStmt : public SwitchCase { + SourceLocation EllipsisLoc; enum { LHS, RHS, SUBSTMT, END_EXPR }; Stmt* SubExprs[END_EXPR]; // The expression for the RHS is Non-null for // GNU "case 1 ... 4" extension - SourceLocation EllipsisLoc; public: CaseStmt(Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc) @@ -784,12 +790,16 @@ inline SourceLocation SwitchCase::getLocEnd() const { /// foo: return; /// class LabelStmt : public Stmt { + SourceLocation IdentLoc; LabelDecl *TheDecl; Stmt *SubStmt; - SourceLocation IdentLoc; + public: LabelStmt(SourceLocation IL, LabelDecl *D, Stmt *substmt) - : Stmt(LabelStmtClass), TheDecl(D), SubStmt(substmt), IdentLoc(IL) { + : Stmt(LabelStmtClass), IdentLoc(IL), TheDecl(D), SubStmt(substmt) { + static_assert(sizeof(LabelStmt) == + 2 * sizeof(SourceLocation) + 2 * sizeof(void *), + "LabelStmt too big"); } // \brief Build an empty label statement. @@ -939,16 +949,14 @@ public: /// SwitchStmt - This represents a 'switch' stmt. /// class SwitchStmt : public Stmt { + SourceLocation SwitchLoc; enum { VAR, COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; - // This points to a linked list of case and default statements. - SwitchCase *FirstCase; - SourceLocation SwitchLoc; - - /// If the SwitchStmt is a switch on an enum value, this records whether - /// all the enum values were covered by CaseStmts. This value is meant to - /// be a hint for possible clients. - unsigned AllEnumCasesCovered : 1; + // This points to a linked list of case and default statements and, if the + // SwitchStmt is a switch on an enum value, records whether all the enum + // values were covered by CaseStmts. The coverage information value is meant + // to be a hint for possible clients. + llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase; public: SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); @@ -976,16 +984,16 @@ public: const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} const Stmt *getBody() const { return SubExprs[BODY]; } - const SwitchCase *getSwitchCaseList() const { return FirstCase; } + const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); } Expr *getCond() { return reinterpret_cast<Expr*>(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } Stmt *getBody() { return SubExprs[BODY]; } void setBody(Stmt *S) { SubExprs[BODY] = S; } - SwitchCase *getSwitchCaseList() { return FirstCase; } + SwitchCase *getSwitchCaseList() { return FirstCase.getPointer(); } /// \brief Set the case list for this switch statement. - void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; } + void setSwitchCaseList(SwitchCase *SC) { FirstCase.setPointer(SC); } SourceLocation getSwitchLoc() const { return SwitchLoc; } void setSwitchLoc(SourceLocation L) { SwitchLoc = L; } @@ -997,21 +1005,17 @@ public: void addSwitchCase(SwitchCase *SC) { assert(!SC->getNextSwitchCase() && "case/default already added to a switch"); - SC->setNextSwitchCase(FirstCase); - FirstCase = SC; + SC->setNextSwitchCase(FirstCase.getPointer()); + FirstCase.setPointer(SC); } /// Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a /// switch over an enum value then all cases have been explicitly covered. - void setAllEnumCasesCovered() { - AllEnumCasesCovered = 1; - } + void setAllEnumCasesCovered() { FirstCase.setInt(true); } /// Returns true if the SwitchStmt is a switch of an enum value and all cases /// have been explicitly covered. - bool isAllEnumCasesCovered() const { - return (bool) AllEnumCasesCovered; - } + bool isAllEnumCasesCovered() const { return FirstCase.getInt(); } SourceLocation getLocStart() const LLVM_READONLY { return SwitchLoc; } SourceLocation getLocEnd() const LLVM_READONLY { @@ -1032,9 +1036,9 @@ public: /// WhileStmt - This represents a 'while' stmt. /// class WhileStmt : public Stmt { + SourceLocation WhileLoc; enum { VAR, COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; - SourceLocation WhileLoc; public: WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, SourceLocation WL); @@ -1087,9 +1091,9 @@ public: /// DoStmt - This represents a 'do/while' stmt. /// class DoStmt : public Stmt { + SourceLocation DoLoc; enum { BODY, COND, END_EXPR }; Stmt* SubExprs[END_EXPR]; - SourceLocation DoLoc; SourceLocation WhileLoc; SourceLocation RParenLoc; // Location of final ')' in do stmt condition. @@ -1138,9 +1142,9 @@ public: /// specified in the source. /// class ForStmt : public Stmt { + SourceLocation ForLoc; enum { INIT, CONDVAR, COND, INC, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; // SubExprs[INIT] is an expression or declstmt. - SourceLocation ForLoc; SourceLocation LParenLoc, RParenLoc; public: @@ -1310,8 +1314,12 @@ public: /// class BreakStmt : public Stmt { SourceLocation BreakLoc; + public: - BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) {} + BreakStmt(SourceLocation BL) : Stmt(BreakStmtClass), BreakLoc(BL) { + static_assert(sizeof(BreakStmt) == 2 * sizeof(SourceLocation), + "BreakStmt too large"); + } /// \brief Build an empty break statement. explicit BreakStmt(EmptyShell Empty) : Stmt(BreakStmtClass, Empty) { } @@ -1341,18 +1349,16 @@ public: /// depend on the return type of the function and the presence of an argument. /// class ReturnStmt : public Stmt { - Stmt *RetExpr; SourceLocation RetLoc; + Stmt *RetExpr; const VarDecl *NRVOCandidate; public: - ReturnStmt(SourceLocation RL) - : Stmt(ReturnStmtClass), RetExpr(nullptr), RetLoc(RL), - NRVOCandidate(nullptr) {} + explicit ReturnStmt(SourceLocation RL) : ReturnStmt(RL, nullptr, nullptr) {} ReturnStmt(SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate) - : Stmt(ReturnStmtClass), RetExpr((Stmt*) E), RetLoc(RL), - NRVOCandidate(NRVOCandidate) {} + : Stmt(ReturnStmtClass), RetLoc(RL), RetExpr((Stmt *)E), + NRVOCandidate(NRVOCandidate) {} /// \brief Build an empty return expression. explicit ReturnStmt(EmptyShell Empty) : Stmt(ReturnStmtClass, Empty) { } diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 837dc45..567a772 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -126,11 +126,11 @@ public: /// analysis of the constituent components. The original syntactic components /// can be extracted using getLoopVariable and getRangeInit. class CXXForRangeStmt : public Stmt { + SourceLocation ForLoc; enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; - SourceLocation ForLoc; SourceLocation ColonLoc; SourceLocation RParenLoc; public: diff --git a/include/clang/AST/StmtIterator.h b/include/clang/AST/StmtIterator.h index 6ffe74f..ec7329a 100644 --- a/include/clang/AST/StmtIterator.h +++ b/include/clang/AST/StmtIterator.h @@ -148,7 +148,7 @@ struct StmtRange : std::pair<StmtIterator,StmtIterator> { : std::pair<StmtIterator,StmtIterator>(begin, end) {} bool empty() const { return first == second; } - LLVM_EXPLICIT operator bool() const { return !empty(); } + explicit operator bool() const { return !empty(); } Stmt *operator->() const { return first.operator->(); } Stmt *&operator*() const { return first.operator*(); } @@ -191,7 +191,7 @@ struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> { : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {} bool empty() const { return first == second; } - LLVM_EXPLICIT operator bool() const { return !empty(); } + explicit operator bool() const { return !empty(); } const Stmt *operator->() const { return first.operator->(); } const Stmt *operator*() const { return first.operator*(); } diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index d0527e2..68fe3ef 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -118,12 +118,13 @@ public: /// \brief Represents Objective-C's \@finally statement class ObjCAtFinallyStmt : public Stmt { - Stmt *AtFinallyStmt; SourceLocation AtFinallyLoc; + Stmt *AtFinallyStmt; + public: ObjCAtFinallyStmt(SourceLocation atFinallyLoc, Stmt *atFinallyStmt) - : Stmt(ObjCAtFinallyStmtClass), - AtFinallyStmt(atFinallyStmt), AtFinallyLoc(atFinallyLoc) {} + : Stmt(ObjCAtFinallyStmtClass), AtFinallyLoc(atFinallyLoc), + AtFinallyStmt(atFinallyStmt) {} explicit ObjCAtFinallyStmt(EmptyShell Empty) : Stmt(ObjCAtFinallyStmtClass, Empty) { } @@ -260,9 +261,9 @@ public: /// \endcode class ObjCAtSynchronizedStmt : public Stmt { private: + SourceLocation AtSynchronizedLoc; enum { SYNC_EXPR, SYNC_BODY, END_EXPR }; Stmt* SubStmts[END_EXPR]; - SourceLocation AtSynchronizedLoc; public: ObjCAtSynchronizedStmt(SourceLocation atSynchronizedLoc, Stmt *synchExpr, @@ -310,8 +311,9 @@ public: /// \brief Represents Objective-C's \@throw statement. class ObjCAtThrowStmt : public Stmt { - Stmt *Throw; SourceLocation AtThrowLoc; + Stmt *Throw; + public: ObjCAtThrowStmt(SourceLocation atThrowLoc, Stmt *throwExpr) : Stmt(ObjCAtThrowStmtClass), Throw(throwExpr) { @@ -341,13 +343,12 @@ public: /// \brief Represents Objective-C's \@autoreleasepool Statement class ObjCAutoreleasePoolStmt : public Stmt { - Stmt *SubStmt; SourceLocation AtLoc; + Stmt *SubStmt; + public: - ObjCAutoreleasePoolStmt(SourceLocation atLoc, - Stmt *subStmt) - : Stmt(ObjCAutoreleasePoolStmtClass), - SubStmt(subStmt), AtLoc(atLoc) {} + ObjCAutoreleasePoolStmt(SourceLocation atLoc, Stmt *subStmt) + : Stmt(ObjCAutoreleasePoolStmtClass), AtLoc(atLoc), SubStmt(subStmt) {} explicit ObjCAutoreleasePoolStmt(EmptyShell Empty) : Stmt(ObjCAutoreleasePoolStmtClass, Empty) { } diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index aed7691..5161eff 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -95,6 +95,7 @@ public: /// This iterator visits only those declarations that meet some run-time /// criteria. template <class FilterPredicate> class filtered_clause_iterator { + protected: ArrayRef<OMPClause *>::const_iterator Current; ArrayRef<OMPClause *>::const_iterator End; FilterPredicate Pred; @@ -107,7 +108,7 @@ public: typedef const OMPClause *value_type; filtered_clause_iterator() : Current(), End() {} filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred) - : Current(Arr.begin()), End(Arr.end()), Pred(Pred) { + : Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) { SkipToNextClause(); } value_type operator*() const { return *Current; } @@ -125,9 +126,25 @@ public: } bool operator!() { return Current == End; } - operator bool() { return Current != End; } + explicit operator bool() { return Current != End; } + bool empty() const { return Current == End; } }; + template <typename Fn> + filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const { + return filtered_clause_iterator<Fn>(clauses(), std::move(fn)); + } + struct ClauseKindFilter { + OpenMPClauseKind Kind; + bool operator()(const OMPClause *clause) const { + return clause->getClauseKind() == Kind; + } + }; + filtered_clause_iterator<ClauseKindFilter> + getClausesOfKind(OpenMPClauseKind Kind) const { + return getFilteredClauses(ClauseKindFilter{Kind}); + } + /// \brief Gets a single clause of the specified kind \a K associated with the /// current directive iff there is only one clause of this kind (and assertion /// is fired if there is more than one clause is associated with the @@ -410,6 +427,8 @@ public: Expr *IterationVarRef; /// \brief Loop last iteration number. Expr *LastIteration; + /// \brief Loop number of iterations. + Expr *NumIterations; /// \brief Calculation of last iteration. Expr *CalcLastIteration; /// \brief Loop pre-condition. @@ -447,8 +466,9 @@ public: /// worksharing ones). bool builtAll() { return IterationVarRef != nullptr && LastIteration != nullptr && - PreCond != nullptr && Cond != nullptr && - SeparatedCond != nullptr && Init != nullptr && Inc != nullptr; + NumIterations != nullptr && PreCond != nullptr && + Cond != nullptr && SeparatedCond != nullptr && Init != nullptr && + Inc != nullptr; } /// \brief Initialize all the fields to null. @@ -1557,6 +1577,26 @@ public: /// class OMPAtomicDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may + /// have atomic expressions of forms + /// \code + /// x = x binop expr; + /// x = expr binop x; + /// \endcode + /// This field is true for the first form of the expression and false for the + /// second. Required for correct codegen of non-associative operations (like + /// << or >>). + bool IsXLHSInRHSPart; + /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may + /// have atomic expressions of forms + /// \code + /// v = x; <update x>; + /// <update x>; v = x; + /// \endcode + /// This field is true for the first(postfix) form of the expression and false + /// otherwise. + bool IsPostfixUpdate; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -1566,7 +1606,8 @@ class OMPAtomicDirective : public OMPExecutableDirective { OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic, - StartLoc, EndLoc, NumClauses, 4) {} + StartLoc, EndLoc, NumClauses, 5), + IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} /// \brief Build an empty directive. /// @@ -1575,14 +1616,19 @@ class OMPAtomicDirective : public OMPExecutableDirective { explicit OMPAtomicDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic, SourceLocation(), SourceLocation(), NumClauses, - 4) {} + 5), + IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} /// \brief Set 'x' part of the associated expression/statement. void setX(Expr *X) { *std::next(child_begin()) = X; } + /// \brief Set helper expression of the form + /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or + /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. + void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; } /// \brief Set 'v' part of the associated expression/statement. - void setV(Expr *V) { *std::next(child_begin(), 2) = V; } + void setV(Expr *V) { *std::next(child_begin(), 3) = V; } /// \brief Set 'expr' part of the associated expression/statement. - void setExpr(Expr *E) { *std::next(child_begin(), 3) = E; } + void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; } public: /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' @@ -1597,11 +1643,17 @@ public: /// \param X 'x' part of the associated expression/statement. /// \param V 'v' part of the associated expression/statement. /// \param E 'expr' part of the associated expression/statement. - /// + /// \param UE Helper expression of the form + /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or + /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. + /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the + /// second. + /// \param IsPostfixUpdate true if original value of 'x' must be stored in + /// 'v', not an updated one. static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, - Expr *E); + Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1617,15 +1669,31 @@ public: const Expr *getX() const { return cast_or_null<Expr>(*std::next(child_begin())); } + /// \brief Get helper expression of the form + /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or + /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. + Expr *getUpdateExpr() { + return cast_or_null<Expr>(*std::next(child_begin(), 2)); + } + const Expr *getUpdateExpr() const { + return cast_or_null<Expr>(*std::next(child_begin(), 2)); + } + /// \brief Return true if helper update expression has form + /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form + /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. + bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } + /// \brief Return true if 'v' expression must be updated to original value of + /// 'x', false if 'v' must be updated to the new value of 'x'. + bool isPostfixUpdate() const { return IsPostfixUpdate; } /// \brief Get 'v' part of the associated expression/statement. - Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 2)); } + Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); } const Expr *getV() const { - return cast_or_null<Expr>(*std::next(child_begin(), 2)); + return cast_or_null<Expr>(*std::next(child_begin(), 3)); } /// \brief Get 'expr' part of the associated expression/statement. - Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); } + Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); } const Expr *getExpr() const { - return cast_or_null<Expr>(*std::next(child_begin(), 3)); + return cast_or_null<Expr>(*std::next(child_begin(), 4)); } static bool classof(const Stmt *T) { diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 80b68bc..1d01753 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -114,7 +114,7 @@ private: struct TV TypeOrValue; }; - TemplateArgument(TemplateName, bool) LLVM_DELETED_FUNCTION; + TemplateArgument(TemplateName, bool) = delete; public: /// \brief Construct an empty, invalid template argument. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 1bda01f..8cd29b7 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -456,7 +456,7 @@ public: bool operator==(Qualifiers Other) const { return Mask == Other.Mask; } bool operator!=(Qualifiers Other) const { return Mask != Other.Mask; } - LLVM_EXPLICIT operator bool() const { return hasQualifiers(); } + explicit operator bool() const { return hasQualifiers(); } Qualifiers &operator+=(Qualifiers R) { addQualifiers(R); @@ -1179,8 +1179,8 @@ public: }; private: - Type(const Type &) LLVM_DELETED_FUNCTION; - void operator=(const Type &) LLVM_DELETED_FUNCTION; + Type(const Type &) = delete; + void operator=(const Type &) = delete; /// Bitfields required by the Type class. class TypeBitfields { @@ -1575,6 +1575,7 @@ public: bool isObjCLifetimeType() const; // (array of)* retainable type bool isObjCIndirectLifetimeType() const; // (pointer to)* lifetime type bool isObjCNSObjectType() const; // __attribute__((NSObject)) + bool isObjCIndependentClassType() const; // __attribute__((objc_independent_class)) // FIXME: change this to 'raw' interface type, so we can used 'interface' type // for the common case. bool isObjCObjectType() const; // NSString or typeof(*(id)0) @@ -3472,7 +3473,6 @@ public: attr_thiscall, attr_pascal, attr_vectorcall, - attr_pnaclcall, attr_inteloclbicc, attr_ms_abi, attr_sysv_abi, diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 4f3c811..e29fa49 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -93,7 +93,7 @@ public: } bool isNull() const { return !Ty; } - LLVM_EXPLICIT operator bool() const { return Ty; } + explicit operator bool() const { return Ty; } /// \brief Returns the size of type source info data block for the given type. static unsigned getFullDataSizeForType(QualType Ty); diff --git a/include/clang/AST/TypeNodes.def b/include/clang/AST/TypeNodes.def index 3b2665b..2549f0b 100644 --- a/include/clang/AST/TypeNodes.def +++ b/include/clang/AST/TypeNodes.def @@ -11,7 +11,7 @@ // enumerated by providing its name (e.g., "Builtin" or "Enum") and // base class (e.g., "Type" or "TagType"). Depending on where in the // abstract syntax tree the type will show up, the enumeration uses -// one of four different macros: +// one of five different macros: // // TYPE(Class, Base) - A type that can show up anywhere in the AST, // and might be dependent, canonical, or non-canonical. All clients diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index a11f22d..26ee1cf 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -19,74 +19,36 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" -#include <iterator> +#include "llvm/ADT/iterator.h" namespace clang { /// The iterator over UnresolvedSets. Serves as both the const and /// non-const iterator. -class UnresolvedSetIterator { -private: - typedef MutableArrayRef<DeclAccessPair> DeclsTy; - typedef DeclsTy::iterator IteratorTy; - - IteratorTy ir; - +class UnresolvedSetIterator : public llvm::iterator_adaptor_base< + UnresolvedSetIterator, DeclAccessPair *, + std::random_access_iterator_tag, NamedDecl *, + std::ptrdiff_t, NamedDecl *, NamedDecl *> { friend class UnresolvedSetImpl; friend class ASTUnresolvedSet; friend class OverloadExpr; - explicit UnresolvedSetIterator(DeclsTy::iterator ir) : ir(ir) {} - explicit UnresolvedSetIterator(DeclsTy::const_iterator ir) : - ir(const_cast<DeclsTy::iterator>(ir)) {} - - IteratorTy getIterator() const { return ir; } - + + explicit UnresolvedSetIterator(DeclAccessPair *Iter) + : iterator_adaptor_base(Iter) {} + explicit UnresolvedSetIterator(const DeclAccessPair *Iter) + : iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {} + public: UnresolvedSetIterator() {} - typedef std::iterator_traits<IteratorTy>::difference_type difference_type; - typedef NamedDecl *value_type; - typedef NamedDecl **pointer; - typedef NamedDecl *reference; - typedef std::iterator_traits<IteratorTy>::iterator_category iterator_category; - - NamedDecl *getDecl() const { return ir->getDecl(); } - void setDecl(NamedDecl *ND) const { return ir->setDecl(ND); } - AccessSpecifier getAccess() const { return ir->getAccess(); } - void setAccess(AccessSpecifier AS) { ir->setAccess(AS); } - DeclAccessPair getPair() const { return *ir; } + NamedDecl *getDecl() const { return I->getDecl(); } + void setDecl(NamedDecl *ND) const { return I->setDecl(ND); } + AccessSpecifier getAccess() const { return I->getAccess(); } + void setAccess(AccessSpecifier AS) { I->setAccess(AS); } + const DeclAccessPair &getPair() const { return *I; } NamedDecl *operator*() const { return getDecl(); } - - UnresolvedSetIterator &operator++() { ++ir; return *this; } - UnresolvedSetIterator operator++(int) { return UnresolvedSetIterator(ir++); } - UnresolvedSetIterator &operator--() { --ir; return *this; } - UnresolvedSetIterator operator--(int) { return UnresolvedSetIterator(ir--); } - - UnresolvedSetIterator &operator+=(difference_type d) { - ir += d; return *this; - } - UnresolvedSetIterator operator+(difference_type d) const { - return UnresolvedSetIterator(ir + d); - } - UnresolvedSetIterator &operator-=(difference_type d) { - ir -= d; return *this; - } - UnresolvedSetIterator operator-(difference_type d) const { - return UnresolvedSetIterator(ir - d); - } - value_type operator[](difference_type d) const { return *(*this + d); } - - difference_type operator-(const UnresolvedSetIterator &o) const { - return ir - o.ir; - } - - bool operator==(const UnresolvedSetIterator &o) const { return ir == o.ir; } - bool operator!=(const UnresolvedSetIterator &o) const { return ir != o.ir; } - bool operator<(const UnresolvedSetIterator &o) const { return ir < o.ir; } - bool operator<=(const UnresolvedSetIterator &o) const { return ir <= o.ir; } - bool operator>=(const UnresolvedSetIterator &o) const { return ir >= o.ir; } - bool operator>(const UnresolvedSetIterator &o) const { return ir > o.ir; } + NamedDecl *operator->() const { return **this; } }; /// \brief A set of unresolved declarations. @@ -132,21 +94,17 @@ public: /// Replaces the declaration at the given iterator with the new one, /// preserving the original access bits. - void replace(iterator I, NamedDecl *New) { - I.ir->setDecl(New); - } + void replace(iterator I, NamedDecl *New) { I.I->setDecl(New); } void replace(iterator I, NamedDecl *New, AccessSpecifier AS) { - I.ir->set(New, AS); + I.I->set(New, AS); } void erase(unsigned I) { decls()[I] = decls().pop_back_val(); } - void erase(iterator I) { *I.ir = decls().pop_back_val(); } + void erase(iterator I) { *I.I = decls().pop_back_val(); } - void setAccess(iterator I, AccessSpecifier AS) { - I.ir->setAccess(AS); - } + void setAccess(iterator I, AccessSpecifier AS) { I.I->setAccess(AS); } void clear() { decls().clear(); } void set_size(unsigned N) { decls().set_size(N); } @@ -154,9 +112,7 @@ public: bool empty() const { return decls().empty(); } unsigned size() const { return decls().size(); } - void append(iterator I, iterator E) { - decls().append(I.ir, E.ir); - } + void append(iterator I, iterator E) { decls().append(I.I, E.I); } DeclAccessPair &operator[](unsigned I) { return decls()[I]; } const DeclAccessPair &operator[](unsigned I) const { return decls()[I]; } diff --git a/include/clang/AST/VTableBuilder.h b/include/clang/AST/VTableBuilder.h index 4e24bdd..ebfbb8a 100644 --- a/include/clang/AST/VTableBuilder.h +++ b/include/clang/AST/VTableBuilder.h @@ -333,7 +333,7 @@ private: public: ItaniumVTableContext(ASTContext &Context); - ~ItaniumVTableContext(); + ~ItaniumVTableContext() override; const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { computeVTableRelatedInformation(RD); @@ -511,7 +511,7 @@ public: MicrosoftVTableContext(ASTContext &Context) : VTableContextBase(/*MS=*/true), Context(Context) {} - ~MicrosoftVTableContext(); + ~MicrosoftVTableContext() override; const VPtrInfoVector &getVFPtrOffsets(const CXXRecordDecl *RD); diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index f002cb9..7f97646 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -47,6 +47,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclFriend.h" +#include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/ASTMatchers/ASTMatchersInternal.h" #include "clang/ASTMatchers/ASTMatchersMacros.h" @@ -143,6 +144,20 @@ typedef internal::Matcher<NestedNameSpecifierLoc> NestedNameSpecifierLocMatcher; /// Usable as: Any Matcher inline internal::TrueMatcher anything() { return internal::TrueMatcher(); } +/// \brief Matches the top declaration context. +/// +/// Given +/// \code +/// int X; +/// namespace NS { +/// int Y; +/// } // namespace NS +/// \endcode +/// decl(hasDeclContext(translationUnitDecl())) +/// matches "int X", but not "int Y". +const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl> + translationUnitDecl; + /// \brief Matches typedef declarations. /// /// Given @@ -167,8 +182,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl; /// /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> AST_POLYMORPHIC_MATCHER(isExpansionInMainFile, - AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt, - TypeLoc)) { + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) { auto &SourceManager = Finder->getASTContext().getSourceManager(); return SourceManager.isInMainFile( SourceManager.getExpansionLoc(Node.getLocStart())); @@ -189,8 +203,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile, /// /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader, - AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt, - TypeLoc)) { + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc)) { auto &SourceManager = Finder->getASTContext().getSourceManager(); auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart()); if (ExpansionLoc.isInvalid()) { @@ -215,8 +228,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader, /// /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, - AST_POLYMORPHIC_SUPPORTED_TYPES_3(Decl, Stmt, - TypeLoc), + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc), std::string, RegExp) { auto &SourceManager = Finder->getASTContext().getSourceManager(); auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getLocStart()); @@ -442,8 +454,8 @@ AST_MATCHER(Decl, isImplicit) { /// matches the specialization \c A<int> AST_POLYMORPHIC_MATCHER_P( hasAnyTemplateArgument, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl, - TemplateSpecializationType), + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + TemplateSpecializationType), internal::Matcher<TemplateArgument>, InnerMatcher) { ArrayRef<TemplateArgument> List = internal::getTemplateSpecializationArgs(Node); @@ -542,8 +554,8 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, /// matches the specialization \c A<bool, int> AST_POLYMORPHIC_MATCHER_P2( hasTemplateArgument, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl, - TemplateSpecializationType), + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + TemplateSpecializationType), unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) { ArrayRef<TemplateArgument> List = internal::getTemplateSpecializationArgs(Node); @@ -563,8 +575,8 @@ AST_POLYMORPHIC_MATCHER_P2( /// matches C<int>. AST_POLYMORPHIC_MATCHER_P( templateArgumentCountIs, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(ClassTemplateSpecializationDecl, - TemplateSpecializationType), + AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, + TemplateSpecializationType), unsigned, N) { return internal::getTemplateSpecializationArgs(Node).size() == N; } @@ -745,6 +757,15 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl; +/// \brief Matches conversion operator declarations. +/// +/// Example matches the operator. +/// \code +/// class X { operator int() const; }; +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl> + conversionDecl; + /// \brief Matches variable declarations. /// /// Note: this does not match declarations of member variables, which are @@ -858,6 +879,20 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXMemberCallExpr> memberCallExpr; +/// \brief Matches ObjectiveC Message invocation expressions. +/// +/// The innermost message send invokes the "alloc" class method on the +/// NSString class, while the outermost message send invokes the +/// "initWithString" instance method on the object returned from +/// NSString's "alloc". This matcher should match both message sends. +/// \code +/// [[NSString alloc] initWithString:@"Hello"] +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + ObjCMessageExpr> objcMessageExpr; + + /// \brief Matches expressions that introduce cleanups to be run at the end /// of the sub-expression's evaluation. /// @@ -1406,6 +1441,11 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXNullPtrLiteralExpr> nullPtrLiteralExpr; +/// \brief Matches GNU __null expression. +const internal::VariadicDynCastAllOfMatcher< + Stmt, + GNUNullExpr> gnuNullExpr; + /// \brief Matches binary operator expressions. /// /// Example matches a || b @@ -1739,12 +1779,11 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl> inline internal::PolymorphicMatcherWithParam1< internal::HasOverloadedOperatorNameMatcher, StringRef, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)> + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)> hasOverloadedOperatorName(StringRef Name) { return internal::PolymorphicMatcherWithParam1< internal::HasOverloadedOperatorNameMatcher, StringRef, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(CXXOperatorCallExpr, FunctionDecl)>( - Name); + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name); } /// \brief Matches C++ classes that are directly or indirectly derived from @@ -1997,6 +2036,104 @@ AST_MATCHER_P(CXXMemberCallExpr, on, internal::Matcher<Expr>, InnerMatcher.matches(*ExprNode, Finder, Builder)); } + +/// \brief Matches on the receiver of an ObjectiveC Message expression. +/// +/// Example +/// matcher = objCMessageExpr(hasRecieverType(asString("UIWebView *"))); +/// matches the [webView ...] message invocation. +/// \code +/// NSString *webViewJavaScript = ... +/// UIWebView *webView = ... +/// [webView stringByEvaluatingJavaScriptFromString:webViewJavascript]; +/// \endcode +AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>, + InnerMatcher) { + const QualType TypeDecl = Node.getReceiverType(); + return InnerMatcher.matches(TypeDecl, Finder, Builder); +} + +/// \brief Matches when BaseName == Selector.getAsString() +/// +/// matcher = objCMessageExpr(hasSelector("loadHTMLString:baseURL:")); +/// matches the outer message expr in the code below, but NOT the message +/// invocation for self.bodyView. +/// \code +/// [self.bodyView loadHTMLString:html baseURL:NULL]; +/// \endcode + AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) { + Selector Sel = Node.getSelector(); + return BaseName.compare(Sel.getAsString()) == 0; +} + + +/// \brief Matches ObjC selectors whose name contains +/// a substring matched by the given RegExp. +/// matcher = objCMessageExpr(matchesSelector("loadHTMLString\:baseURL?")); +/// matches the outer message expr in the code below, but NOT the message +/// invocation for self.bodyView. +/// \code +/// [self.bodyView loadHTMLString:html baseURL:NULL]; +/// \endcode +AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) { + assert(!RegExp.empty()); + std::string SelectorString = Node.getSelector().getAsString(); + llvm::Regex RE(RegExp); + return RE.match(SelectorString); +} + +/// \brief Matches when the selector is the empty selector +/// +/// Matches only when the selector of the objCMessageExpr is NULL. This may +/// represent an error condition in the tree! +AST_MATCHER(ObjCMessageExpr, hasNullSelector) { + return Node.getSelector().isNull(); +} + +/// \brief Matches when the selector is a Unary Selector +/// +/// matcher = objCMessageExpr(matchesSelector(hasUnarySelector()); +/// matches self.bodyView in the code below, but NOT the outer message +/// invocation of "loadHTMLString:baseURL:". +/// \code +/// [self.bodyView loadHTMLString:html baseURL:NULL]; +/// \endcode +AST_MATCHER(ObjCMessageExpr, hasUnarySelector) { + return Node.getSelector().isUnarySelector(); +} + +/// \brief Matches when the selector is a keyword selector +/// +/// objCMessageExpr(hasKeywordSelector()) matches the generated setFrame +/// message expression in +/// +/// \code +/// UIWebView *webView = ...; +/// CGRect bodyFrame = webView.frame; +/// bodyFrame.size.height = self.bodyContentHeight; +/// webView.frame = bodyFrame; +/// // ^---- matches here +/// \endcode + +AST_MATCHER(ObjCMessageExpr, hasKeywordSelector) { + return Node.getSelector().isKeywordSelector(); +} + +/// \brief Matches when the selector has the specified number of arguments +/// +/// matcher = objCMessageExpr(numSelectorArgs(1)); +/// matches self.bodyView in the code below +/// +/// matcher = objCMessageExpr(numSelectorArgs(2)); +/// matches the invocation of "loadHTMLString:baseURL:" but not that +/// of self.bodyView +/// \code +/// [self.bodyView loadHTMLString:html baseURL:NULL]; +/// \endcode +AST_MATCHER_P(ObjCMessageExpr, numSelectorArgs, unsigned, N) { + return Node.getSelector().getNumArgs() == N; +} + /// \brief Matches if the call expression's callee expression matches. /// /// Given @@ -2043,7 +2180,7 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher, /// void y(X &x) { x; X z; } /// \endcode AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, ValueDecl), internal::Matcher<QualType>, InnerMatcher, 0) { return InnerMatcher.matches(Node.getType(), Finder, Builder); } @@ -2065,9 +2202,10 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// \endcode /// /// Usable as: Matcher<Expr>, Matcher<ValueDecl> -AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES_2(Expr, ValueDecl), - internal::Matcher<Decl>, InnerMatcher, 1) { +AST_POLYMORPHIC_MATCHER_P_OVERLOAD(hasType, + AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, + ValueDecl), + internal::Matcher<Decl>, InnerMatcher, 1) { return qualType(hasDeclaration(InnerMatcher)) .matches(Node.getType(), Finder, Builder); } @@ -2303,8 +2441,10 @@ AST_MATCHER(VarDecl, hasGlobalStorage) { /// void f(int x, int y); /// f(0, 0); /// \endcode -AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2( - CallExpr, CXXConstructExpr), +AST_POLYMORPHIC_MATCHER_P(argumentCountIs, + AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, + CXXConstructExpr, + ObjCMessageExpr), unsigned, N) { return Node.getNumArgs() == N; } @@ -2317,10 +2457,11 @@ AST_POLYMORPHIC_MATCHER_P(argumentCountIs, AST_POLYMORPHIC_SUPPORTED_TYPES_2( /// \code /// void x(int) { int y; x(y); } /// \endcode -AST_POLYMORPHIC_MATCHER_P2( - hasArgument, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(CallExpr, CXXConstructExpr), - unsigned, N, internal::Matcher<Expr>, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P2(hasArgument, + AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, + CXXConstructExpr, + ObjCMessageExpr), + unsigned, N, internal::Matcher<Expr>, InnerMatcher) { return (N < Node.getNumArgs() && InnerMatcher.matches( *Node.getArg(N)->IgnoreParenImpCasts(), Finder, Builder)); @@ -2460,8 +2601,9 @@ AST_MATCHER(CXXCtorInitializer, isWritten) { /// the argument before applying the inner matcher. We'll want to remove /// this to allow for greater control by the user once \c ignoreImplicit() /// has been implemented. -AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES_2( - CallExpr, CXXConstructExpr), +AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, + AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, + CXXConstructExpr), internal::Matcher<Expr>, InnerMatcher) { for (const Expr *Arg : Node.arguments()) { BoundNodesTreeBuilder Result(*Builder); @@ -2567,6 +2709,23 @@ AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } +/// \brief Matches constexpr variable and function declarations. +/// +/// Given: +/// \code +/// constexpr int foo = 42; +/// constexpr int bar(); +/// \endcode +/// varDecl(isConstexpr()) +/// matches the declaration of foo. +/// functionDecl(isConstexpr()) +/// matches the declaration of bar. +AST_POLYMORPHIC_MATCHER(isConstexpr, + AST_POLYMORPHIC_SUPPORTED_TYPES(VarDecl, + FunctionDecl)) { + return Node.isConstexpr(); +} + /// \brief Matches the condition expression of an if statement, for loop, /// or conditional operator. /// @@ -2574,10 +2733,11 @@ AST_MATCHER(FunctionDecl, isDeleted) { /// \code /// if (true) {} /// \endcode -AST_POLYMORPHIC_MATCHER_P( - hasCondition, AST_POLYMORPHIC_SUPPORTED_TYPES_5( - IfStmt, ForStmt, WhileStmt, DoStmt, ConditionalOperator), - internal::Matcher<Expr>, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P(hasCondition, + AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, + WhileStmt, DoStmt, + ConditionalOperator), + internal::Matcher<Expr>, InnerMatcher) { const Expr *const Condition = Node.getCond(); return (Condition != nullptr && InnerMatcher.matches(*Condition, Finder, Builder)); @@ -2628,8 +2788,9 @@ AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) { /// forEachDescendant(declRefExpr(to(decl(equalsBoundNode("d")))))) /// will trigger a match for each combination of variable declaration /// and reference to that variable declaration within a compound statement. -AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, AST_POLYMORPHIC_SUPPORTED_TYPES_4( - Stmt, Decl, Type, QualType), +AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, + AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl, Type, + QualType), std::string, ID) { // FIXME: Figure out whether it makes sense to allow this // on any other node types. @@ -2704,9 +2865,9 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// with compoundStmt() /// matching '{}' AST_POLYMORPHIC_MATCHER_P(hasBody, - AST_POLYMORPHIC_SUPPORTED_TYPES_4(DoStmt, ForStmt, - WhileStmt, - CXXForRangeStmt), + AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, + WhileStmt, + CXXForRangeStmt), internal::Matcher<Stmt>, InnerMatcher) { const Stmt *const Statement = Node.getBody(); return (Statement != nullptr && @@ -2768,8 +2929,9 @@ equals(const ValueT &Value) { /// \code /// !(a || b) /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasOperatorName, AST_POLYMORPHIC_SUPPORTED_TYPES_2( - BinaryOperator, UnaryOperator), +AST_POLYMORPHIC_MATCHER_P(hasOperatorName, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, + UnaryOperator), std::string, Name) { return Name == Node.getOpcodeStr(Node.getOpcode()); } @@ -2892,8 +3054,9 @@ AST_MATCHER_P(ConditionalOperator, hasFalseExpression, /// \endcode /// /// Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> -AST_POLYMORPHIC_MATCHER(isDefinition, AST_POLYMORPHIC_SUPPORTED_TYPES_3( - TagDecl, VarDecl, FunctionDecl)) { +AST_POLYMORPHIC_MATCHER(isDefinition, + AST_POLYMORPHIC_SUPPORTED_TYPES(TagDecl, VarDecl, + FunctionDecl)) { return Node.isThisDeclarationADefinition(); } @@ -2979,7 +3142,7 @@ AST_MATCHER(CXXMethodDecl, isConst) { /// \endcode /// matches B::x AST_MATCHER(CXXMethodDecl, isOverride) { - return Node.size_overridden_methods() > 0; + return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>(); } /// \brief Matches member expressions that are called with '->' as opposed @@ -3140,9 +3303,9 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, /// does not match, as X<A> is an explicit template specialization. /// /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> -AST_POLYMORPHIC_MATCHER( - isTemplateInstantiation, - AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) { +AST_POLYMORPHIC_MATCHER(isTemplateInstantiation, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl, + CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ImplicitInstantiation || Node.getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition); @@ -3197,9 +3360,9 @@ AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) { /// matches the specialization A<int>(). /// /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> -AST_POLYMORPHIC_MATCHER( - isExplicitTemplateSpecialization, - AST_POLYMORPHIC_SUPPORTED_TYPES_3(FunctionDecl, VarDecl, CXXRecordDecl)) { +AST_POLYMORPHIC_MATCHER(isExplicitTemplateSpecialization, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl, + CXXRecordDecl)) { return (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization); } @@ -3272,9 +3435,9 @@ AST_TYPE_MATCHER(ComplexType, complexType); /// matches "int b[7]" /// /// Usable as: Matcher<ArrayType>, Matcher<ComplexType> -AST_TYPELOC_TRAVERSE_MATCHER( - hasElementType, getElement, - AST_POLYMORPHIC_SUPPORTED_TYPES_2(ArrayType, ComplexType)); +AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement, + AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType, + ComplexType)); /// \brief Matches C arrays with a specified constant size. /// @@ -3383,7 +3546,7 @@ AST_TYPE_MATCHER(AtomicType, atomicType); /// /// Usable as: Matcher<AtomicType> AST_TYPELOC_TRAVERSE_MATCHER(hasValueType, getValue, - AST_POLYMORPHIC_SUPPORTED_TYPES_1(AtomicType)); + AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType)); /// \brief Matches types nodes representing C++11 auto types. /// @@ -3412,7 +3575,7 @@ AST_TYPE_MATCHER(AutoType, autoType); /// /// Usable as: Matcher<AutoType> AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, - AST_POLYMORPHIC_SUPPORTED_TYPES_1(AutoType)); + AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType)); /// \brief Matches \c FunctionType nodes. /// @@ -3450,7 +3613,7 @@ AST_TYPE_MATCHER(ParenType, parenType); /// /// Usable as: Matcher<ParenType> AST_TYPE_TRAVERSE_MATCHER(innerType, getInnerType, - AST_POLYMORPHIC_SUPPORTED_TYPES_1(ParenType)); + AST_POLYMORPHIC_SUPPORTED_TYPES(ParenType)); /// \brief Matches block pointer types, i.e. types syntactically represented as /// "void (^)(int)". @@ -3544,10 +3707,11 @@ AST_TYPE_MATCHER(RValueReferenceType, rValueReferenceType); /// /// Usable as: Matcher<BlockPointerType>, Matcher<MemberPointerType>, /// Matcher<PointerType>, Matcher<ReferenceType> -AST_TYPELOC_TRAVERSE_MATCHER( - pointee, getPointee, - AST_POLYMORPHIC_SUPPORTED_TYPES_4(BlockPointerType, MemberPointerType, - PointerType, ReferenceType)); +AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee, + AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, + MemberPointerType, + PointerType, + ReferenceType)); /// \brief Matches typedef types. /// diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index ebe5cdd..cbaa4ba 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -38,9 +38,13 @@ #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclTemplate.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" +#include "clang/AST/StmtObjC.h" #include "clang/AST/Type.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/VariadicFunction.h" @@ -139,7 +143,7 @@ public: void setBinding(const std::string &Id, const ast_type_traits::DynTypedNode &DynNode) { if (Bindings.empty()) - Bindings.push_back(BoundNodesMap()); + Bindings.emplace_back(); for (BoundNodesMap &Binding : Bindings) Binding.addNode(Id, DynNode); } @@ -206,7 +210,7 @@ public: template <typename T> class MatcherInterface : public DynMatcherInterface { public: - virtual ~MatcherInterface() {} + ~MatcherInterface() override {} /// \brief Returns true if 'Node' can be matched. /// @@ -381,6 +385,19 @@ private: IntrusiveRefCntPtr<DynMatcherInterface> Implementation; }; +/// \brief Wrapper base class for a wrapping matcher. +/// +/// This is just a container for a DynTypedMatcher that can be used as a base +/// class for another matcher. +template <typename T> +class WrapperMatcherInterface : public MatcherInterface<T> { +protected: + explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher) + : InnerMatcher(std::move(InnerMatcher)) {} + + const DynTypedMatcher InnerMatcher; +}; + /// \brief Wrapper of a MatcherInterface<T> *that allows copying. /// /// A Matcher<Base> can be used anywhere a Matcher<Derived> is @@ -453,19 +470,18 @@ public: /// does only matches in the absence of qualifiers, or not, i.e. simply /// ignores any qualifiers. template <typename TypeT> - class TypeToQualType : public MatcherInterface<QualType> { - public: + class TypeToQualType : public WrapperMatcherInterface<QualType> { + public: TypeToQualType(const Matcher<TypeT> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} + : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {} bool matches(const QualType &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { if (Node.isNull()) return false; - return InnerMatcher.matches(*Node, Finder, Builder); + return this->InnerMatcher.matches( + ast_type_traits::DynTypedNode::create(*Node), Finder, Builder); } - private: - const Matcher<TypeT> InnerMatcher; }; private: @@ -629,13 +645,13 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> { /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but /// not actually used. template <typename T, typename DeclMatcherT> -class HasDeclarationMatcher : public MatcherInterface<T> { +class HasDeclarationMatcher : public WrapperMatcherInterface<T> { static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value, "instantiated with wrong types"); public: explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} + : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { @@ -698,13 +714,12 @@ private: /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node /// is \c NULL. - bool matchesDecl(const Decl *Node, - ASTMatchFinder *Finder, + bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return Node != nullptr && InnerMatcher.matches(*Node, Finder, Builder); + return Node != nullptr && + this->InnerMatcher.matches( + ast_type_traits::DynTypedNode::create(*Node), Finder, Builder); } - - const Matcher<Decl> InnerMatcher; }; /// \brief IsBaseType<T>::value is true if T is a "base" type in the AST @@ -847,19 +862,11 @@ protected: /// \brief A type-list implementation. /// -/// A list is declared as a tree of type list nodes, where the leafs are the -/// types. -/// However, it is used as a "linked list" of types, by using the ::head and -/// ::tail typedefs. -/// Each node supports up to 4 children (instead of just 2) to reduce the -/// nesting required by large lists. -template <typename T1 = void, typename T2 = void, typename T3 = void, - typename T4 = void> -struct TypeList { - /// \brief Implementation detail. Combined with the specializations below, - /// this typedef allows for flattening of nested structures. - typedef TypeList<T1, T2, T3, T4> self; +/// A "linked list" of types, accessible by using the ::head and ::tail +/// typedefs. +template <typename... Ts> struct TypeList {}; // Empty sentinel type list. +template <typename T1, typename... Ts> struct TypeList<T1, Ts...> { /// \brief The first type on the list. typedef T1 head; @@ -867,24 +874,7 @@ struct TypeList { /// /// This type is used to do recursion. TypeList<>/EmptyTypeList indicates the /// end of the list. - typedef typename TypeList<T2, T3, T4>::self tail; -}; - -/// \brief Template specialization to allow nested lists. -/// -/// First element is a typelist. Pop its first element. -template <typename Sub1, typename Sub2, typename Sub3, typename Sub4, - typename T2, typename T3, typename T4> -struct TypeList<TypeList<Sub1, Sub2, Sub3, Sub4>, T2, T3, - T4> : public TypeList<Sub1, - typename TypeList<Sub2, Sub3, Sub4>::self, - typename TypeList<T2, T3, T4>::self> {}; - -/// \brief Template specialization to allow nested lists. -/// -/// First element is an empty typelist. Skip it. -template <typename T2, typename T3, typename T4> -struct TypeList<TypeList<>, T2, T3, T4> : public TypeList<T2, T3, T4> { + typedef TypeList<Ts...> tail; }; /// \brief The empty type list. @@ -906,14 +896,13 @@ struct TypeListContainsSuperOf<EmptyTypeList, T> { /// \brief A "type list" that contains all types. /// /// Useful for matchers like \c anything and \c unless. -typedef TypeList< - TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc>, - TypeList<QualType, Type, TypeLoc, CXXCtorInitializer> > AllNodeBaseTypes; +typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, + QualType, Type, TypeLoc, CXXCtorInitializer> AllNodeBaseTypes; /// \brief Helper meta-function to extract the argument out of a function of /// type void(Arg). /// -/// See AST_POLYMORPHIC_SUPPORTED_TYPES_* for details. +/// See AST_POLYMORPHIC_SUPPORTED_TYPES for details. template <class T> struct ExtractFunctionArgMeta; template <class T> struct ExtractFunctionArgMeta<void(T)> { typedef T type; @@ -921,17 +910,15 @@ template <class T> struct ExtractFunctionArgMeta<void(T)> { /// \brief Default type lists for ArgumentAdaptingMatcher matchers. typedef AllNodeBaseTypes AdaptativeDefaultFromTypes; -typedef TypeList<TypeList<Decl, Stmt, NestedNameSpecifier>, - TypeList<NestedNameSpecifierLoc, TypeLoc, QualType> > -AdaptativeDefaultToTypes; +typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, + TypeLoc, QualType> AdaptativeDefaultToTypes; /// \brief All types that are supported by HasDeclarationMatcher above. -typedef TypeList<TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType>, - TypeList<InjectedClassNameType, LabelStmt, MemberExpr>, - TypeList<QualType, RecordType, TagType>, - TypeList<TemplateSpecializationType, TemplateTypeParmType, - TypedefType, UnresolvedUsingType> > -HasDeclarationSupportedTypes; +typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType, + InjectedClassNameType, LabelStmt, MemberExpr, QualType, + RecordType, TagType, TemplateSpecializationType, + TemplateTypeParmType, TypedefType, + UnresolvedUsingType> HasDeclarationSupportedTypes; /// \brief Converts a \c Matcher<T> to a matcher of desired type \c To by /// "adapting" a \c To into a \c T. @@ -1095,24 +1082,21 @@ public: /// /// ChildT must be an AST base type. template <typename T, typename ChildT> -class HasMatcher : public MatcherInterface<T> { +class HasMatcher : public WrapperMatcherInterface<T> { static_assert(IsBaseType<ChildT>::value, "has only accepts base type matcher"); public: explicit HasMatcher(const Matcher<ChildT> &ChildMatcher) - : ChildMatcher(ChildMatcher) {} + : HasMatcher::WrapperMatcherInterface(ChildMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { return Finder->matchesChildOf( - Node, ChildMatcher, Builder, + Node, this->InnerMatcher, Builder, ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, ASTMatchFinder::BK_First); } - - private: - const Matcher<ChildT> ChildMatcher; }; /// \brief Matches nodes of type T that have child nodes of type ChildT for @@ -1121,176 +1105,65 @@ public: /// As opposed to the HasMatcher, the ForEachMatcher will produce a match /// for each child that matches. template <typename T, typename ChildT> -class ForEachMatcher : public MatcherInterface<T> { +class ForEachMatcher : public WrapperMatcherInterface<T> { static_assert(IsBaseType<ChildT>::value, "for each only accepts base type matcher"); public: - explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher) - : ChildMatcher(ChildMatcher) {} + explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher) + : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {} bool matches(const T& Node, ASTMatchFinder* Finder, BoundNodesTreeBuilder* Builder) const override { return Finder->matchesChildOf( - Node, ChildMatcher, Builder, - ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, - ASTMatchFinder::BK_All); + Node, this->InnerMatcher, Builder, + ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, + ASTMatchFinder::BK_All); } - -private: - const Matcher<ChildT> ChildMatcher; }; /// \brief VariadicOperatorMatcher related types. /// @{ -/// \brief "No argument" placeholder to use as template paratemers. -struct VariadicOperatorNoArg {}; - /// \brief Polymorphic matcher object that uses a \c /// DynTypedMatcher::VariadicOperator operator. /// /// Input matchers can have any type (including other polymorphic matcher /// types), and the actual Matcher<T> is generated on demand with an implicit /// coversion operator. -template <typename P1, typename P2 = VariadicOperatorNoArg, - typename P3 = VariadicOperatorNoArg, - typename P4 = VariadicOperatorNoArg, - typename P5 = VariadicOperatorNoArg, - typename P6 = VariadicOperatorNoArg, - typename P7 = VariadicOperatorNoArg, - typename P8 = VariadicOperatorNoArg, - typename P9 = VariadicOperatorNoArg> -class VariadicOperatorMatcher { +template <typename... Ps> class VariadicOperatorMatcher { public: - VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, - const P1 &Param1, - const P2 &Param2 = VariadicOperatorNoArg(), - const P3 &Param3 = VariadicOperatorNoArg(), - const P4 &Param4 = VariadicOperatorNoArg(), - const P5 &Param5 = VariadicOperatorNoArg(), - const P6 &Param6 = VariadicOperatorNoArg(), - const P7 &Param7 = VariadicOperatorNoArg(), - const P8 &Param8 = VariadicOperatorNoArg(), - const P9 &Param9 = VariadicOperatorNoArg()) - : Op(Op), Param1(Param1), Param2(Param2), Param3(Param3), - Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7), - Param8(Param8), Param9(Param9) {} + VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, Ps &&... Params) + : Op(Op), Params(std::forward<Ps>(Params)...) {} template <typename T> operator Matcher<T>() const { - std::vector<DynTypedMatcher> Matchers; - addMatcher<T>(Param1, Matchers); - addMatcher<T>(Param2, Matchers); - addMatcher<T>(Param3, Matchers); - addMatcher<T>(Param4, Matchers); - addMatcher<T>(Param5, Matchers); - addMatcher<T>(Param6, Matchers); - addMatcher<T>(Param7, Matchers); - addMatcher<T>(Param8, Matchers); - addMatcher<T>(Param9, Matchers); - return DynTypedMatcher::constructVariadic(Op, std::move(Matchers)) + return DynTypedMatcher::constructVariadic( + Op, getMatchers<T>(llvm::index_sequence_for<Ps...>())) .template unconditionalConvertTo<T>(); } private: - template <typename T> - static void addMatcher(const Matcher<T> &M, - std::vector<DynTypedMatcher> &Matchers) { - Matchers.push_back(M); + // Helper method to unpack the tuple into a vector. + template <typename T, std::size_t... Is> + std::vector<DynTypedMatcher> getMatchers(llvm::index_sequence<Is...>) const { + return {Matcher<T>(std::get<Is>(Params))...}; } - /// \brief Overload to ignore \c VariadicOperatorNoArg arguments. - template <typename T> - static void addMatcher(VariadicOperatorNoArg, - std::vector<DynTypedMatcher> &Matchers) {} - const DynTypedMatcher::VariadicOperator Op; - const P1 Param1; - const P2 Param2; - const P3 Param3; - const P4 Param4; - const P5 Param5; - const P6 Param6; - const P7 Param7; - const P8 Param8; - const P9 Param9; + std::tuple<Ps...> Params; }; /// \brief Overloaded function object to generate VariadicOperatorMatcher /// objects from arbitrary matchers. -/// -/// It supports 1-9 argument overloaded operator(). More can be added if needed. template <unsigned MinCount, unsigned MaxCount> struct VariadicOperatorMatcherFunc { DynTypedMatcher::VariadicOperator Op; - template <unsigned Count, typename T> - struct EnableIfValidArity - : public std::enable_if<MinCount <= Count && Count <= MaxCount, T> {}; - - template <typename M1> - typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type - operator()(const M1 &P1) const { - return VariadicOperatorMatcher<M1>(Op, P1); - } - template <typename M1, typename M2> - typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type - operator()(const M1 &P1, const M2 &P2) const { - return VariadicOperatorMatcher<M1, M2>(Op, P1, P2); - } - template <typename M1, typename M2, typename M3> - typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3) const { - return VariadicOperatorMatcher<M1, M2, M3>(Op, P1, P2, P3); - } - template <typename M1, typename M2, typename M3, typename M4> - typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const { - return VariadicOperatorMatcher<M1, M2, M3, M4>(Op, P1, P2, P3, P4); - } - template <typename M1, typename M2, typename M3, typename M4, typename M5> - typename EnableIfValidArity< - 5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, - const M5 &P5) const { - return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Op, P1, P2, P3, P4, P5); - } - template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6> - typename EnableIfValidArity< - 6, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, - const M5 &P5, const M6 &P6) const { - return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6>( - Op, P1, P2, P3, P4, P5, P6); - } - template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7> - typename EnableIfValidArity< - 7, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, - const M5 &P5, const M6 &P6, const M7 &P7) const { - return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7>( - Op, P1, P2, P3, P4, P5, P6, P7); - } - template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8> - typename EnableIfValidArity< - 8, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, - const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const { - return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8>( - Op, P1, P2, P3, P4, P5, P6, P7, P8); - } - template <typename M1, typename M2, typename M3, typename M4, typename M5, - typename M6, typename M7, typename M8, typename M9> - typename EnableIfValidArity< - 9, VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9> >::type - operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, - const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8, - const M9 &P9) const { - return VariadicOperatorMatcher<M1, M2, M3, M4, M5, M6, M7, M8, M9>( - Op, P1, P2, P3, P4, P5, P6, P7, P8, P9); + template <typename... Ms> + VariadicOperatorMatcher<Ms...> operator()(Ms &&... Ps) const { + static_assert(MinCount <= sizeof...(Ms) && sizeof...(Ms) <= MaxCount, + "invalid number of parameters for variadic matcher"); + return VariadicOperatorMatcher<Ms...>(Op, std::forward<Ms>(Ps)...); } }; @@ -1315,11 +1188,9 @@ BindableMatcher<T> makeAllOfComposite( return BindableMatcher<T>(*InnerMatchers[0]); } - std::vector<DynTypedMatcher> DynMatchers; - DynMatchers.reserve(InnerMatchers.size()); - for (const auto *InnerMatcher : InnerMatchers) { - DynMatchers.push_back(*InnerMatcher); - } + typedef llvm::pointee_iterator<const Matcher<T> *const *> PI; + std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()), + PI(InnerMatchers.end())); return BindableMatcher<T>( DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf, std::move(DynMatchers)) @@ -1344,22 +1215,19 @@ BindableMatcher<T> makeDynCastAllOfComposite( /// /// DescendantT must be an AST base type. template <typename T, typename DescendantT> -class HasDescendantMatcher : public MatcherInterface<T> { +class HasDescendantMatcher : public WrapperMatcherInterface<T> { static_assert(IsBaseType<DescendantT>::value, "has descendant only accepts base type matcher"); public: explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher) - : DescendantMatcher(DescendantMatcher) {} + : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesDescendantOf( - Node, DescendantMatcher, Builder, ASTMatchFinder::BK_First); + return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder, + ASTMatchFinder::BK_First); } - - private: - const Matcher<DescendantT> DescendantMatcher; }; /// \brief Matches nodes of type \c T that have a parent node of type \c ParentT @@ -1367,22 +1235,19 @@ public: /// /// \c ParentT must be an AST base type. template <typename T, typename ParentT> -class HasParentMatcher : public MatcherInterface<T> { +class HasParentMatcher : public WrapperMatcherInterface<T> { static_assert(IsBaseType<ParentT>::value, "has parent only accepts base type matcher"); public: explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher) - : ParentMatcher(ParentMatcher) {} + : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesAncestorOf( - Node, ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly); + return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder, + ASTMatchFinder::AMM_ParentOnly); } - - private: - const Matcher<ParentT> ParentMatcher; }; /// \brief Matches nodes of type \c T that have at least one ancestor node of @@ -1390,22 +1255,19 @@ public: /// /// \c AncestorT must be an AST base type. template <typename T, typename AncestorT> -class HasAncestorMatcher : public MatcherInterface<T> { +class HasAncestorMatcher : public WrapperMatcherInterface<T> { static_assert(IsBaseType<AncestorT>::value, "has ancestor only accepts base type matcher"); public: explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher) - : AncestorMatcher(AncestorMatcher) {} + : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesAncestorOf( - Node, AncestorMatcher, Builder, ASTMatchFinder::AMM_All); + return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder, + ASTMatchFinder::AMM_All); } - - private: - const Matcher<AncestorT> AncestorMatcher; }; /// \brief Matches nodes of type T that have at least one descendant node of @@ -1415,23 +1277,20 @@ public: /// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match /// for each descendant node that matches instead of only for the first. template <typename T, typename DescendantT> -class ForEachDescendantMatcher : public MatcherInterface<T> { +class ForEachDescendantMatcher : public WrapperMatcherInterface<T> { static_assert(IsBaseType<DescendantT>::value, "for each descendant only accepts base type matcher"); - public: +public: explicit ForEachDescendantMatcher( - const Matcher<DescendantT>& DescendantMatcher) - : DescendantMatcher(DescendantMatcher) {} + const Matcher<DescendantT> &DescendantMatcher) + : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {} - bool matches(const T& Node, ASTMatchFinder* Finder, - BoundNodesTreeBuilder* Builder) const override { - return Finder->matchesDescendantOf(Node, DescendantMatcher, Builder, + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const override { + return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder, ASTMatchFinder::BK_All); } - -private: - const Matcher<DescendantT> DescendantMatcher; }; /// \brief Matches on nodes that have a getValue() method if getValue() equals @@ -1456,6 +1315,32 @@ private: const ValueT ExpectedValue; }; +/// \brief Template specializations to easily write matchers for floating point +/// literals. +template <> +inline bool ValueEqualsMatcher<FloatingLiteral, double>::matchesNode( + const FloatingLiteral &Node) const { + if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle) + return Node.getValue().convertToFloat() == ExpectedValue; + if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble) + return Node.getValue().convertToDouble() == ExpectedValue; + return false; +} +template <> +inline bool ValueEqualsMatcher<FloatingLiteral, float>::matchesNode( + const FloatingLiteral &Node) const { + if ((&Node.getSemantics()) == &llvm::APFloat::IEEEsingle) + return Node.getValue().convertToFloat() == ExpectedValue; + if ((&Node.getSemantics()) == &llvm::APFloat::IEEEdouble) + return Node.getValue().convertToDouble() == ExpectedValue; + return false; +} +template <> +inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode( + const FloatingLiteral &Node) const { + return ExpectedValue.compare(Node.getValue()) == llvm::APFloat::cmpEqual; +} + /// \brief A VariadicDynCastAllOfMatcher<SourceT, TargetT> object is a /// variadic functor that takes a number of Matcher<TargetT> and returns a /// Matcher<SourceT> that matches TargetT nodes that are matched by all of the @@ -1498,66 +1383,64 @@ public: /// \brief Matches nodes of type \c TLoc for which the inner /// \c Matcher<T> matches. template <typename TLoc, typename T> -class LocMatcher : public MatcherInterface<TLoc> { +class LocMatcher : public WrapperMatcherInterface<TLoc> { public: explicit LocMatcher(const Matcher<T> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} + : LocMatcher::WrapperMatcherInterface(InnerMatcher) {} bool matches(const TLoc &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { if (!Node) return false; - return InnerMatcher.matches(*extract(Node), Finder, Builder); + return this->InnerMatcher.matches(extract(Node), Finder, Builder); } private: - const NestedNameSpecifier *extract(const NestedNameSpecifierLoc &Loc) const { - return Loc.getNestedNameSpecifier(); + static ast_type_traits::DynTypedNode + extract(const NestedNameSpecifierLoc &Loc) { + return ast_type_traits::DynTypedNode::create(*Loc.getNestedNameSpecifier()); } - - const Matcher<T> InnerMatcher; }; /// \brief Matches \c TypeLocs based on an inner matcher matching a certain /// \c QualType. /// /// Used to implement the \c loc() matcher. -class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> { +class TypeLocTypeMatcher : public WrapperMatcherInterface<TypeLoc> { public: explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher) - : InnerMatcher(InnerMatcher) {} + : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {} bool matches(const TypeLoc &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { if (!Node) return false; - return InnerMatcher.matches(Node.getType(), Finder, Builder); + return this->InnerMatcher.matches( + ast_type_traits::DynTypedNode::create(Node.getType()), Finder, Builder); } - -private: - const Matcher<QualType> InnerMatcher; }; /// \brief Matches nodes of type \c T for which the inner matcher matches on a /// another node of type \c T that can be reached using a given traverse /// function. template <typename T> -class TypeTraverseMatcher : public MatcherInterface<T> { +class TypeTraverseMatcher : public WrapperMatcherInterface<T> { public: explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher, QualType (T::*TraverseFunction)() const) - : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} + : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher), + TraverseFunction(TraverseFunction) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { QualType NextNode = (Node.*TraverseFunction)(); if (NextNode.isNull()) return false; - return InnerMatcher.matches(NextNode, Finder, Builder); + return this->InnerMatcher.matches( + ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder); } private: - const Matcher<QualType> InnerMatcher; QualType (T::*TraverseFunction)() const; }; @@ -1565,22 +1448,23 @@ private: /// matcher matches on a another node of type \c T that can be reached using a /// given traverse function. template <typename T> -class TypeLocTraverseMatcher : public MatcherInterface<T> { +class TypeLocTraverseMatcher : public WrapperMatcherInterface<T> { public: explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher, TypeLoc (T::*TraverseFunction)() const) - : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} + : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher), + TraverseFunction(TraverseFunction) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { TypeLoc NextNode = (Node.*TraverseFunction)(); if (!NextNode) return false; - return InnerMatcher.matches(NextNode, Finder, Builder); + return this->InnerMatcher.matches( + ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder); } private: - const Matcher<TypeLoc> InnerMatcher; TypeLoc (T::*TraverseFunction)() const; }; diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h index b7888be..e8eab86 100644 --- a/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -37,7 +37,7 @@ #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H -/// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { +/// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... } /// defines a zero parameter function named DefineMatcher() that returns a /// ReturnType object. #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \ @@ -48,7 +48,7 @@ } \ inline ReturnType DefineMatcher##_getInstance() -/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { +/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { ... } /// defines a single-parameter function named DefineMatcher() that returns a /// ReturnType object. /// @@ -193,15 +193,8 @@ /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to /// extract the TypeList object. -#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \ - void(internal::TypeList<t1, t2>) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \ - void(internal::TypeList<t1, t2, t3>) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \ - void(internal::TypeList<t1, t2, t3, t4>) -#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \ - void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >) +#define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \ + void(internal::TypeList<__VA_ARGS__>) /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } /// defines a single-parameter function named DefineMatcher() that is diff --git a/include/clang/ASTMatchers/Dynamic/Parser.h b/include/clang/ASTMatchers/Dynamic/Parser.h index bd006b6..cdc259e 100644 --- a/include/clang/ASTMatchers/Dynamic/Parser.h +++ b/include/clang/ASTMatchers/Dynamic/Parser.h @@ -123,7 +123,7 @@ public: /// tokens. class RegistrySema : public Parser::Sema { public: - virtual ~RegistrySema(); + ~RegistrySema() override; llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName) override; diff --git a/include/clang/ASTMatchers/Dynamic/Registry.h b/include/clang/ASTMatchers/Dynamic/Registry.h index ad24a8d..fc1e783 100644 --- a/include/clang/ASTMatchers/Dynamic/Registry.h +++ b/include/clang/ASTMatchers/Dynamic/Registry.h @@ -123,7 +123,7 @@ public: Diagnostics *Error); private: - Registry() LLVM_DELETED_FUNCTION; + Registry() = delete; }; } // namespace dynamic diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h index a9bd3d5..78aa9dc 100644 --- a/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -111,7 +111,7 @@ class VariantMatcher { ArrayRef<VariantMatcher> InnerMatchers) const; protected: - ~MatcherOps() {} + ~MatcherOps() = default; private: ast_type_traits::ASTNodeKind NodeKind; @@ -122,7 +122,7 @@ class VariantMatcher { /// It follows a similar interface as VariantMatcher itself. class Payload : public RefCountedBaseVPTR { public: - virtual ~Payload(); + ~Payload() override; virtual llvm::Optional<DynTypedMatcher> getSingleMatcher() const = 0; virtual std::string getTypeAsString() const = 0; virtual llvm::Optional<DynTypedMatcher> @@ -258,7 +258,7 @@ public: VariantValue(const VariantMatcher &Matchers); /// \brief Returns true iff this is not an empty value. - LLVM_EXPLICIT operator bool() const { return hasValue(); } + explicit operator bool() const { return hasValue(); } bool hasValue() const { return Type != VT_Nothing; } /// \brief Unsigned value functions. diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h index fcef0fc..4524aeb 100644 --- a/include/clang/Analysis/Analyses/Dominators.h +++ b/include/clang/Analysis/Analyses/Dominators.h @@ -44,9 +44,7 @@ public: DT = new llvm::DominatorTreeBase<CFGBlock>(false); } - ~DominatorTree() { - delete DT; - } + ~DominatorTree() override { delete DT; } llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; } diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h index 174cce4..2e8058da 100644 --- a/include/clang/Analysis/Analyses/FormatString.h +++ b/include/clang/Analysis/Analyses/FormatString.h @@ -49,7 +49,7 @@ public: const char *toString() const { return representation; } // Overloaded operators for bool like qualities - LLVM_EXPLICIT operator bool() const { return flag; } + explicit operator bool() const { return flag; } OptionalFlag& operator=(const bool &rhs) { flag = rhs; return *this; // Return a reference to myself. @@ -161,6 +161,12 @@ public: ObjCObjArg, // '@' ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg, + // FreeBSD kernel specific specifiers. + FreeBSDbArg, + FreeBSDDArg, + FreeBSDrArg, + FreeBSDyArg, + // GlibC specific specifiers. PrintErrno, // 'm' @@ -204,7 +210,8 @@ public: return EndScanList ? EndScanList - Position : 1; } - bool isIntArg() const { return kind >= IntArgBeg && kind <= IntArgEnd; } + bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) || + kind == FreeBSDrArg || kind == FreeBSDyArg; } bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } const char *toString() const; @@ -224,6 +231,9 @@ class ArgType { public: enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy, AnyCharTy, CStrTy, WCStrTy, WIntTy }; + + enum MatchKind { NoMatch = 0, Match = 1, NoMatchPedantic }; + private: const Kind K; QualType T; @@ -247,7 +257,7 @@ public: return Res; } - bool matchesType(ASTContext &C, QualType argTy) const; + MatchKind matchesType(ASTContext &C, QualType argTy) const; QualType getRepresentativeType(ASTContext &C) const; @@ -646,10 +656,10 @@ public: bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, - const TargetInfo &Target); - -bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, - const TargetInfo &Target); + const TargetInfo &Target, bool isFreeBSDKPrintf); + +bool ParseFormatStringHasSArg(const char *beg, const char *end, + const LangOptions &LO, const TargetInfo &Target); bool ParseScanfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h index c29dd40..e17f73a6 100644 --- a/include/clang/Analysis/Analyses/LiveVariables.h +++ b/include/clang/Analysis/Analyses/LiveVariables.h @@ -44,8 +44,6 @@ public: llvm::ImmutableSet<const VarDecl *> LiveDecls) : liveStmts(LiveStmts), liveDecls(LiveDecls) {} - ~LivenessValues() {} - bool isLive(const Stmt *S) const; bool isLive(const VarDecl *D) const; @@ -66,11 +64,10 @@ public: /// Called when the live variables analysis registers /// that a variable is killed. virtual void observerKill(const DeclRefExpr *DR) {} - }; + }; + ~LiveVariables() override; - virtual ~LiveVariables(); - /// Compute the liveness information for a given CFG. static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext, bool killAtAssign); diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h index 458bb57..22694a7 100644 --- a/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/include/clang/Analysis/Analyses/ThreadSafety.h @@ -26,6 +26,8 @@ namespace clang { namespace threadSafety { +class BeforeSet; + /// This enum distinguishes between different kinds of operations that may /// need to be protected by locks. We use this enum in error handling. enum ProtectedOperationKind { @@ -183,6 +185,14 @@ public: virtual void handleFunExcludesLock(StringRef Kind, Name FunName, Name LockName, SourceLocation Loc) {} + + /// Warn that L1 cannot be acquired before L2. + virtual void handleLockAcquiredBefore(StringRef Kind, Name L1Name, + Name L2Name, SourceLocation Loc) {} + + /// Warn that there is a cycle in acquired_before/after dependencies. + virtual void handleBeforeAfterCycle(Name L1Name, SourceLocation Loc) {} + /// Called by the analysis when starting analysis of a function. /// Used to issue suggestions for changes to annotations. virtual void enterFunction(const FunctionDecl *FD) {} @@ -203,7 +213,10 @@ private: /// at the end of each block, and issue warnings for thread safety violations. /// Each block in the CFG is traversed exactly once. void runThreadSafetyAnalysis(AnalysisDeclContext &AC, - ThreadSafetyHandler &Handler); + ThreadSafetyHandler &Handler, + BeforeSet **Bset); + +void threadSafetyCleanup(BeforeSet *Cache); /// \brief Helper function that returns a LockKind required for the given level /// of access. diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index be81121..9b7725a 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -286,6 +286,14 @@ public: sx::partiallyMatches(CapExpr, other.CapExpr); } + const ValueDecl* valueDecl() const { + if (Negated) + return nullptr; + if (auto *P = dyn_cast<til::Project>(CapExpr)) + return P->clangDecl(); + return nullptr; + } + std::string toString() const { if (Negated) return "!" + sx::toString(CapExpr); @@ -422,8 +430,8 @@ private: } private: - BlockInfo(const BlockInfo &) LLVM_DELETED_FUNCTION; - void operator=(const BlockInfo &) LLVM_DELETED_FUNCTION; + BlockInfo(const BlockInfo &) = delete; + void operator=(const BlockInfo &) = delete; }; // We implement the CFGVisitor API diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h index 2cd8c6d..4b59466 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h @@ -282,7 +282,7 @@ public: /// SExpr objects cannot be deleted. // This declaration is public to workaround a gcc bug that breaks building // with REQUIRES_EH=1. - void operator delete(void *) LLVM_DELETED_FUNCTION; + void operator delete(void *) = delete; /// Returns the instruction ID for this expression. /// All basic block instructions have a unique ID (i.e. virtual register). @@ -309,10 +309,10 @@ protected: BasicBlock* Block; private: - SExpr() LLVM_DELETED_FUNCTION; + SExpr() = delete; /// SExpr objects must be created in an arena. - void *operator new(size_t) LLVM_DELETED_FUNCTION; + void *operator new(size_t) = delete; }; @@ -424,7 +424,7 @@ public: Future() : SExpr(COP_Future), Status(FS_pending), Result(nullptr) {} private: - virtual ~Future() LLVM_DELETED_FUNCTION; + virtual ~Future() = delete; public: // A lazy rewriting strategy should subclass Future and override this method. diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index ba3e0e5..4d3402f 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -130,6 +130,8 @@ public: typedef T *iterator; typedef const T *const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; size_t size() const { return Size; } size_t capacity() const { return Capacity; } @@ -160,6 +162,16 @@ public: const_iterator cbegin() const { return Data; } const_iterator cend() const { return Data + Size; } + reverse_iterator rbegin() { return reverse_iterator(end()); } + reverse_iterator rend() { return reverse_iterator(begin()); } + + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + void push_back(const T &Elem) { assert(Size < Capacity); Data[Size++] = Elem; @@ -188,36 +200,12 @@ public: return J - Osz; } - // An adaptor to reverse a simple array - class ReverseAdaptor { - public: - ReverseAdaptor(SimpleArray &Array) : Array(Array) {} - // A reverse iterator used by the reverse adaptor - class Iterator { - public: - Iterator(T *Data) : Data(Data) {} - T &operator*() { return *Data; } - const T &operator*() const { return *Data; } - Iterator &operator++() { - --Data; - return *this; - } - bool operator!=(Iterator Other) { return Data != Other.Data; } - - private: - T *Data; - }; - Iterator begin() { return Array.end() - 1; } - Iterator end() { return Array.begin() - 1; } - const Iterator begin() const { return Array.end() - 1; } - const Iterator end() const { return Array.begin() - 1; } - - private: - SimpleArray &Array; - }; - - const ReverseAdaptor reverse() const { return ReverseAdaptor(*this); } - ReverseAdaptor reverse() { return ReverseAdaptor(*this); } + llvm::iterator_range<reverse_iterator> reverse() { + return llvm::make_range(rbegin(), rend()); + } + llvm::iterator_range<const_reverse_iterator> reverse() const { + return llvm::make_range(rbegin(), rend()); + } private: // std::max is annoying here, because it requires a reference, @@ -226,7 +214,7 @@ private: static const size_t InitialCapacity = 4; - SimpleArray(const SimpleArray<T> &A) LLVM_DELETED_FUNCTION; + SimpleArray(const SimpleArray<T> &A) = delete; T *Data; size_t Size; @@ -255,8 +243,8 @@ class CopyOnWriteVector { }; // No copy constructor or copy assignment. Use clone() with move assignment. - CopyOnWriteVector(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION; - void operator=(const CopyOnWriteVector &V) LLVM_DELETED_FUNCTION; + CopyOnWriteVector(const CopyOnWriteVector &V) = delete; + void operator=(const CopyOnWriteVector &V) = delete; public: CopyOnWriteVector() : Data(nullptr) {} diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 0ebdf15..931190e 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -173,8 +173,8 @@ public: typedef const VarDecl * const * referenced_decls_iterator; - std::pair<referenced_decls_iterator, referenced_decls_iterator> - getReferencedBlockVars(const BlockDecl *BD); + llvm::iterator_range<referenced_decls_iterator> + getReferencedBlockVars(const BlockDecl *BD); /// Return the ImplicitParamDecl* associated with 'self' if this /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise. @@ -289,7 +289,7 @@ class StackFrameContext : public LocationContext { Block(blk), Index(idx) {} public: - ~StackFrameContext() {} + ~StackFrameContext() override {} const Stmt *getCallSite() const { return CallSite; } @@ -324,7 +324,7 @@ class ScopeContext : public LocationContext { : LocationContext(Scope, ctx, parent), Enter(s) {} public: - ~ScopeContext() {} + ~ScopeContext() override {} void Profile(llvm::FoldingSetNodeID &ID) override; @@ -352,7 +352,7 @@ class BlockInvocationContext : public LocationContext { : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {} public: - ~BlockInvocationContext() {} + ~BlockInvocationContext() override {} const BlockDecl *getBlockDecl() const { return BD; } diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h index beea867..e7f63836 100644 --- a/include/clang/Analysis/CFG.h +++ b/include/clang/Analysis/CFG.h @@ -322,7 +322,7 @@ public: Stmt &operator*() { return *getStmt(); } const Stmt &operator*() const { return *getStmt(); } - LLVM_EXPLICIT operator bool() const { return getStmt(); } + explicit operator bool() const { return getStmt(); } }; /// CFGBlock - Represents a single basic block in a source-level CFG. @@ -493,7 +493,6 @@ public: : Elements(C), Label(nullptr), Terminator(nullptr), LoopTarget(nullptr), BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false), Parent(parent) {} - ~CFGBlock() {} // Statement iterators typedef ElementList::iterator iterator; diff --git a/include/clang/Basic/ABI.h b/include/clang/Basic/ABI.h index bd24679..75e9faf 100644 --- a/include/clang/Basic/ABI.h +++ b/include/clang/Basic/ABI.h @@ -17,14 +17,17 @@ #define LLVM_CLANG_BASIC_ABI_H #include "llvm/Support/DataTypes.h" +#include <cstring> namespace clang { /// \brief C++ constructor types. enum CXXCtorType { - Ctor_Complete, ///< Complete object ctor - Ctor_Base, ///< Base object ctor - Ctor_Comdat ///< The COMDAT used for ctors + Ctor_Complete, ///< Complete object ctor + Ctor_Base, ///< Base object ctor + Ctor_Comdat, ///< The COMDAT used for ctors + Ctor_CopyingClosure, ///< Copying closure variant of a ctor + Ctor_DefaultClosure, ///< Default closure variant of a ctor }; /// \brief C++ destructor types. diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 3ed7f8d..c310d25 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -144,6 +144,7 @@ class TypeArgument<string name, bit opt = 0> : Argument<name, opt>; class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>; class VariadicUnsignedArgument<string name> : Argument<name, 1>; class VariadicExprArgument<string name> : Argument<name, 1>; +class VariadicStringArgument<string name> : Argument<name, 1>; // A version of the form major.minor[.subminor]. class VersionArgument<string name, bit opt = 0> : Argument<name, opt>; @@ -224,12 +225,14 @@ class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag, string CustomDiag = customDiag; } -class LangOpt<string name> { +class LangOpt<string name, bit negated = 0> { string Name = name; + bit Negated = negated; } def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; +def COnly : LangOpt<"CPlusPlus", 1>; // Defines targets for target-specific attributes. The list of strings should // specify architectures for which the target applies, based off the ArchType @@ -343,6 +346,8 @@ def AddressSpace : TypeAttr { def Alias : Attr { let Spellings = [GCC<"alias">]; let Args = [StringArgument<"Aliasee">]; + let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag, + "ExpectedFunctionGlobalVarMethodOrProperty">; let Documentation = [Undocumented]; } @@ -436,8 +441,11 @@ def Availability : InheritableAttr { let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch<llvm::StringRef>(Platform) + .Case("android", "Android") .Case("ios", "iOS") .Case("macosx", "OS X") + .Case("ios_app_extension", "iOS (App Extension)") + .Case("macosx_app_extension", "OS X (App Extension)") .Default(llvm::StringRef()); } }]; let HasCustomParsing = 1; @@ -574,7 +582,7 @@ def CUDAInvalidTarget : InheritableAttr { def CUDALaunchBounds : InheritableAttr { let Spellings = [GNU<"launch_bounds">]; - let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>]; + let Args = [ExprArgument<"MaxThreads">, ExprArgument<"MinBlocks", 1>]; let LangOpts = [CUDA]; let Subjects = SubjectList<[ObjCMethod, FunctionLike], WarnDiag, "ExpectedFunctionOrMethod">; @@ -707,6 +715,25 @@ def MinSize : InheritableAttr { let Documentation = [Undocumented]; } +def FlagEnum : InheritableAttr { + let Spellings = [GNU<"flag_enum">]; + let Subjects = SubjectList<[Enum]>; + let Documentation = [FlagEnumDocs]; + let LangOpts = [COnly]; + let AdditionalMembers = [{ +private: + llvm::APInt FlagBits; +public: + llvm::APInt &getFlagBits() { + return FlagBits; + } + + const llvm::APInt &getFlagBits() const { + return FlagBits; + } +}]; +} + def Flatten : InheritableAttr { let Spellings = [GCC<"flatten">]; let Subjects = SubjectList<[Function], ErrorDiag>; @@ -767,9 +794,9 @@ def IBOutletCollection : InheritableAttr { let Documentation = [Undocumented]; } -def Malloc : InheritableAttr { - let Spellings = [GCC<"malloc">]; -// let Subjects = [Function]; +def Restrict : InheritableAttr { + let Spellings = [Declspec<"restrict">, GCC<"malloc">]; + let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } @@ -958,7 +985,8 @@ def NoThrow : InheritableAttr { def ObjCBridge : InheritableAttr { let Spellings = [GNU<"objc_bridge">]; - let Subjects = SubjectList<[Record], ErrorDiag>; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, + "ExpectedStructOrUnionOrTypedef">; let Args = [IdentifierArgument<"BridgedType">]; let Documentation = [Undocumented]; } @@ -1031,6 +1059,11 @@ def ObjCNSObject : InheritableAttr { let Documentation = [Undocumented]; } +def ObjCIndependentClass : InheritableAttr { + let Spellings = [GNU<"objc_independent_class">]; + let Documentation = [Undocumented]; +} + def ObjCPreciseLifetime : InheritableAttr { let Spellings = [GNU<"objc_precise_lifetime">]; let Subjects = SubjectList<[Var], ErrorDiag>; @@ -1118,12 +1151,6 @@ def Packed : InheritableAttr { let Documentation = [Undocumented]; } -def PnaclCall : InheritableAttr { - let Spellings = [GNU<"pnaclcall">]; -// let Subjects = [Function, ObjCMethod]; - let Documentation = [Undocumented]; -} - def IntelOclBicc : InheritableAttr { let Spellings = [GNU<"intel_ocl_bicc">]; // let Subjects = [Function, ObjCMethod]; @@ -1360,26 +1387,35 @@ def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> { let Documentation = [Undocumented]; } -// Attribute to disable AddressSanitizer (or equivalent) checks. -def NoSanitizeAddress : InheritableAttr { - let Spellings = [GCC<"no_address_safety_analysis">, - GCC<"no_sanitize_address">]; - let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [NoSanitizeAddressDocs]; -} - -// Attribute to disable ThreadSanitizer checks. -def NoSanitizeThread : InheritableAttr { - let Spellings = [GNU<"no_sanitize_thread">]; - let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [NoSanitizeThreadDocs]; +def NoSanitize : InheritableAttr { + let Spellings = [GNU<"no_sanitize">, CXX11<"clang", "no_sanitize">]; + let Args = [VariadicStringArgument<"Sanitizers">]; + let Subjects = SubjectList<[Function, ObjCMethod], ErrorDiag>; + let Documentation = [NoSanitizeDocs]; + let AdditionalMembers = [{ + SanitizerMask getMask() const { + SanitizerMask Mask = 0; + for (auto SanitizerName : sanitizers()) { + SanitizerMask ParsedMask = + parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); + Mask |= expandSanitizerGroups(ParsedMask); + } + return Mask; + } + }]; } -// Attribute to disable MemorySanitizer checks. -def NoSanitizeMemory : InheritableAttr { - let Spellings = [GNU<"no_sanitize_memory">]; +// Attributes to disable a specific sanitizer. No new sanitizers should be added +// to this list; the no_sanitize attribute should be extended instead. +def NoSanitizeSpecific : InheritableAttr { + let Spellings = [GCC<"no_address_safety_analysis">, + GCC<"no_sanitize_address">, + GCC<"no_sanitize_thread">, + GNU<"no_sanitize_memory">]; let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [NoSanitizeMemoryDocs]; + let Documentation = [NoSanitizeAddressDocs, NoSanitizeThreadDocs, + NoSanitizeMemoryDocs]; + let ASTNode = 0; } // C/C++ Thread safety attributes (e.g. for deadlock, data race checking) @@ -1743,11 +1779,17 @@ def TypeTagForDatatype : InheritableAttr { // Microsoft-related attributes -def MsProperty : IgnoredAttr { +def MSNoVTable : InheritableAttr { + let Spellings = [Declspec<"novtable">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [MSNoVTableDocs]; +} + +def : IgnoredAttr { let Spellings = [Declspec<"property">]; } -def MsStruct : InheritableAttr { +def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 530c6e7..9314c44 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -920,6 +920,22 @@ This attribute accepts a single parameter that must be one of the following: }]; } +def NoSanitizeDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use the ``no_sanitize`` attribute on a function declaration to specify +that a particular instrumentation or set of instrumentations should not be +applied to that function. The attribute takes a list of string literals, +which have the same meaning as values accepted by the ``-fno-sanitize=`` +flag. For example, ``__attribute__((no_sanitize("address", "thread")))`` +specifies that AddressSanitizer and ThreadSanitizer should not be applied +to the function. + +See :ref:`Controlling Code Generation <controlling-code-generation>` for a +full list of supported sanitizer flags. + }]; +} + def NoSanitizeAddressDocs : Documentation { let Category = DocCatFunction; // This function has multiple distinct spellings, and so it requires a custom @@ -936,6 +952,7 @@ not be applied to that function. def NoSanitizeThreadDocs : Documentation { let Category = DocCatFunction; + let Heading = "no_sanitize_thread"; let Content = [{ .. _langext-thread_sanitizer: @@ -948,6 +965,7 @@ tool to avoid false positives and provide meaningful stack traces. def NoSanitizeMemoryDocs : Documentation { let Category = DocCatFunction; + let Heading = "no_sanitize_memory"; let Content = [{ .. _langext-memory_sanitizer: @@ -1196,6 +1214,16 @@ behavior of the program is undefined. }]; } +def FlagEnumDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute can be added to an enumerator to signal to the compiler that it +is intended to be used as a flag type. This will cause the compiler to assume +that the range of the type includes all of the values that you can get by +manipulating bits of the enumerator when issuing warnings. + }]; +} + def MSInheritanceDocs : Documentation { let Category = DocCatType; let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance"; @@ -1243,6 +1271,15 @@ an error: }]; } +def MSNoVTableDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute can be added to a class declaration or definition to signal to +the compiler that constructors and destructors will not reference the virtual +function table. + }]; +} + def OptnoneDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 098f5da..1927907 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -56,7 +56,8 @@ // I -> Required to constant fold to an integer constant expression. // // Types may be postfixed with the following modifiers: -// * -> pointer (optionally followed by an address space number) +// * -> pointer (optionally followed by an address space number, if no address +// space is specified than any address space will be accepted) // & -> reference (optionally followed by an address space number) // C -> const // D -> volatile @@ -692,19 +693,29 @@ BUILTIN(__builtin_index, "c*cC*i", "Fn") BUILTIN(__builtin_rindex, "c*cC*i", "Fn") // Microsoft builtins. These are only active with -fms-extensions. -LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) +LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__assume, "vb", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__debugbreak, "v", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__exception_code, "ULi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_exception_code, "ULi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__exception_info, "v*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_exception_info, "v*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__abnormal_termination, "i", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_abnormal_termination, "i", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__GetExceptionInfo, "v*.", "ntu", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchange, "LiLiD*LiLi", "n", ALL_MS_LANGUAGES) LANGBUILTIN(_InterlockedCompareExchangePointer, "v*v*D*v*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES) -LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedDecrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangeAdd, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchange, "LiLiD*Li", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedExchangePointer, "v*v*D*v*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(_InterlockedIncrement, "LiLiD*", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__noop, "i.", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__readfsdword, "ULiULi", "n", ALL_MS_LANGUAGES) +LANGBUILTIN(__va_start, "vc**.", "nt", ALL_MS_LANGUAGES) + +// Microsoft library builtins. +LIBBUILTIN(_setjmpex, "iJ", "fj", "setjmpex.h", ALL_MS_LANGUAGES) // C99 library functions // C99 stdlib.h diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index 3ce2255..27428ad 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -143,6 +143,12 @@ public: return strchr(GetRecord(ID).Attributes, 't') != nullptr; } + /// \brief Determines whether this builtin has a result or any arguments which + /// are pointer types. + bool hasPtrArgsOrResult(unsigned ID) const { + return strchr(GetRecord(ID).Type, '*') != nullptr; + } + /// \brief Completely forget that the given ID was ever considered a builtin, /// e.g., because the user provided a conflicting signature. void ForgetBuiltin(unsigned ID, IdentifierTable &Table); diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index 9091ad4..98d5ab7 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -96,7 +96,7 @@ LANGBUILTIN(__sevl, "v", "", ALL_MS_LANGUAGES) LANGBUILTIN(__dmb, "vUi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__dsb, "vUi", "nc", ALL_MS_LANGUAGES) LANGBUILTIN(__isb, "vUi", "nc", ALL_MS_LANGUAGES) -LANGBUILTIN(__ldrexd, "WiCDWi*", "", ALL_MS_LANGUAGES) +LANGBUILTIN(__ldrexd, "WiWiCD*", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveFromCoprocessor, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveFromCoprocessor2, "UiUiUiUiUiUi", "", ALL_MS_LANGUAGES) LANGBUILTIN(_MoveToCoprocessor, "vUiUiUiUiUiUi", "", ALL_MS_LANGUAGES) diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def index e42af42..57ae63e 100644 --- a/include/clang/Basic/BuiltinsPPC.def +++ b/include/clang/Basic/BuiltinsPPC.def @@ -26,6 +26,9 @@ BUILTIN(__builtin_altivec_vaddshs, "V8SsV8SsV8Ss", "") BUILTIN(__builtin_altivec_vadduhs, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_vaddsws, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vadduws, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vaddeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vaddcuq, "V1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vaddecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vsubsbs, "V16ScV16ScV16Sc", "") BUILTIN(__builtin_altivec_vsububs, "V16UcV16UcV16Uc", "") @@ -33,6 +36,9 @@ BUILTIN(__builtin_altivec_vsubshs, "V8SsV8SsV8Ss", "") BUILTIN(__builtin_altivec_vsubuhs, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_vsubsws, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vsubuws, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vsubeuqm, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vsubcuq, "V1ULLLiV1ULLLiV1ULLLi","") +BUILTIN(__builtin_altivec_vsubecuq, "V1ULLLiV1ULLLiV1ULLLiV1ULLLi","") BUILTIN(__builtin_altivec_vavgsb, "V16ScV16ScV16Sc", "") BUILTIN(__builtin_altivec_vavgub, "V16UcV16UcV16Uc", "") @@ -85,10 +91,14 @@ BUILTIN(__builtin_altivec_vmuleub, "V8UsV16UcV16Uc", "") BUILTIN(__builtin_altivec_vmulesb, "V8SsV16ScV16Sc", "") BUILTIN(__builtin_altivec_vmuleuh, "V4UiV8UsV8Us", "") BUILTIN(__builtin_altivec_vmulesh, "V4SiV8SsV8Ss", "") +BUILTIN(__builtin_altivec_vmuleuw, "V2ULLiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vmulesw, "V2SLLiV4SiV4Si", "") BUILTIN(__builtin_altivec_vmuloub, "V8UsV16UcV16Uc", "") BUILTIN(__builtin_altivec_vmulosb, "V8SsV16ScV16Sc", "") BUILTIN(__builtin_altivec_vmulouh, "V4UiV8UsV8Us", "") BUILTIN(__builtin_altivec_vmulosh, "V4SiV8SsV8Ss", "") +BUILTIN(__builtin_altivec_vmulouw, "V2ULLiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vmulosw, "V2SLLiV4SiV4Si", "") BUILTIN(__builtin_altivec_vnmsubfp, "V4fV4fV4fV4f", "") @@ -99,6 +109,10 @@ BUILTIN(__builtin_altivec_vpkuwus, "V8UsV4UiV4Ui", "") BUILTIN(__builtin_altivec_vpkswss, "V8SsV4SiV4Si", "") BUILTIN(__builtin_altivec_vpkshus, "V16UcV8SsV8Ss", "") BUILTIN(__builtin_altivec_vpkswus, "V8UsV4SiV4Si", "") +BUILTIN(__builtin_altivec_vpksdss, "V4SiV2SLLiV2SLLi", "") +BUILTIN(__builtin_altivec_vpksdus, "V4UiV2SLLiV2SLLi", "") +BUILTIN(__builtin_altivec_vpkudus, "V4UiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vpkudum, "V4UiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vperm_4si, "V4iV4iV4iV16Uc", "") @@ -115,6 +129,7 @@ BUILTIN(__builtin_altivec_vcmpgefp, "V4iV4fV4f", "") BUILTIN(__builtin_altivec_vcmpequb, "V16cV16cV16c", "") BUILTIN(__builtin_altivec_vcmpequh, "V8sV8sV8s", "") BUILTIN(__builtin_altivec_vcmpequw, "V4iV4iV4i", "") +BUILTIN(__builtin_altivec_vcmpequd, "V2LLiV2LLiV2LLi", "") BUILTIN(__builtin_altivec_vcmpeqfp, "V4iV4fV4f", "") BUILTIN(__builtin_altivec_vcmpgtsb, "V16cV16ScV16Sc", "") @@ -123,6 +138,8 @@ BUILTIN(__builtin_altivec_vcmpgtsh, "V8sV8SsV8Ss", "") BUILTIN(__builtin_altivec_vcmpgtuh, "V8sV8UsV8Us", "") BUILTIN(__builtin_altivec_vcmpgtsw, "V4iV4SiV4Si", "") BUILTIN(__builtin_altivec_vcmpgtuw, "V4iV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vcmpgtsd, "V2LLiV2LLiV2LLi", "") +BUILTIN(__builtin_altivec_vcmpgtud, "V2LLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vcmpgtfp, "V4iV4fV4f", "") BUILTIN(__builtin_altivec_vmaxsb, "V16ScV16ScV16Sc", "") @@ -131,6 +148,8 @@ BUILTIN(__builtin_altivec_vmaxsh, "V8SsV8SsV8Ss", "") BUILTIN(__builtin_altivec_vmaxuh, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_vmaxsw, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vmaxuw, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vmaxsd, "V2LLiV2LLiV2LLi", "") +BUILTIN(__builtin_altivec_vmaxud, "V2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vmaxfp, "V4fV4fV4f", "") BUILTIN(__builtin_altivec_mfvscr, "V8Us", "") @@ -141,6 +160,8 @@ BUILTIN(__builtin_altivec_vminsh, "V8SsV8SsV8Ss", "") BUILTIN(__builtin_altivec_vminuh, "V8UsV8UsV8Us", "") BUILTIN(__builtin_altivec_vminsw, "V4SiV4SiV4Si", "") BUILTIN(__builtin_altivec_vminuw, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vminsd, "V2LLiV2LLiV2LLi", "") +BUILTIN(__builtin_altivec_vminud, "V2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vminfp, "V4fV4fV4f", "") BUILTIN(__builtin_altivec_mtvscr, "vV4i", "") @@ -150,6 +171,7 @@ BUILTIN(__builtin_altivec_vrefp, "V4fV4f", "") BUILTIN(__builtin_altivec_vrlb, "V16cV16cV16Uc", "") BUILTIN(__builtin_altivec_vrlh, "V8sV8sV8Us", "") BUILTIN(__builtin_altivec_vrlw, "V4iV4iV4Ui", "") +BUILTIN(__builtin_altivec_vrld, "V2LLiV2LLiV2ULLi", "") BUILTIN(__builtin_altivec_vsel_4si, "V4iV4iV4iV4Ui", "") @@ -182,10 +204,12 @@ BUILTIN(__builtin_altivec_vrfiz, "V4fV4f", "") BUILTIN(__builtin_altivec_vupkhsb, "V8sV16c", "") BUILTIN(__builtin_altivec_vupkhpx, "V4UiV8s", "") BUILTIN(__builtin_altivec_vupkhsh, "V4iV8s", "") +BUILTIN(__builtin_altivec_vupkhsw, "V2LLiV4i", "") BUILTIN(__builtin_altivec_vupklsb, "V8sV16c", "") BUILTIN(__builtin_altivec_vupklpx, "V4UiV8s", "") BUILTIN(__builtin_altivec_vupklsh, "V4iV8s", "") +BUILTIN(__builtin_altivec_vupklsw, "V2LLiV4i", "") BUILTIN(__builtin_altivec_vcmpbfp_p, "iiV4fV4f", "") @@ -194,6 +218,7 @@ BUILTIN(__builtin_altivec_vcmpgefp_p, "iiV4fV4f", "") BUILTIN(__builtin_altivec_vcmpequb_p, "iiV16cV16c", "") BUILTIN(__builtin_altivec_vcmpequh_p, "iiV8sV8s", "") BUILTIN(__builtin_altivec_vcmpequw_p, "iiV4iV4i", "") +BUILTIN(__builtin_altivec_vcmpequd_p, "iiV2LLiV2LLi", "") BUILTIN(__builtin_altivec_vcmpeqfp_p, "iiV4fV4f", "") BUILTIN(__builtin_altivec_vcmpgtsb_p, "iiV16ScV16Sc", "") @@ -202,8 +227,24 @@ BUILTIN(__builtin_altivec_vcmpgtsh_p, "iiV8SsV8Ss", "") BUILTIN(__builtin_altivec_vcmpgtuh_p, "iiV8UsV8Us", "") BUILTIN(__builtin_altivec_vcmpgtsw_p, "iiV4SiV4Si", "") BUILTIN(__builtin_altivec_vcmpgtuw_p, "iiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_vcmpgtsd_p, "iiV2LLiV2LLi", "") +BUILTIN(__builtin_altivec_vcmpgtud_p, "iiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vcmpgtfp_p, "iiV4fV4f", "") +// P8 Crypto built-ins. +BUILTIN(__builtin_altivec_crypto_vsbox, "V2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_crypto_vpermxor, "V16UcV16UcV16UcV16Uc", "") +BUILTIN(__builtin_altivec_crypto_vshasigmaw, "V4UiV4UiIiIi", "") +BUILTIN(__builtin_altivec_crypto_vshasigmad, "V2ULLiV2ULLiIiIi", "") +BUILTIN(__builtin_altivec_crypto_vcipher, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_crypto_vcipherlast, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_crypto_vncipher, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_crypto_vncipherlast, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_crypto_vpmsumb, "V16UcV16UcV16Uc", "") +BUILTIN(__builtin_altivec_crypto_vpmsumh, "V8UsV8UsV8Us", "") +BUILTIN(__builtin_altivec_crypto_vpmsumw, "V4UiV4UiV4Ui", "") +BUILTIN(__builtin_altivec_crypto_vpmsumd, "V2ULLiV2ULLiV2ULLi", "") + // VSX built-ins. BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "") @@ -223,6 +264,44 @@ BUILTIN(__builtin_vsx_xsmindp, "ddd", "") BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "") BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "") +// HTM builtins +BUILTIN(__builtin_tbegin, "UiUIi", "") +BUILTIN(__builtin_tend, "UiUIi", "") + +BUILTIN(__builtin_tabort, "UiUi", "") +BUILTIN(__builtin_tabortdc, "UiUiUiUi", "") +BUILTIN(__builtin_tabortdci, "UiUiUii", "") +BUILTIN(__builtin_tabortwc, "UiUiUiUi", "") +BUILTIN(__builtin_tabortwci, "UiUiUii", "") + +BUILTIN(__builtin_tcheck, "Ui", "") +BUILTIN(__builtin_treclaim, "UiUi", "") +BUILTIN(__builtin_trechkpt, "Ui", "") +BUILTIN(__builtin_tsr, "UiUi", "") + +BUILTIN(__builtin_tendall, "Ui", "") +BUILTIN(__builtin_tresume, "Ui", "") +BUILTIN(__builtin_tsuspend, "Ui", "") + +BUILTIN(__builtin_get_texasr, "LUi", "c") +BUILTIN(__builtin_get_texasru, "LUi", "c") +BUILTIN(__builtin_get_tfhar, "LUi", "c") +BUILTIN(__builtin_get_tfiar, "LUi", "c") + +BUILTIN(__builtin_set_texasr, "vLUi", "c") +BUILTIN(__builtin_set_texasru, "vLUi", "c") +BUILTIN(__builtin_set_tfhar, "vLUi", "c") +BUILTIN(__builtin_set_tfiar, "vLUi", "c") + +BUILTIN(__builtin_ttest, "LUi", "") + +// Scalar built-ins +BUILTIN(__builtin_divwe, "SiSiSi", "") +BUILTIN(__builtin_divweu, "UiUiUi", "") +BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "") +BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "") +BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "") + // FIXME: Obviously incomplete. #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def new file mode 100644 index 0000000..68d5a1c --- /dev/null +++ b/include/clang/Basic/BuiltinsSystemZ.def @@ -0,0 +1,252 @@ +//===-- BuiltinsSystemZ.def - SystemZ Builtin function database -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the SystemZ-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// The format of this database matches clang/Basic/Builtins.def. + +// Transactional-memory intrinsics +BUILTIN(__builtin_tbegin, "iv*", "j") +BUILTIN(__builtin_tbegin_nofloat, "iv*", "j") +BUILTIN(__builtin_tbeginc, "v", "nj") +BUILTIN(__builtin_tabort, "vi", "r") +BUILTIN(__builtin_tend, "i", "n") +BUILTIN(__builtin_tx_nesting_depth, "i", "nc") +BUILTIN(__builtin_tx_assist, "vi", "n") +BUILTIN(__builtin_non_tx_store, "vULi*ULi", "") + +// Vector intrinsics. +// These all map directly to z instructions, except that some variants ending +// in "s" have a final "int *" that receives the post-instruction CC value. + +// Vector support instructions (chapter 21 of the PoP) +BUILTIN(__builtin_s390_lcbb, "UivC*Ii", "nc") +BUILTIN(__builtin_s390_vlbb, "V16ScvC*Ii", "") +BUILTIN(__builtin_s390_vll, "V16ScUivC*", "") +BUILTIN(__builtin_s390_vstl, "vV16ScUiv*", "") +BUILTIN(__builtin_s390_vperm, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vpdi, "V2ULLiV2ULLiV2ULLiIi", "nc") +BUILTIN(__builtin_s390_vpksh, "V16ScV8SsV8Ss", "nc") +BUILTIN(__builtin_s390_vpkshs, "V16ScV8SsV8Ssi*", "nc") +BUILTIN(__builtin_s390_vpksf, "V8SsV4SiV4Si", "nc") +BUILTIN(__builtin_s390_vpksfs, "V8SsV4SiV4Sii*", "nc") +BUILTIN(__builtin_s390_vpksg, "V4SiV2SLLiV2SLLi", "nc") +BUILTIN(__builtin_s390_vpksgs, "V4SiV2SLLiV2SLLii*", "nc") +BUILTIN(__builtin_s390_vpklsh, "V16UcV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vpklshs, "V16UcV8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vpklsf, "V8UsV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vpklsfs, "V8UsV4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vpklsg, "V4UiV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vpklsgs, "V4UiV2ULLiV2ULLii*", "nc") +BUILTIN(__builtin_s390_vuphb, "V8SsV16Sc", "nc") +BUILTIN(__builtin_s390_vuphh, "V4SiV8Ss", "nc") +BUILTIN(__builtin_s390_vuphf, "V2SLLiV4Si", "nc") +BUILTIN(__builtin_s390_vuplb, "V8SsV16Sc", "nc") +BUILTIN(__builtin_s390_vuplhw, "V4SiV8Ss", "nc") +BUILTIN(__builtin_s390_vuplf, "V2SLLiV4Si", "nc") +BUILTIN(__builtin_s390_vuplhb, "V8UsV16Uc", "nc") +BUILTIN(__builtin_s390_vuplhh, "V4UiV8Us", "nc") +BUILTIN(__builtin_s390_vuplhf, "V2ULLiV4Ui", "nc") +BUILTIN(__builtin_s390_vupllb, "V8UsV16Uc", "nc") +BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc") +BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc") + +// Vector integer instructions (chapter 22 of the PoP) +BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_s390_vavgg, "V2SLLiV2SLLiV2SLLi", "nc") +BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc") +BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc") +BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc") +BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc") +BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc") +BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc") +BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc") +BUILTIN(__builtin_s390_vchgs, "V2SLLiV2SLLiV2SLLii*", "nc") +BUILTIN(__builtin_s390_vchlbs, "V16ScV16UcV16Uci*", "nc") +BUILTIN(__builtin_s390_vchlhs, "V8SsV8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vchlfs, "V4SiV4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vchlgs, "V2SLLiV2ULLiV2ULLii*", "nc") +BUILTIN(__builtin_s390_vcksm, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vclzb, "V16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vclzh, "V8UsV8Us", "nc") +BUILTIN(__builtin_s390_vclzf, "V4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vclzg, "V2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vctzb, "V16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vctzh, "V8UsV8Us", "nc") +BUILTIN(__builtin_s390_vctzf, "V4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vctzg, "V2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc") +BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc") +BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc") +BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc") +BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc") +BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc") +BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc") +BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc") +BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc") +BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc") +BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc") +BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc") +BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc") +BUILTIN(__builtin_s390_vmalhb, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vmalhh, "V8UsV8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vmalhf, "V4UiV4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vmaeb, "V8SsV16ScV16ScV8Ss", "nc") +BUILTIN(__builtin_s390_vmaeh, "V4SiV8SsV8SsV4Si", "nc") +BUILTIN(__builtin_s390_vmaef, "V2SLLiV4SiV4SiV2SLLi", "nc") +BUILTIN(__builtin_s390_vmaleb, "V8UsV16UcV16UcV8Us", "nc") +BUILTIN(__builtin_s390_vmaleh, "V4UiV8UsV8UsV4Ui", "nc") +BUILTIN(__builtin_s390_vmalef, "V2ULLiV4UiV4UiV2ULLi", "nc") +BUILTIN(__builtin_s390_vmaob, "V8SsV16ScV16ScV8Ss", "nc") +BUILTIN(__builtin_s390_vmaoh, "V4SiV8SsV8SsV4Si", "nc") +BUILTIN(__builtin_s390_vmaof, "V2SLLiV4SiV4SiV2SLLi", "nc") +BUILTIN(__builtin_s390_vmalob, "V8UsV16UcV16UcV8Us", "nc") +BUILTIN(__builtin_s390_vmaloh, "V4UiV8UsV8UsV4Ui", "nc") +BUILTIN(__builtin_s390_vmalof, "V2ULLiV4UiV4UiV2ULLi", "nc") +BUILTIN(__builtin_s390_vmhb, "V16ScV16ScV16Sc", "nc") +BUILTIN(__builtin_s390_vmhh, "V8SsV8SsV8Ss", "nc") +BUILTIN(__builtin_s390_vmhf, "V4SiV4SiV4Si", "nc") +BUILTIN(__builtin_s390_vmlhb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vmlhh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vmlhf, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vmeb, "V8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_s390_vmeh, "V4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_s390_vmef, "V2SLLiV4SiV4Si", "nc") +BUILTIN(__builtin_s390_vmleb, "V8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vmleh, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vmlef, "V2ULLiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vmob, "V8SsV16ScV16Sc", "nc") +BUILTIN(__builtin_s390_vmoh, "V4SiV8SsV8Ss", "nc") +BUILTIN(__builtin_s390_vmof, "V2SLLiV4SiV4Si", "nc") +BUILTIN(__builtin_s390_vmlob, "V8UsV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vmloh, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vmlof, "V2ULLiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc") +BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc") +BUILTIN(__builtin_s390_vsra, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsrab, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsrl, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsrlb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc") +BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc") + +// Vector string instructions (chapter 23 of the PoP) +BUILTIN(__builtin_s390_vfaeb, "V16UcV16UcV16UcIi", "nc") +BUILTIN(__builtin_s390_vfaebs, "V16UcV16UcV16UcIii*", "nc") +BUILTIN(__builtin_s390_vfaeh, "V8UsV8UsV8UsIi", "nc") +BUILTIN(__builtin_s390_vfaehs, "V8UsV8UsV8UsIii*", "nc") +BUILTIN(__builtin_s390_vfaef, "V4UiV4UiV4UiIi", "nc") +BUILTIN(__builtin_s390_vfaefs, "V4UiV4UiV4UiIii*", "nc") +BUILTIN(__builtin_s390_vfaezb, "V16UcV16UcV16UcIi", "nc") +BUILTIN(__builtin_s390_vfaezbs, "V16UcV16UcV16UcIii*", "nc") +BUILTIN(__builtin_s390_vfaezh, "V8UsV8UsV8UsIi", "nc") +BUILTIN(__builtin_s390_vfaezhs, "V8UsV8UsV8UsIii*", "nc") +BUILTIN(__builtin_s390_vfaezf, "V4UiV4UiV4UiIi", "nc") +BUILTIN(__builtin_s390_vfaezfs, "V4UiV4UiV4UiIii*", "nc") +BUILTIN(__builtin_s390_vfeeb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vfeebs, "V16UcV16UcV16Uci*", "nc") +BUILTIN(__builtin_s390_vfeeh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vfeehs, "V8UsV8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vfeef, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vfeefs, "V4UiV4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vfeezb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vfeezbs, "V16UcV16UcV16Uci*", "nc") +BUILTIN(__builtin_s390_vfeezh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vfeezhs, "V8UsV8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vfeezf, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vfeezfs, "V4UiV4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vfeneb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vfenebs, "V16UcV16UcV16Uci*", "nc") +BUILTIN(__builtin_s390_vfeneh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vfenehs, "V8UsV8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vfenef, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vfenefs, "V4UiV4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vfenezb, "V16UcV16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vfenezbs, "V16UcV16UcV16Uci*", "nc") +BUILTIN(__builtin_s390_vfenezh, "V8UsV8UsV8Us", "nc") +BUILTIN(__builtin_s390_vfenezhs, "V8UsV8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vfenezf, "V4UiV4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vfenezfs, "V4UiV4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vistrb, "V16UcV16Uc", "nc") +BUILTIN(__builtin_s390_vistrbs, "V16UcV16Uci*", "nc") +BUILTIN(__builtin_s390_vistrh, "V8UsV8Us", "nc") +BUILTIN(__builtin_s390_vistrhs, "V8UsV8Usi*", "nc") +BUILTIN(__builtin_s390_vistrf, "V4UiV4Ui", "nc") +BUILTIN(__builtin_s390_vistrfs, "V4UiV4Uii*", "nc") +BUILTIN(__builtin_s390_vstrcb, "V16UcV16UcV16UcV16UcIi", "nc") +BUILTIN(__builtin_s390_vstrcbs, "V16UcV16UcV16UcV16UcIii*", "nc") +BUILTIN(__builtin_s390_vstrch, "V8UsV8UsV8UsV8UsIi", "nc") +BUILTIN(__builtin_s390_vstrchs, "V8UsV8UsV8UsV8UsIii*", "nc") +BUILTIN(__builtin_s390_vstrcf, "V4UiV4UiV4UiV4UiIi", "nc") +BUILTIN(__builtin_s390_vstrcfs, "V4UiV4UiV4UiV4UiIii*", "nc") +BUILTIN(__builtin_s390_vstrczb, "V16UcV16UcV16UcV16UcIi", "nc") +BUILTIN(__builtin_s390_vstrczbs, "V16UcV16UcV16UcV16UcIii*", "nc") +BUILTIN(__builtin_s390_vstrczh, "V8UsV8UsV8UsV8UsIi", "nc") +BUILTIN(__builtin_s390_vstrczhs, "V8UsV8UsV8UsV8UsIii*", "nc") +BUILTIN(__builtin_s390_vstrczf, "V4UiV4UiV4UiV4UiIi", "nc") +BUILTIN(__builtin_s390_vstrczfs, "V4UiV4UiV4UiV4UiIii*", "nc") + +// Vector floating-point instructions (chapter 24 of the PoP) +BUILTIN(__builtin_s390_vfcedbs, "V2SLLiV2dV2di*", "nc") +BUILTIN(__builtin_s390_vfchdbs, "V2SLLiV2dV2di*", "nc") +BUILTIN(__builtin_s390_vfchedbs, "V2SLLiV2dV2di*", "nc") +BUILTIN(__builtin_s390_vfidb, "V2dV2dIiIi", "nc") +BUILTIN(__builtin_s390_vflndb, "V2dV2d", "nc") +BUILTIN(__builtin_s390_vflpdb, "V2dV2d", "nc") +BUILTIN(__builtin_s390_vfmadb, "V2dV2dV2dV2d", "nc") +BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc") +BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc") +BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc") + +#undef BUILTIN diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index eb6803b..1a597b5 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -316,8 +316,6 @@ BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "") BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "") BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "") BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_pslldqi128, "V2LLiV2LLiIi", "") -BUILTIN(__builtin_ia32_psrldqi128, "V2LLiV2LLiIi", "") BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "") BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "") BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "") @@ -338,9 +336,6 @@ BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIc", "") BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fIc", "") BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "") -BUILTIN(__builtin_ia32_pblendw128, "V8sV8sV8sIc", "") -BUILTIN(__builtin_ia32_blendpd, "V2dV2dV2dIc", "") -BUILTIN(__builtin_ia32_blendps, "V4fV4fV4fIc", "") BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "") BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "") @@ -436,16 +431,11 @@ BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "") BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "") BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "") BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "") -BUILTIN(__builtin_ia32_blendpd256, "V4dV4dV4dIc", "") -BUILTIN(__builtin_ia32_blendps256, "V8fV8fV8fIc", "") BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "") BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "") BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "") BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "") BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "") -BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIc", "") -BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIc", "") -BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIc", "") BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "") BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "") BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "") @@ -457,9 +447,6 @@ BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "") BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "") BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "") BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "") -BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dIc", "") -BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fIc", "") -BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4iIc", "") BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "") BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "") BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "") @@ -524,7 +511,6 @@ BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIc", "") BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "") BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "") BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "") -BUILTIN(__builtin_ia32_pblendw256, "V16sV16sV16sIc", "") BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "") BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "") BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "") @@ -590,9 +576,6 @@ BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLi*", "") BUILTIN(__builtin_ia32_vbroadcastss_ps, "V4fV4f", "") BUILTIN(__builtin_ia32_vbroadcastss_ps256, "V8fV4f", "") BUILTIN(__builtin_ia32_vbroadcastsd_pd256, "V4dV2d", "") -BUILTIN(__builtin_ia32_vbroadcastsi256, "V4LLiV2LLi", "") -BUILTIN(__builtin_ia32_pblendd128, "V4iV4iV4iIc", "") -BUILTIN(__builtin_ia32_pblendd256, "V8iV8iV8iIc", "") BUILTIN(__builtin_ia32_pbroadcastb256, "V32cV16c", "") BUILTIN(__builtin_ia32_pbroadcastw256, "V16sV8s", "") BUILTIN(__builtin_ia32_pbroadcastd256, "V8iV4i", "") @@ -604,8 +587,6 @@ BUILTIN(__builtin_ia32_pbroadcastq128, "V2LLiV2LLi", "") BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "") BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8f", "") BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "") -BUILTIN(__builtin_ia32_extract128i256, "V2LLiV4LLiIc", "") -BUILTIN(__builtin_ia32_insert128i256, "V4LLiV4LLiV2LLiIc", "") BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "") BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "") BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "") @@ -738,12 +719,12 @@ BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "") BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "") BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "") BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUci", "") -BUILTIN(__builtin_ia32_vfmsubpd512_mask, "V8dV8dV8dV8dUci", "") -BUILTIN(__builtin_ia32_vfnmaddpd512_mask, "V8dV8dV8dV8dUci", "") -BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsi", "") -BUILTIN(__builtin_ia32_vfmsubps512_mask, "V16fV16fV16fV16fUsi", "") -BUILTIN(__builtin_ia32_vfnmaddps512_mask, "V16fV16fV16fV16fUsi", "") +BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_vfmsubpd512_mask, "V8dV8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_vfnmaddpd512_mask, "V8dV8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "") +BUILTIN(__builtin_ia32_vfmsubps512_mask, "V16fV16fV16fV16fUsIi", "") +BUILTIN(__builtin_ia32_vfnmaddps512_mask, "V16fV16fV16fV16fUsIi", "") // XOP BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "") @@ -820,29 +801,33 @@ BUILTIN(__builtin_ia32_rdtsc, "ULLi", "") BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "") // AVX-512 -BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUciC", "") -BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsiC", "") +BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsIi", "") BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "") BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "") BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "") BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_rsqrt28sd_mask, "V2dV2dV2dV2dUciC", "") -BUILTIN(__builtin_ia32_rsqrt28ss_mask, "V4fV4fV4fV4fUciC", "") -BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUciC", "") -BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsiC", "") +BUILTIN(__builtin_ia32_rsqrt28sd_mask, "V2dV2dV2dV2dUcIi", "") +BUILTIN(__builtin_ia32_rsqrt28ss_mask, "V4fV4fV4fV4fUcIi", "") +BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "") BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "") BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "") BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "") BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_rcp28sd_mask, "V2dV2dV2dV2dUciC", "") -BUILTIN(__builtin_ia32_rcp28ss_mask, "V4fV4fV4fV4fUciC", "") -BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUciC", "") -BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsiC", "") -BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsiC", "") -BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsiC", "") -BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUciC", "") -BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUciC", "") -BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fiCUsi", "") +BUILTIN(__builtin_ia32_rcp28sd_mask, "V2dV2dV2dV2dUcIi", "") +BUILTIN(__builtin_ia32_rcp28ss_mask, "V4fV4fV4fV4fUcIi", "") +BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "") +BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "") +BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "") +BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "") +BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "") +BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "") +BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "") +BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "") +BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "") BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "") BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "") BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "") @@ -855,24 +840,44 @@ BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "") BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "") BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "") BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "") -BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8diCUci", "") -BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fiCV16fUsiC", "") -BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8diCV8dUciC", "") -BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsiC", "") -BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUciC", "") -BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsiC", "") -BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUciC", "") -BUILTIN(__builtin_ia32_minps512_mask, "V16fV16fV16fV16fUsiC", "") -BUILTIN(__builtin_ia32_minpd512_mask, "V8dV8dV8dV8dUciC", "") -BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsiC", "") -BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUciC", "") -BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsiC", "") -BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsiC", "") +BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "") +BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "") +BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "") +BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "") +BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "") +BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "") +BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "") +BUILTIN(__builtin_ia32_pcmpgtw256_mask, "sV16sV16ss", "") +BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "") +BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "") +BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "") +BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "") +BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "") +BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "") +BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "") +BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "") +BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "") +BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "") +BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "") +BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "") +BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "") +BUILTIN(__builtin_ia32_minps512_mask, "V16fV16fV16fV16fUsIi", "") +BUILTIN(__builtin_ia32_minpd512_mask, "V8dV8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsIi", "") +BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcIi", "") +BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "") +BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "") BUILTIN(__builtin_ia32_cvtdq2pd512_mask, "V8dV8iV8dUc", "") BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "") -BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUciC", "") -BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fiCV16sUs", "") -BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsiC", "") +BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "") +BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "") +BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "") +BUILTIN(__builtin_ia32_pandd512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_pandq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_pord512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_porq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_pxord512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_pxorq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") BUILTIN(__builtin_ia32_pabsd512_mask, "V16iV16iV16iUs", "") BUILTIN(__builtin_ia32_pabsq512_mask, "V8LLiV8LLiV8LLiUc", "") BUILTIN(__builtin_ia32_pmaxsd512_mask, "V16iV16iV16iV16iUs", "") @@ -897,41 +902,152 @@ BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "") BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16ivC*V16iUs", "") BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLivC*V8LLiUc", "") BUILTIN(__builtin_ia32_loadups512_mask, "V16fvC*V16fUs", "") +BUILTIN(__builtin_ia32_loadaps512_mask, "V16fvC*V16fUs", "") BUILTIN(__builtin_ia32_loadupd512_mask, "V8dvC*V8dUc", "") +BUILTIN(__builtin_ia32_loadapd512_mask, "V8dvC*V8dUc", "") BUILTIN(__builtin_ia32_storedqudi512_mask, "vv*V8LLiUc", "") BUILTIN(__builtin_ia32_storedqusi512_mask, "vv*V16iUs", "") BUILTIN(__builtin_ia32_storeupd512_mask, "vv*V8dUc", "") +BUILTIN(__builtin_ia32_storeapd512_mask, "vv*V8dUc", "") BUILTIN(__builtin_ia32_storeups512_mask, "vv*V16fUs", "") +BUILTIN(__builtin_ia32_storeaps512_mask, "vv*V16fUs", "") BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "") BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "") BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "") -BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiUcV8LLiUc", "") -BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iUcV16iUc", "") -BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUciC", "") -BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*UsiC", "") -BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUciC", "") -BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUciC", "") -BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUciC", "") -BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*UsiC", "") -BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUciC", "") -BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUciC", "") -BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8diC", "") -BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fiC", "") -BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8diC", "") -BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fiC", "") -BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiiC", "") -BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iiC", "") -BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiiC", "") -BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iiC", "") -BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*iCiC", "") -BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*iCiC", "") -BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*iCiC", "") -BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*iCiC", "") -BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*iCiC", "") -BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*iCiC", "") -BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*iCiC", "") -BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*iCiC", "") +BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiIcV8LLiUc", "") +BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iIcV16iUs", "") +BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIcV4dUc", "") +BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIcV4fUc", "") +BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "") +BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*UsIi", "") +BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "") +BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "") +BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "") +BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*UsIi", "") +BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "") +BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "") +BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "") +BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "") +BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "") +BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "") +BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "") +BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "") +BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "") +BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "") +BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "") +BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "") +BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "") +BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "") +BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "") +BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "") +BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "") +BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "") BUILTIN(__builtin_ia32_knothi, "UsUs", "") +BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "") +BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "") +BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "") +BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "") +BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "") +BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "") +BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "") +BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "") +BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "") +BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "") +BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "") +BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "") +BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "") +BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "") +BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "") +BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "") +BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "") +BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "") +BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "") +BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "") +BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "") +BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "") +BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "") +BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "") + +BUILTIN(__builtin_ia32_paddd256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "") +BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "") +BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "") +BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "") +BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_pandd256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_pandd128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_pandnd256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_pandnd128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_pord256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_pord128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_pxord256_mask, "V8iV8iV8iV8iUc", "") +BUILTIN(__builtin_ia32_pxord128_mask, "V4iV4iV4iV4iUc", "") +BUILTIN(__builtin_ia32_pandq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_pandq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_pandnq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_pandnq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_porq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_porq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_pxorq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_pxorq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "") +BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "") +BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "") +BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "") +BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "") +BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "") +BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "") +BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "") +BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "") +BUILTIN(__builtin_ia32_pandnd512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_pandnq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "") +BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") +BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "") +BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "") +BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "") +BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "") +BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "") +BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "") +BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "") +BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "") +BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") +BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") +BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "") +BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "") +BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "") +BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "") +BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "") +BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "") +BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "") +BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "") +BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "") +BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "") +BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "") +BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "") +BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "") +BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "") +BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "") +BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "") + #undef BUILTIN diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index 18bca57..dece8f9 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -11,6 +11,7 @@ class DDecl<Decl base, bit abstract = 0> : Decl<abstract> { class DeclContext { } def TranslationUnit : Decl, DeclContext; +def ExternCContext : Decl, DeclContext; def Named : Decl<1>; def Namespace : DDecl<Named>, DeclContext; def UsingDirective : DDecl<Named>; diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 91e94db..0f3831d 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -132,8 +132,8 @@ public: /// the user. DiagnosticsEngine is tied to one translation unit and one /// SourceManager. class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> { - DiagnosticsEngine(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION; - void operator=(const DiagnosticsEngine &) LLVM_DELETED_FUNCTION; + DiagnosticsEngine(const DiagnosticsEngine &) = delete; + void operator=(const DiagnosticsEngine &) = delete; public: /// \brief The level of the diagnostic, after it has been through mapping. @@ -877,7 +877,7 @@ class DiagnosticBuilder { /// call to ForceEmit. mutable bool IsForceEmit; - void operator=(const DiagnosticBuilder &) LLVM_DELETED_FUNCTION; + void operator=(const DiagnosticBuilder &) = delete; friend class DiagnosticsEngine; DiagnosticBuilder() @@ -991,7 +991,8 @@ public: void AddFixItHint(const FixItHint &Hint) const { assert(isActive() && "Clients must not add to cleared diagnostic!"); - DiagObj->DiagFixItHints.push_back(Hint); + if (!Hint.isNull()) + DiagObj->DiagFixItHints.push_back(Hint); } void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; } @@ -1095,7 +1096,13 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const FixItHint &Hint) { - if (!Hint.isNull()) + DB.AddFixItHint(Hint); + return DB; +} + +inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + ArrayRef<FixItHint> Hints) { + for (const FixItHint &Hint : Hints) DB.AddFixItHint(Hint); return DB; } @@ -1260,7 +1267,7 @@ public: ~StoredDiagnostic(); /// \brief Evaluates true when this object stores a diagnostic. - LLVM_EXPLICIT operator bool() const { return Message.size() > 0; } + explicit operator bool() const { return Message.size() > 0; } unsigned getID() const { return ID; } DiagnosticsEngine::Level getLevel() const { return Level; } @@ -1364,7 +1371,7 @@ class ForwardingDiagnosticConsumer : public DiagnosticConsumer { public: ForwardingDiagnosticConsumer(DiagnosticConsumer &Target) : Target(Target) {} - virtual ~ForwardingDiagnosticConsumer(); + ~ForwardingDiagnosticConsumer() override; void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Info) override; diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index d353b45..0b37030 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -168,6 +168,14 @@ let CategoryName = "Inline Assembly Issue" in { "invalid operand number in inline asm string">; } +// vtable related. +let CategoryName = "VTable ABI Issue" in { + def err_vftable_ambiguous_component : Error< + "ambiguous vftable component for %0 introduced via covariant thunks; " + "this is an inherent limitation of the ABI">; + def note_covariant_thunk : Note< + "covariant thunk required by %0">; +} // Importing ASTs def err_odr_variable_type_inconsistent : Error< diff --git a/include/clang/Basic/DiagnosticCommentKinds.td b/include/clang/Basic/DiagnosticCommentKinds.td index 6dc8b27..ab24582 100644 --- a/include/clang/Basic/DiagnosticCommentKinds.td +++ b/include/clang/Basic/DiagnosticCommentKinds.td @@ -166,7 +166,7 @@ def warn_unknown_comment_command_name : Warning< def warn_correct_comment_command_name : Warning< "unknown command tag name '%0'; did you mean '%1'?">, - InGroup<Documentation>, DefaultIgnore; + InGroup<DocumentationUnknownCommand>, DefaultIgnore; } // end of documentation issue category } // end of AST component diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index ff9ed69..afdd926 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -81,8 +81,13 @@ def err_deleted_non_function : Error< "only functions can have deleted definitions">; def err_module_not_found : Error<"module '%0' not found">, DefaultFatal; def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal; +def err_module_build_disabled: Error< + "module '%0' is needed but has not been provided, and implicit use of module " + "files is disabled">, DefaultFatal; def err_module_lock_failure : Error< "could not acquire lock file for module '%0'">, DefaultFatal; +def err_module_lock_timeout : Error< + "timed out waiting to acquire lock file for module '%0'">, DefaultFatal; def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, DefaultFatal; def note_pragma_entered_here : Note<"#pragma entered here">; @@ -112,6 +117,16 @@ def ext_integer_literal_too_large_for_signed : ExtWarn< "interpreting as unsigned">, InGroup<DiagGroup<"implicitly-unsigned-literal">>; +// SEH +def err_seh_expected_handler : Error< + "expected '__except' or '__finally' block">; +def err_seh___except_block : Error< + "%0 only allowed in __except block or filter expression">; +def err_seh___except_filter : Error< + "%0 only allowed in __except filter expression">; +def err_seh___finally_block : Error< + "%0 only allowed in __finally block">; + // Sema && AST def note_invalid_subexpr_in_const_expr : Note< "subexpression not valid in a constant expression">; diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 41c78ee..7c0696a 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -142,6 +142,8 @@ def warn_drv_empty_joined_argument : Warning< InGroup<UnusedCommandLineArgument>; def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; +def warn_drv_deprecated_arg : Warning< + "argument '%0' is deprecated, use '%1' instead">, InGroup<Deprecated>; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; def warn_ignoring_ftabstop_value : Warning< @@ -160,6 +162,12 @@ def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">, InGroup<DiagGroup<"missing-sysroot">>; def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">, InGroup<DiagGroup<"debug-compression-unavailable">>; +def warn_drv_enabling_rtti_with_exceptions : Warning< + "implicitly enabling rtti for exception handling">, + InGroup<DiagGroup<"rtti-for-exceptions">>; +def warn_drv_disabling_vptr_no_rtti_default : Warning< + "implicitly disabling vptr sanitizer because rtti wasn't enabled">, + InGroup<DiagGroup<"auto-disable-vptr-sanitizer">>; def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; @@ -179,4 +187,11 @@ def err_drv_modules_validate_once_requires_timestamp : Error< def warn_drv_invoking_fallback : Warning<"falling back to %0">, InGroup<Fallback>; + +def warn_target_unsupported_nan2008 : Warning< + "ignoring '-mnan=2008' option because the '%0' architecture does not support it">, + InGroup<UnsupportedNan>; +def warn_target_unsupported_nanlegacy : Warning< + "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">, + InGroup<UnsupportedNan>; } diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 15f74b11..f4ab480 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -35,6 +35,10 @@ def err_fe_backend_plugin: Error<"%0">, BackendInfo; def remark_fe_backend_plugin: Remark<"%0">, BackendInfo, InGroup<RemarkBackendPlugin>; def note_fe_backend_plugin: Note<"%0">, BackendInfo; +def warn_fe_override_module : Warning< + "overriding the module target triple with %0">, + InGroup<DiagGroup<"override-module">>; + def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo, InGroup<BackendOptimizationRemark>; def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo, @@ -193,7 +197,11 @@ def err_conflicting_module_names : Error< def err_conflicting_module_files : Error< "module '%0' is defined in both '%1' and '%2'">; def err_module_file_not_found : Error< - "file '%0' is not a precompiled module file">, DefaultFatal; + "module file '%0' not found">, DefaultFatal; +def err_module_file_invalid : Error< + "file '%0' is not a valid precompiled module file">, DefaultFatal; +def note_module_file_imported_by : Note< + "imported by %select{|module '%2' in }1'%0'">; def err_module_file_not_module : Error< "AST file '%0' was not built as a module">, DefaultFatal; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 2681ada..61436ea 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -45,6 +45,7 @@ def IntConversion : DiagGroup<"int-conversion">; def EnumConversion : DiagGroup<"enum-conversion">; def FloatConversion : DiagGroup<"float-conversion">; def EnumTooLarge : DiagGroup<"enum-too-large">; +def UnsupportedNan : DiagGroup<"unsupported-nan">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; def NullConversion : DiagGroup<"null-conversion">; def ImplicitConversionFloatingPointToBool : @@ -80,6 +81,7 @@ def CXX11CompatDeprecatedWritableStr : def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def UnavailableDeclarations : DiagGroup<"unavailable-declarations">; +def PartialAvailability : DiagGroup<"partial-availability">; def DeprecatedImplementations :DiagGroup<"deprecated-implementations">; def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">; def DeprecatedRegister : DiagGroup<"deprecated-register">; @@ -106,6 +108,8 @@ def Documentation : DiagGroup<"documentation", DocumentationDeprecatedSync]>; def EmptyBody : DiagGroup<"empty-body">; +def Exceptions : DiagGroup<"exceptions">; + def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">; def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">; def ExtraTokens : DiagGroup<"extra-tokens">; @@ -190,6 +194,7 @@ def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">; def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; +def FlagEnum : DiagGroup<"flag-enum">; def InfiniteRecursion : DiagGroup<"infinite-recursion">; def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; @@ -218,7 +223,10 @@ def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">; def LiteralRange : DiagGroup<"literal-range">; def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args", [CXX98CompatLocalTypeTemplateArgs]>; -def LoopAnalysis : DiagGroup<"loop-analysis">; +def RangeLoopAnalysis : DiagGroup<"range-loop-analysis">; +def ForLoopAnalysis : DiagGroup<"for-loop-analysis">; +def LoopAnalysis : DiagGroup<"loop-analysis", [ForLoopAnalysis, + RangeLoopAnalysis]>; def MalformedWarningCheck : DiagGroup<"malformed-warning-check">; def Main : DiagGroup<"main">; def MainReturnType : DiagGroup<"main-return-type">; @@ -278,6 +286,7 @@ def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">; def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">; def Packed : DiagGroup<"packed">; def Padded : DiagGroup<"padded">; +def PessimizingMove : DiagGroup<"pessimizing-move">; def PointerArith : DiagGroup<"pointer-arith">; def PoundWarning : DiagGroup<"#warnings">; def PoundPragmaMessage : DiagGroup<"#pragma-messages">, @@ -286,6 +295,7 @@ def : DiagGroup<"pointer-to-int-cast">; def : DiagGroup<"redundant-decls">; def RedeclaredClassMember : DiagGroup<"redeclared-class-member">; def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">; +def RedundantMove : DiagGroup<"redundant-move">; def ReturnStackAddress : DiagGroup<"return-stack-address">; def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">; def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>; @@ -386,10 +396,12 @@ def IgnoredPragmas : DiagGroup<"ignored-pragmas">; def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>; def UnknownWarningOption : DiagGroup<"unknown-warning-option">; def NSobjectAttribute : DiagGroup<"NSObject-attribute">; +def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">; def UnknownAttributes : DiagGroup<"unknown-attributes">; def IgnoredAttributes : DiagGroup<"ignored-attributes">; def Attributes : DiagGroup<"attributes", [UnknownAttributes, IgnoredAttributes]>; +def UnknownSanitizers : DiagGroup<"unknown-sanitizers">; def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args", [CXX98CompatUnnamedTypeTemplateArgs]>; def UnsupportedFriend : DiagGroup<"unsupported-friend">; @@ -550,6 +562,7 @@ def FormatInvalidSpecifier : DiagGroup<"format-invalid-specifier">; def FormatSecurity : DiagGroup<"format-security">; def FormatNonStandard : DiagGroup<"format-non-iso">; def FormatY2K : DiagGroup<"format-y2k">; +def FormatPedantic : DiagGroup<"format-pedantic">; def Format : DiagGroup<"format", [FormatExtraArgs, FormatZeroLength, NonNull, FormatSecurity, FormatY2K, FormatInvalidSpecifier]>, @@ -564,6 +577,8 @@ def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">; def IntToPointerCast : DiagGroup<"int-to-pointer-cast", [IntToVoidPointerCast]>; +def Move : DiagGroup<"move", [PessimizingMove, RedundantMove, SelfMove]>; + def Extra : DiagGroup<"extra", [ MissingFieldInitializers, IgnoredQualifiers, @@ -582,6 +597,7 @@ def Most : DiagGroup<"most", [ Implicit, MismatchedTags, MissingBraces, + Move, MultiChar, Reorder, ReturnType, diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 99b469d..a675dfa 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -34,7 +34,7 @@ namespace clang { DIAG_START_LEX = DIAG_START_SERIALIZATION + 120, DIAG_START_PARSE = DIAG_START_LEX + 300, DIAG_START_AST = DIAG_START_PARSE + 500, - DIAG_START_COMMENT = DIAG_START_AST + 100, + DIAG_START_COMMENT = DIAG_START_AST + 110, DIAG_START_SEMA = DIAG_START_COMMENT + 100, DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 93cc7c2..3d568e8 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -579,7 +579,9 @@ def err_mmap_module_id : Error< def err_mmap_expected_library_name : Error< "expected %select{library|framework}0 name as a string">; def err_mmap_config_macro_submodule : Error< - "configuration macros are only allowed on top-level modules">; + "configuration macros are only allowed in top-level modules">; +def err_mmap_use_decl_submodule : Error< + "use declarations are only allowed in top-level modules">; def err_mmap_expected_config_macro : Error< "expected configuration macro name after ','">; def err_mmap_expected_conflicts_comma : Error< @@ -625,9 +627,10 @@ def warn_uncovered_module_header : Warning< InGroup<IncompleteUmbrella>; def err_expected_id_building_module : Error< "expected a module name in '__building_module' expression">; -def error_use_of_private_header_outside_module : Error< - "use of private header from outside its module: '%0'">; -def error_undeclared_use_of_module : Error< +def warn_use_of_private_header_outside_module : Warning< + "use of private header from outside its module: '%0'">, + InGroup<DiagGroup<"private-header">>, DefaultError; +def err_undeclared_use_of_module : Error< "module %0 does not depend on a module exporting '%1'">; def warn_non_modular_include_in_framework_module : Warning< "include of non-modular header inside framework module '%0'">, @@ -635,7 +638,9 @@ def warn_non_modular_include_in_framework_module : Warning< def warn_non_modular_include_in_module : Warning< "include of non-modular header inside module '%0'">, InGroup<NonModularIncludeInModule>, DefaultIgnore; - +def warn_module_conflict : Warning< + "module '%0' conflicts with already-imported module '%1': %2">, + InGroup<ModuleConflict>; def warn_header_guard : Warning< "%0 is used as a header guard here, followed by #define of a different macro">, diff --git a/include/clang/Basic/DiagnosticOptions.h b/include/clang/Basic/DiagnosticOptions.h index 058e00f..a16c774 100644 --- a/include/clang/Basic/DiagnosticOptions.h +++ b/include/clang/Basic/DiagnosticOptions.h @@ -27,7 +27,7 @@ enum OverloadsShown : unsigned { /// \brief Options for controlling the compiler diagnostics engine. class DiagnosticOptions : public RefCountedBase<DiagnosticOptions>{ public: - enum TextDiagnosticFormat { Clang, Msvc, Vi }; + enum TextDiagnosticFormat { Clang, MSVC, Vi }; // Default values. enum { DefaultTabStop = 8, MaxTabStop = 100, diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index eca5f13..f00a3b3 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -25,6 +25,8 @@ def err_msasm_unsupported_arch : Error< "Unsupported architecture '%0' for MS-style inline assembly">; def err_msasm_unable_to_create_target : Error< "MS-style inline assembly is not available: %0">; +def err_gnu_inline_asm_disabled : Error< + "GNU-style inline assembly is disabled">; } let CategoryName = "Parse Issue" in { @@ -168,6 +170,7 @@ def err_function_declared_typedef : Error< "function definition declared 'typedef'">; def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">; def err_at_in_class : Error<"unexpected '@' in member specification">; +def err_unexpected_semi : Error<"unexpected ';' before %0">; def err_expected_fn_body : Error< "expected function body after function declarator">; @@ -181,6 +184,8 @@ def warn_attribute_no_decl : Warning< "attribute %0 ignored, because it is not attached to a declaration">, InGroup<IgnoredAttributes>; def err_expected_method_body : Error<"expected method body">; +def err_declspec_after_virtspec : Error< + "'%0' qualifier may not appear after the virtual specifier '%1'">; def err_invalid_token_after_toplevel_declarator : Error< "expected ';' after top level declarator">; def err_invalid_token_after_declarator_suggest_equal : Error< @@ -350,7 +355,12 @@ def err_invalid_pixel_decl_spec_combination : Error< def err_invalid_vector_bool_decl_spec : Error< "cannot use '%0' with '__vector bool'">; def err_invalid_vector_double_decl_spec : Error < - "use of 'double' with '__vector' requires VSX support to be enabled (available on the POWER7 or later)">; + "use of 'double' with '__vector' requires VSX support to be enabled " + "(available on POWER7 or later)">; +def err_invalid_vector_long_long_decl_spec : Error < + "use of 'long long' with '__vector bool' requires VSX support (available on " + "POWER7 or later) or extended Altivec support (available on POWER8 or later) " + "to be enabled">; def err_invalid_vector_long_double_decl_spec : Error< "cannot use 'long double' with '__vector'">; def warn_vector_long_decl_spec_combination : Warning< @@ -468,7 +478,8 @@ def err_invalid_operator_on_type : Error< def err_expected_unqualified_id : Error< "expected %select{identifier|unqualified-id}0">; def err_brackets_go_after_unqualified_id : Error< - "brackets go after the %select{identifier|unqualified-id}0">; + "brackets are not allowed here; to declare an array, " + "place the brackets after the %select{identifier|name}0">; def err_unexpected_unqualified_id : Error<"type-id cannot have a name">; def err_func_def_no_params : Error< "function definition does not declare parameters">; @@ -924,6 +935,9 @@ def err_pragma_fp_contract_scope : Error< def err_pragma_comment_malformed : Error< "pragma comment requires parenthesized identifier and optional string">; def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">; +// PS4 recognizes only #pragma comment(lib) +def warn_pragma_comment_ignored : Warning<"'#pragma comment %0' ignored">, + InGroup<Microsoft>; // - #pragma detect_mismatch def err_pragma_detect_mismatch_malformed : Error< "pragma detect_mismatch is malformed; it requires two comma-separated " @@ -951,18 +965,6 @@ def warn_pragma_expected_enable_disable : Warning< def warn_pragma_unknown_extension : Warning< "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>; -def err_seh_expected_handler : Error< - "expected '__except' or '__finally' block">; - -def err_seh___except_block : Error< - "%0 only allowed in __except block">; - -def err_seh___except_filter : Error< - "%0 only allowed in __except filter expression">; - -def err_seh___finally_block : Error< - "%0 only allowed in __finally block">; - // OpenMP support. def warn_pragma_omp_ignored : Warning< "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore; diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1a27e7c..9ccd5ad 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1,3 +1,4 @@ + //==--- DiagnosticSemaKinds.td - libsema diagnostics ----------------------===// // // The LLVM Compiler Infrastructure @@ -23,13 +24,30 @@ def note_defined_here : Note<"%0 defined here">; def warn_variables_not_in_loop_body : Warning< "variable%select{s| %1|s %1 and %2|s %1, %2, and %3|s %1, %2, %3, and %4}0 " "used in loop condition not modified in loop body">, - InGroup<LoopAnalysis>, DefaultIgnore; + InGroup<ForLoopAnalysis>, DefaultIgnore; def warn_redundant_loop_iteration : Warning< "variable %0 is %select{decremented|incremented}1 both in the loop header " "and in the loop body">, - InGroup<LoopAnalysis>, DefaultIgnore; + InGroup<ForLoopAnalysis>, DefaultIgnore; def note_loop_iteration_here : Note<"%select{decremented|incremented}0 here">; +def warn_for_range_const_reference_copy : Warning< + "loop variable %0 " + "%diff{has type $ but is initialized with type $" + "| is initialized with a value of a different type}1,2 resulting in a copy">, + InGroup<RangeLoopAnalysis>, DefaultIgnore; +def note_use_type_or_non_reference : Note< + "use non-reference type %0 to keep the copy or type %1 to prevent copying">; +def warn_for_range_variable_always_copy : Warning< + "loop variable %0 is always a copy because the range of type %1 does not " + "return a reference">, + InGroup<RangeLoopAnalysis>, DefaultIgnore; +def note_use_non_reference_type : Note<"use non-reference type %0">; +def warn_for_range_copy : Warning< + "loop variable %0 of type %1 creates a copy from type %2">, + InGroup<RangeLoopAnalysis>, DefaultIgnore; +def note_use_reference_type : Note<"use reference type %0 to prevent copying">; + def warn_duplicate_enum_values : Warning< "element %0 has been implicitly assigned %1 which another element has " "been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore; @@ -467,6 +485,8 @@ def warn_static_main : Warning<"'main' should not be declared static">, InGroup<Main>; def err_static_main : Error<"'main' is not allowed to be declared static">; def err_inline_main : Error<"'main' is not allowed to be declared inline">; +def ext_variadic_main : ExtWarn< + "'main' is not allowed to be declared variadic">, InGroup<Main>; def ext_noreturn_main : ExtWarn< "'main' is not allowed to be declared _Noreturn">, InGroup<Main>; def note_main_remove_noreturn : Note<"remove '_Noreturn'">; @@ -730,7 +750,7 @@ def warn_accessor_property_type_mismatch : Warning< def not_conv_function_declared_at : Note<"type conversion function declared here">; def note_method_declared_at : Note<"method %0 declared here">; def note_property_attribute : Note<"property %0 is declared " - "%select{deprecated|unavailable}1 here">; + "%select{deprecated|unavailable|partial}1 here">; def err_setter_type_void : Error<"type of setter must be void">; def err_duplicate_method_decl : Error<"duplicate declaration of method %0">; def warn_duplicate_method_decl : @@ -797,6 +817,12 @@ def warn_cocoa_naming_owned_rule : Warning< "property follows Cocoa naming" " convention for returning 'owned' objects">, InGroup<DiagGroup<"objc-property-matches-cocoa-ownership-rule">>; +def err_cocoa_naming_owned_rule : Error< + "property follows Cocoa naming" + " convention for returning 'owned' objects">; +def note_cocoa_naming_declare_family : Note< + "explicitly declare getter %objcinstance0 with '%1' to return an 'unowned' " + "object">; def warn_auto_synthesizing_protocol_property :Warning< "auto property synthesis will not synthesize property %0" " declared in protocol %1">, @@ -828,9 +854,6 @@ def warn_property_getter_owning_mismatch : Warning< def error_property_setter_ambiguous_use : Error< "synthesized properties %0 and %1 both claim setter %2 -" " use of this setter will cause unexpected behavior">; -def err_cocoa_naming_owned_rule : Error< - "property follows Cocoa naming" - " convention for returning 'owned' objects">; def warn_default_atomic_custom_getter_setter : Warning< "atomic by default property %0 has a user defined %select{getter|setter}1 " "(property should be marked 'atomic' if this is intended)">, @@ -889,8 +912,6 @@ def warn_receiver_is_weak : Warning < "weak %select{receiver|property|implicit property}0 may be " "unpredictably set to nil">, InGroup<DiagGroup<"receiver-is-weak">>, DefaultIgnore; -def note_arc_assign_to_strong : Note< - "assign the value to a strong variable to keep the object alive during use">; def warn_arc_repeated_use_of_weak : Warning < "weak %select{variable|property|implicit property|instance variable}0 %1 is " "accessed multiple times in this %select{function|method|block|lambda}2 " @@ -1227,13 +1248,19 @@ def warn_cxx98_compat_enum_nested_name_spec : Warning< InGroup<CXX98Compat>, DefaultIgnore; def err_nested_name_spec_is_not_class : Error< "%0 cannot appear before '::' because it is not a class" - "%select{ or namespace|, namespace, or scoped enumeration}1; did you mean ':'?">; + "%select{ or namespace|, namespace, or enumeration}1; did you mean ':'?">; +def ext_nested_name_spec_is_enum : ExtWarn< + "use of enumeration in a nested name specifier is a C++11 extension">, + InGroup<CXX11>; // C++ class members def err_storageclass_invalid_for_member : Error< "storage class specified for a member declaration">; def err_mutable_function : Error<"'mutable' cannot be applied to functions">; def err_mutable_reference : Error<"'mutable' cannot be applied to references">; +def ext_mutable_reference : ExtWarn< + "'mutable' on a reference type is a Microsoft extension">, + InGroup<Microsoft>; def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">; def err_mutable_nonmember : Error< "'mutable' can only be applied to member variables">; @@ -1292,6 +1319,8 @@ def err_missing_default_ctor : Error< "%select{|implicit default |inheriting }0constructor for %1 must explicitly " "initialize the %select{base class|member}2 %3 which does not have a default " "constructor">; +def note_due_to_dllexported_class : Note< + "due to '%0' being dllexported%select{|; try compiling in C++11 mode}1">; def err_illegal_union_or_anon_struct_member : Error< "%select{anonymous struct|union}0 member %1 has a non-trivial " @@ -1461,8 +1490,10 @@ def err_lvalue_reference_bind_to_unrelated : Error< "%diff{to type $ cannot bind to a value of unrelated type $|" "cannot bind to a value of unrelated type}1,2">; def err_reference_bind_drops_quals : Error< - "binding of reference %diff{to type $ to a value of type $ drops qualifiers|" - "drops qualifiers}0,1">; + "binding value %diff{of type $ to reference to type $|to reference}0,1 " + "drops %select{<<ERROR>>|'const'|'restrict'|'const' and 'restrict'|" + "'volatile'|'const' and 'volatile'|'restrict' and 'volatile'|" + "'const', 'restrict', and 'volatile'}2 qualifier%plural{1:|2:|4:|:s}2">; def err_reference_bind_failed : Error< "reference %diff{to type $ could not bind to an %select{rvalue|lvalue}1 of " "type $|could not bind to %select{rvalue|lvalue}1 of incompatible type}0,2">; @@ -1543,7 +1574,7 @@ def warn_uninit_byref_blockvar_captured_by_block : Warning< "block pointer variable %0 is uninitialized when captured by block">, InGroup<Uninitialized>, DefaultIgnore; def note_block_var_fixit_add_initialization : Note< - "maybe you meant to use __block %0">; + "did you mean to use __block %0?">; def note_in_omitted_aggregate_initializer : Note< "in implicit initialization of %select{array element %1|field %1}0 " "with omitted initializer">; @@ -2025,6 +2056,8 @@ def err_typecheck_vector_not_convertable : Error< "can't convert between vector values of different size (%0 and %1)">; def err_typecheck_vector_not_convertable_non_scalar : Error< "can't convert between vector and non-scalar values (%0 and %1)">; +def err_typecheck_vector_lengths_not_equal : Error< + "vector operands do not have the same number of elements (%0 and %1)">; def err_ext_vector_component_exceeds_length : Error< "vector component access exceeds type %0">; def err_ext_vector_component_name_illegal : Error< @@ -2091,6 +2124,9 @@ def note_objc_literal_comparison_isequal : Note< "use 'isEqual:' instead">; def err_attribute_argument_is_zero : Error< "%0 attribute must be greater than 0">; +def warn_attribute_argument_n_negative : Warning< + "%0 attribute parameter %1 is negative and will be ignored">, + InGroup<CudaCompat>; def err_property_function_in_objc_container : Error< "use of Objective-C property in function nested in Objective-C " "container not supported, move function outside its container">; @@ -2122,6 +2158,8 @@ def error_cannot_find_suitable_accessor : Error< def err_alignment_not_power_of_two : Error< "requested alignment is not a power of 2">; +def err_alignment_dependent_typedef_name : Error< + "requested alignment is dependent but declaration is not dependent">; def err_attribute_aligned_too_great : Error< "requested alignment must be %0 bytes or smaller">; @@ -2169,6 +2207,14 @@ def warn_gc_attribute_weak_on_local : Warning< def warn_nsobject_attribute : Warning< "'NSObject' attribute may be put on a typedef only; attribute is ignored">, InGroup<NSobjectAttribute>; +def warn_independentclass_attribute : Warning< + "'objc_independent_class' attribute may be put on a typedef only; " + "attribute is ignored">, + InGroup<IndependentClassAttribute>; +def warn_ptr_independentclass_attribute : Warning< + "'objc_independent_class' attribute may be put on Objective-C object " + "pointer type only; attribute is ignored">, + InGroup<IndependentClassAttribute>; def warn_attribute_weak_on_local : Warning< "__weak attribute cannot be specified on an automatic variable when ARC " "is not enabled">, @@ -2205,6 +2251,9 @@ def err_attribute_dllimport_static_field_definition : Error< def warn_attribute_dllimport_static_field_definition : Warning< "definition of dllimport static field">, InGroup<DiagGroup<"dllimport-static-field-def">>; +def warn_attribute_dllexport_explicit_instantiation_decl : Warning< + "explicit instantiation declaration should not be 'dllexport'">, + InGroup<DiagGroup<"dllexport-explicit-instantation-decl">>; def warn_invalid_initializer_from_system_header : Warning< "invalid constructor form class in system header, should not be explicit">, InGroup<DiagGroup<"invalid-initializer-from-system-header">>; @@ -2240,7 +2289,7 @@ def warn_attribute_wrong_decl_type : Warning< "%0 attribute only applies to %select{functions|unions|" "variables and functions|functions and methods|parameters|" "functions, methods and blocks|functions, methods, and classes|" - "functions, methods, and parameters|classes|variables|methods|" + "functions, methods, and parameters|classes|enums|variables|methods|" "variables, functions and labels|fields and global variables|structs|" "variables and typedefs|thread-local variables|" "variables and fields|variables, data members and tag types|" @@ -2248,7 +2297,7 @@ def warn_attribute_wrong_decl_type : Warning< "struct or union|struct, union or class|types|" "Objective-C instance methods|init methods of interface or class extension declarations|" "variables, functions and classes|Objective-C protocols|" - "functions and global variables|structs or typedefs|" + "functions and global variables|structs, unions, and typedefs|structs and typedefs|" "interface or protocol declarations|kernel functions}1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>; @@ -2388,6 +2437,13 @@ def warn_fun_excludes_mutex : Warning< def warn_cannot_resolve_lock : Warning< "cannot resolve lock expression">, InGroup<ThreadSafetyAnalysis>, DefaultIgnore; +def warn_acquired_before : Warning< + "%0 '%1' must be acquired before '%2'">, + InGroup<ThreadSafetyAnalysis>, DefaultIgnore; +def warn_acquired_before_after_cycle : Warning< + "Cycle in acquired_before/after dependencies, starting with '%0'">, + InGroup<ThreadSafetyAnalysis>, DefaultIgnore; + // Thread safety warnings negative capabilities def warn_acquire_requires_negative_cap : Warning< @@ -2465,6 +2521,10 @@ def warn_param_typestate_mismatch : Warning< "argument not in expected state; expected '%0', observed '%1'">, InGroup<Consumed>, DefaultIgnore; +// no_sanitize attribute +def warn_unknown_sanitizer_ignored : Warning< + "unknown sanitizer '%0' ignored">, InGroup<UnknownSanitizers>; + def warn_impcast_vector_scalar : Warning< "implicit conversion turns vector to scalar: %0 to %1">, InGroup<Conversion>, DefaultIgnore; @@ -2633,9 +2693,6 @@ def warn_attribute_nonnull_no_pointers : Warning< def warn_attribute_nonnull_parm_no_args : Warning< "'nonnull' attribute when used on parameters takes no arguments">, InGroup<IgnoredAttributes>; -def warn_attribute_malloc_pointer_only : Warning< - "'malloc' attribute only applies to functions returning a pointer type">, - InGroup<IgnoredAttributes>; def warn_attribute_sentinel_named_arguments : Warning< "'sentinel' attribute requires named arguments">, InGroup<IgnoredAttributes>; @@ -2728,6 +2785,10 @@ def warn_objc_implementation_missing_designated_init_override : Warning< // objc_bridge attribute diagnostics. def err_objc_attr_not_id : Error< "parameter of %0 attribute must be a single name of an Objective-C %select{class|protocol}1">; +def err_objc_attr_typedef_not_id : Error< + "parameter of %0 attribute must be 'id' when used on a typedef">; +def err_objc_attr_typedef_not_void_pointer : Error< + "'objc_bridge(id)' is only allowed on structs and typedefs of void pointers">; def err_objc_cf_bridged_not_interface : Error< "CF object of type %0 is bridged to %1, which is not an Objective-C class">; def err_objc_ns_bridged_invalid_cfobject : Error< @@ -2785,6 +2846,8 @@ def err_param_default_argument_member_template_redecl : Error< "default arguments cannot be added to an out-of-line definition of a member " "of a %select{class template|class template partial specialization|nested " "class in a template}0">; +def err_param_default_argument_on_parameter_pack : Error< + "parameter pack cannot have a default argument">; def err_uninitialized_member_for_assign : Error< "cannot define the implicit copy assignment operator for %0, because " "non-static %select{reference|const}1 member %2 can't use copy " @@ -3424,6 +3487,12 @@ def err_template_spec_redecl_out_of_scope : Error< "variable template partial|function template|member " "function|static data member|member class|member enumeration}0 " "specialization of %1 not in a namespace enclosing %2">; +def ext_ms_template_spec_redecl_out_of_scope: ExtWarn< + "%select{class template|class template partial|variable template|" + "variable template partial|function template|member " + "function|static data member|member class|member enumeration}0 " + "specialization of %1 outside namespace enclosing %2 " + "is a Microsoft extension">, InGroup<Microsoft>; def err_template_spec_redecl_global_scope : Error< "%select{class template|class template partial|variable template|" "variable template partial|function template|member " @@ -3770,34 +3839,14 @@ def note_template_parameter_pack_here : Note< "previous %select{template type|non-type template|template template}0 " "parameter%select{| pack}1 declared here">; -def err_unexpanded_parameter_pack_0 : Error< - "%select{expression|base type|declaration type|data member type|bit-field " - "size|static assertion|fixed underlying type|enumerator value|" - "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type|partial specialization|" - "__if_exists name|__if_not_exists name|lambda|block}0 " - "contains an unexpanded parameter pack">; -def err_unexpanded_parameter_pack_1 : Error< +def err_unexpanded_parameter_pack : Error< "%select{expression|base type|declaration type|data member type|bit-field " "size|static assertion|fixed underlying type|enumerator value|" "using declaration|friend declaration|qualifier|initializer|default argument|" "non-type template parameter type|exception type|partial specialization|" - "__if_exists name|__if_not_exists name|lambda|block}0 " - "contains unexpanded parameter pack %1">; -def err_unexpanded_parameter_pack_2 : Error< - "%select{expression|base type|declaration type|data member type|bit-field " - "size|static assertion|fixed underlying type|enumerator value|" - "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type|partial specialization|" - "__if_exists name|__if_not_exists name|lambda|block}0 " - "contains unexpanded parameter packs %1 and %2">; -def err_unexpanded_parameter_pack_3_or_more : Error< - "%select{expression|base type|declaration type|data member type|bit-field " - "size|static assertion|fixed underlying type|enumerator value|" - "using declaration|friend declaration|qualifier|initializer|default argument|" - "non-type template parameter type|exception type|partial specialization|" - "__if_exists name|__if_not_exists name|lambda|block}0 " - "contains unexpanded parameter packs %1, %2, ...">; + "__if_exists name|__if_not_exists name|lambda|block}0 contains" + "%plural{0: an|:}1 unexpanded parameter pack" + "%plural{0:|1: %2|2:s %2 and %3|:s %2, %3, ...}1">; def err_pack_expansion_without_parameter_packs : Error< "pack expansion does not contain any unexpanded parameter packs">; @@ -3846,6 +3895,15 @@ def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neith def note_not_found_by_two_phase_lookup : Note<"%0 should be declared prior to the " "call site%select{| or in %2| or in an associated namespace of one of its arguments}1">; def err_undeclared_use : Error<"use of undeclared %0">; +def warn_partial_availability : Warning<"%0 is only available conditionally">, + InGroup<PartialAvailability>, DefaultIgnore; +def note_partial_availability_silence : Note< + "explicitly redeclare %0 to silence this warning">; +def warn_partial_message : Warning<"%0 is partial: %1">, + InGroup<PartialAvailability>, DefaultIgnore; +def warn_partial_fwdclass_message : Warning< + "%0 may be partial because the receiver type is unknown">, + InGroup<PartialAvailability>, DefaultIgnore; def warn_deprecated : Warning<"%0 is deprecated">, InGroup<DeprecatedDeclarations>; def warn_property_method_deprecated : @@ -3871,7 +3929,7 @@ def warn_unavailable_fwdclass_message : Warning< InGroup<UnavailableDeclarations>; def note_availability_specified_here : Note< "%0 has been explicitly marked " - "%select{unavailable|deleted|deprecated}1 here">; + "%select{unavailable|deleted|deprecated|partial}1 here">; def note_implicitly_deleted : Note< "explicitly defaulted function was implicitly deleted here">; def note_inherited_deleted_here : Note< @@ -3899,8 +3957,8 @@ def err_static_data_member_reinitialization : def err_redefinition : Error<"redefinition of %0">; def err_alias_after_tentative : Error<"alias definition of %0 after tentative definition">; -def err_tentative_after_alias : - Error<"tentative definition of %0 after alias definition">; +def err_alias_is_definition : + Error<"definition %0 cannot also be an alias">; def err_definition_of_implicitly_declared_member : Error< "definition of implicitly declared %select{default constructor|copy " "constructor|move constructor|copy assignment operator|move assignment " @@ -4063,6 +4121,9 @@ def ext_enum_too_large : ExtWarn< def ext_enumerator_increment_too_large : ExtWarn< "incremented enumerator value %0 is not representable in the " "largest integer type">, InGroup<EnumTooLarge>; +def warn_flag_enum_constant_out_of_range : Warning< + "enumeration value %0 is out of range of flags in enumeration type %1">, + InGroup<FlagEnum>; def warn_illegal_constant_array_size : Extension< "size of static array must be an integer constant expression">; @@ -4100,8 +4161,11 @@ def err_typecheck_negative_array_size : Error<"array size is negative">; def warn_typecheck_negative_array_new_size : Warning<"array size is negative">, // FIXME PR11644: ", will throw std::bad_array_new_length at runtime" InGroup<BadArrayNewLength>; -def warn_typecheck_function_qualifiers : Warning< - "qualifier on function type %0 has unspecified behavior">; +def warn_typecheck_function_qualifiers_ignored : Warning< + "'%0' qualifier on function type %1 has no effect">, + InGroup<IgnoredQualifiers>; +def warn_typecheck_function_qualifiers_unspecified : Warning< + "'%0' qualifier on function type %1 has unspecified behavior">; def warn_typecheck_reference_qualifiers : Warning< "'%0' qualifier on reference type %1 has no effect">, InGroup<IgnoredQualifiers>; @@ -4147,9 +4211,10 @@ def warn_missing_field_initializers : Warning< "missing field %0 initializer">, InGroup<MissingFieldInitializers>, DefaultIgnore; def warn_braces_around_scalar_init : Warning< - "braces around scalar initializer">; + "braces around scalar initializer">, InGroup<DiagGroup<"braced-scalar-init">>; def ext_many_braces_around_scalar_init : ExtWarn< - "too many braces around scalar initializer">; + "too many braces around scalar initializer">, + InGroup<DiagGroup<"many-braces-around-scalar-init">>; def ext_complex_component_init : Extension< "complex initialization specifying real and imaginary components " "is an extension">, InGroup<DiagGroup<"complex-component-init">>; @@ -4278,6 +4343,12 @@ def note_protected_by_cxx_try : Note< "jump bypasses initialization of try block">; def note_protected_by_cxx_catch : Note< "jump bypasses initialization of catch block">; +def note_protected_by_seh_try : Note< + "jump bypasses initialization of __try block">; +def note_protected_by_seh_except : Note< + "jump bypasses initialization of __except block">; +def note_protected_by_seh_finally : Note< + "jump bypasses initialization of __finally block">; def note_protected_by___block : Note< "jump bypasses setup of __block variable">; def note_protected_by_objc_ownership : Note< @@ -4310,6 +4381,12 @@ def note_exits_cxx_try : Note< "jump exits try block">; def note_exits_cxx_catch : Note< "jump exits catch block">; +def note_exits_seh_try : Note< + "jump exits __try block">; +def note_exits_seh_except : Note< + "jump exits __except block">; +def note_exits_seh_finally : Note< + "jump exits __finally block">; def note_exits_objc_autoreleasepool : Note< "jump exits autoreleasepool block">; def note_exits_objc_ownership : Note< @@ -4321,6 +4398,9 @@ def note_exits_block_captures_strong : Note< def note_exits_block_captures_weak : Note< "jump exits lifetime of block which weakly captures a variable">; +def err_func_returning_qualified_void : ExtWarn< + "function cannot return qualified void type %0">, + InGroup<DiagGroup<"qualified-void-return-type">>; def err_func_returning_array_function : Error< "function cannot return %select{array|function}0 type %1">; def err_field_declared_as_function : Error<"field %0 declared as a function">; @@ -4706,6 +4786,17 @@ def warn_self_move : Warning< "explicitly moving variable of type %0 to itself">, InGroup<SelfMove>, DefaultIgnore; +def warn_redundant_move_on_return : Warning< + "redundant move in return statement">, + InGroup<RedundantMove>, DefaultIgnore; +def warn_pessimizing_move_on_return : Warning< + "moving a local object in a return statement prevents copy elision">, + InGroup<PessimizingMove>, DefaultIgnore; +def warn_pessimizing_move_on_initialization : Warning< + "moving a temporary object prevents copy elision">, + InGroup<PessimizingMove>, DefaultIgnore; +def note_remove_move : Note<"remove std::move call here">; + def warn_string_plus_int : Warning< "adding %0 to a string does not append to the string">, InGroup<StringPlusInt>; @@ -4761,7 +4852,7 @@ def error_arc_weak_ivar_access : Error< def err_typecheck_member_reference_arrow : Error< "member reference type %0 is not a pointer">; def err_typecheck_member_reference_suggestion : Error< - "member reference type %0 is %select{a|not a}1 pointer; maybe you meant to use '%select{->|.}1'?">; + "member reference type %0 is %select{a|not a}1 pointer; did you mean to use '%select{->|.}1'?">; def note_typecheck_member_reference_suggestion : Note< "did you mean to use '.' instead?">; def note_member_reference_arrow_from_operator_arrow : Note< @@ -4849,6 +4940,8 @@ def err_ivar_reference_type : Error< "instance variables cannot be of reference type">; def err_typecheck_illegal_increment_decrement : Error< "cannot %select{decrement|increment}1 value of type %0">; +def err_typecheck_expect_int : Error< + "used type %0 where integer is required">; def err_typecheck_arithmetic_incomplete_type : Error< "arithmetic on a pointer to an incomplete type %0">; def err_typecheck_pointer_arith_function_type : Error< @@ -4937,7 +5030,7 @@ def err_typecheck_unary_expr : Error< "invalid argument type %0 to unary expression">; def err_typecheck_indirection_requires_pointer : Error< "indirection requires pointer operand (%0 invalid)">; -def ext_typecheck_indirection_through_void_pointer : Extension< +def ext_typecheck_indirection_through_void_pointer : ExtWarn< "ISO C++ does not allow indirection on operand of type %0">, InGroup<DiagGroup<"void-ptr-dereference">>; def warn_indirection_through_null : Warning< @@ -4987,7 +5080,23 @@ def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error< "%select{comparison between %diff{ ($ and $)|}0,1" "|arithmetic operation with operands of type %diff{ ($ and $)|}0,1}2" " which are pointers to non-overlapping address spaces">; -def err_typecheck_assign_const : Error<"read-only variable is not assignable">; + +def err_typecheck_assign_const : Error< + "%select{" + "cannot assign to return value because function %1 returns a const value|" + "cannot assign to variable %1 with const-qualified type %2|" + "cannot assign to %select{non-|}1static data member %2 " + "with const-qualified type %3|" + "cannot assign to non-static data member within const member function %1|" + "read-only variable is not assignable}0">; + +def note_typecheck_assign_const : Note< + "%select{" + "function %1 which returns const-qualified type %2 declared here|" + "variable %1 declared const here|" + "%select{non-|}1static data member %2 declared const here|" + "member function %q1 is declared const here}0">; + def warn_mixed_sign_comparison : Warning< "comparison of integers of different signs: %0 and %1">, InGroup<SignCompare>, DefaultIgnore; @@ -5012,6 +5121,9 @@ def warn_null_in_comparison_operation : Warning< "comparison between NULL and non-pointer " "%select{(%1 and NULL)|(NULL and %1)}0">, InGroup<NullArithmetic>; +def err_shift_rhs_only_vector : Error< + "requested shift is a vector of type %0 but the first operand is not a " + "vector (%1)">; def warn_logical_not_on_lhs_of_comparison : Warning< "logical not is only applied to the left hand side of this comparison">, @@ -5214,6 +5326,10 @@ def err_objc_object_catch : Error< "can't catch an Objective-C object by value">; def err_incomplete_type_objc_at_encode : Error< "'@encode' of incomplete type %0">; +def warn_objc_circular_container : Warning< + "adding '%0' to '%0' might cause circular dependency in container">, + InGroup<DiagGroup<"objc-circular-container">>; +def note_objc_circular_container_declared_here : Note<"'%0' declared here">; def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " @@ -5255,6 +5371,11 @@ def err_bad_cstyle_cast_overload : Error< def err_bad_cxx_cast_generic : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" "functional-style cast}0 from %1 to %2 is not allowed">; +def err_bad_cxx_cast_unrelated_class : Error< + "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" + "functional-style cast}0 from %1 to %2, which are not related by " + "inheritance, is not allowed">; +def note_type_incomplete : Note<"%0 is incomplete">; def err_bad_cxx_cast_rvalue : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" "functional-style cast}0 from rvalue to reference type %2">; @@ -5374,8 +5495,11 @@ def err_address_space_qualified_delete : Error< def err_default_init_const : Error< "default initialization of an object of const type %0" "%select{| without a user-provided default constructor}1">; -def note_add_initializer : Note< - "add an explicit initializer to initialize %0">; +def ext_default_init_const : ExtWarn< + "default initialization of an object of const type %0" + "%select{| without a user-provided default constructor}1 " + "is a Microsoft extension">, + InGroup<Microsoft>; def err_delete_operand : Error<"cannot delete expression of type %0">; def ext_delete_void_ptr_operand : ExtWarn< "cannot delete expression with pointer-to-'void' type %0">, @@ -5392,7 +5516,12 @@ def err_delete_explicit_conversion : Error< "conversion function">; def note_delete_conversion : Note<"conversion to pointer type %0">; def warn_delete_array_type : Warning< - "'delete' applied to a pointer-to-array type %0 treated as delete[]">; + "'delete' applied to a pointer-to-array type %0 treated as 'delete[]'">; +def warn_mismatched_delete_new : Warning< + "'delete%select{|[]}0' applied to a pointer that was allocated with " + "'new%select{[]|}0'; did you mean 'delete%select{[]|}0'?">, + InGroup<DiagGroup<"mismatched-new-delete">>; +def note_allocated_here : Note<"allocated with 'new%select{[]|}0' here">; def err_no_suitable_delete_member_function_found : Error< "no suitable member %0 in %1">; def err_ambiguous_suitable_delete_member_function_found : Error< @@ -5420,12 +5549,22 @@ def err_bad_memptr_lhs : Error< "left hand operand to %0 must be a %select{|pointer to }1class " "compatible with the right hand operand, but is %2">; def warn_exception_caught_by_earlier_handler : Warning< - "exception of type %0 will be caught by earlier handler">; + "exception of type %0 will be caught by earlier handler">, + InGroup<Exceptions>; def note_previous_exception_handler : Note<"for type %0">; def err_exceptions_disabled : Error< "cannot use '%0' with exceptions disabled">; def err_objc_exceptions_disabled : Error< "cannot use '%0' with Objective-C exceptions disabled">; +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 note_conflicting_try_here : Note< + "conflicting %0 here">; +def warn_jump_out_of_seh_finally : Warning< + "jump out of __finally block has undefined behavior">, + InGroup<DiagGroup<"jump-seh-finally">>; def warn_non_virtual_dtor : Warning< "%0 has virtual functions but non-virtual destructor">, InGroup<NonVirtualDtor>, DefaultIgnore; @@ -5467,6 +5606,12 @@ def err_conditional_ambiguous : Error< def err_conditional_ambiguous_ovl : Error< "conditional expression is ambiguous; %diff{$ and $|types}0,1 " "can be converted to several common types">; +def err_conditional_vector_size : Error< + "vector condition type %0 and result type %1 do not have the same number " + "of elements">; +def err_conditional_vector_element_size : Error< + "vector condition type %0 and result type %1 do not have elements of the " + "same size">; def err_throw_incomplete : Error< "cannot throw object of incomplete type %0">; @@ -5579,8 +5724,8 @@ def err_pseudo_dtor_type_mismatch : Error< def err_pseudo_dtor_call_with_args : Error< "call to pseudo-destructor cannot have any arguments">; def err_dtor_expr_without_call : Error< - "%select{destructor reference|pseudo-destructor expression}0 must be " - "called immediately with '()'">; + "reference to %select{destructor|pseudo-destructor}0 must be called" + "%select{|; did you mean to call it with no arguments?}1">; def err_pseudo_dtor_destructor_non_type : Error< "%0 does not refer to a type name in pseudo-destructor expression; expected " "the name of type %1">; @@ -5602,7 +5747,7 @@ def err_typecheck_deleted_function : Error< "invokes a deleted function">; def err_expected_class_or_namespace : Error<"%0 is not a class" - "%select{ or namespace|, namespace, or scoped enumeration}1">; + "%select{ or namespace|, namespace, or enumeration}1">; def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here " "because namespace %1 does not enclose namespace %2">; def err_invalid_declarator_global_scope : Error< @@ -6008,6 +6153,9 @@ def err_global_call_not_config : Error< def err_ref_bad_target : Error< "reference to %select{__device__|__global__|__host__|__host__ __device__}0 " "function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function">; +def warn_host_calls_from_host_device : Warning< + "calling __host__ function %0 from __host__ __device__ function %1 can lead to runtime errors">, + InGroup<CudaCompat>; def warn_non_pod_vararg_with_format_string : Warning< "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic " @@ -6049,12 +6197,14 @@ def err_typecheck_call_invalid_ordered_compare : Error< def err_typecheck_call_invalid_unary_fp : Error< "floating point classification requires argument of floating point type " "(passed in %0)">; +def err_typecheck_cond_expect_int_float : Error< + "used type %0 where integer or floating point type is required">; def err_typecheck_cond_expect_scalar : Error< "used type %0 where arithmetic or pointer type is required">; +def err_typecheck_cond_expect_nonfloat : Error< + "used type %0 where floating point type is not allowed">; def ext_typecheck_cond_one_void : Extension< "C99 forbids conditional expressions with only one void side">; -def err_typecheck_cond_expect_scalar_or_vector : Error< - "used type %0 where arithmetic, pointer, or vector type is required">; def err_typecheck_cast_to_incomplete : Error< "cast to incomplete type %0">; def ext_typecheck_cast_nonscalar : Extension< @@ -6349,6 +6499,9 @@ def err_base_class_has_flexible_array_member : Error< def err_incomplete_base_class : Error<"base class has incomplete type">; def err_duplicate_base_class : Error< "base class %0 specified more than once as a direct base class">; +def warn_inaccessible_base_class : Warning< + "direct base %0 is inaccessible due to ambiguity:%1">, + InGroup<DiagGroup<"inaccessible-base">>; // FIXME: better way to display derivation? Pass entire thing into diagclient? def err_ambiguous_derived_to_base_conv : Error< "ambiguous conversion from derived class %0 to base class %1:%2">; @@ -6570,6 +6723,10 @@ def warn_format_conversion_argument_type_mismatch : Warning< "format specifies type %0 but the argument has " "%select{type|underlying type}2 %1">, InGroup<Format>; +def warn_format_conversion_argument_type_mismatch_pedantic : Extension< + "format specifies type %0 but the argument has " + "%select{type|underlying type}2 %1">, + InGroup<FormatPedantic>; def warn_format_argument_needs_cast : Warning< "%select{values of type|enum values with underlying type}2 '%0' should not " "be used as format arguments; add an explicit cast to %1 instead">, @@ -6778,29 +6935,18 @@ def warn_case_empty_range : Warning<"empty case range specified">; def warn_missing_case_for_condition : Warning<"no case matching constant switch condition '%0'">; -def warn_def_missing_case1 : Warning< - "enumeration value %0 not explicitly handled in switch">, - InGroup<SwitchEnum>, DefaultIgnore; -def warn_def_missing_case2 : Warning< - "enumeration values %0 and %1 not explicitly handled in switch">, - InGroup<SwitchEnum>, DefaultIgnore; -def warn_def_missing_case3 : Warning< - "enumeration values %0, %1, and %2 not explicitly handled in switch">, - InGroup<SwitchEnum>, DefaultIgnore; -def warn_def_missing_cases : Warning< - "%0 enumeration values not explicitly handled in switch: %1, %2, %3...">, +def warn_def_missing_case : Warning<"%plural{" + "1:enumeration value %1 not explicitly handled in switch|" + "2:enumeration values %1 and %2 not explicitly handled in switch|" + "3:enumeration values %1, %2, and %3 not explicitly handled in switch|" + ":%0 enumeration values not explicitly handled in switch: %1, %2, %3...}0">, InGroup<SwitchEnum>, DefaultIgnore; -def warn_missing_case1 : Warning<"enumeration value %0 not handled in switch">, - InGroup<Switch>; -def warn_missing_case2 : Warning< - "enumeration values %0 and %1 not handled in switch">, - InGroup<Switch>; -def warn_missing_case3 : Warning< - "enumeration values %0, %1, and %2 not handled in switch">, - InGroup<Switch>; -def warn_missing_cases : Warning< - "%0 enumeration values not handled in switch: %1, %2, %3...">, +def warn_missing_case : Warning<"%plural{" + "1:enumeration value %1 not handled in switch|" + "2:enumeration values %1 and %2 not handled in switch|" + "3:enumeration values %1, %2, and %3 not handled in switch|" + ":%0 enumeration values not handled in switch: %1, %2, %3...}0">, InGroup<Switch>; def warn_unannotated_fallthrough : Warning< @@ -6971,6 +7117,12 @@ def note_neon_vector_initializer_non_portable_q : Note< "consider using vld1q_%0%1() to initialize a vector from memory, or " "vcombine_%0%1(vcreate_%0%1(), vcreate_%0%1()) to initialize from integer " "constants">; +def err_systemz_invalid_tabort_code : Error< + "invalid transaction abort code">; +def err_64_bit_builtin_32_bit_tgt : Error< + "this builtin is only available on 64-bit targets">; +def err_ppc_builtin_only_on_pwr7 : Error< + "this builtin is only valid on POWER7 or later CPUs">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; @@ -7043,8 +7195,8 @@ def ext_c99_array_usage : Extension< def err_c99_array_usage_cxx : Error< "%select{qualifier in |static |}0array size %select{||'[*] '}0is a C99 " "feature, not permitted in C++">; -def err_double_requires_fp64 : Error< - "use of type 'double' requires cl_khr_fp64 extension to be enabled">; + def err_type_requires_extension : Error< + "use of type %0 requires %1 extension to be enabled">; def err_int128_unsupported : Error< "__int128 is not supported on this target">; def err_nsconsumed_attribute_mismatch : Error< @@ -7169,9 +7321,14 @@ def err_filter_expression_integral : Error< def err_non_asm_stmt_in_naked_function : Error< "non-ASM statement in naked function is not supported">; +def err_asm_naked_this_ref : Error< + "'this' pointer references not allowed in naked functions">; def err_asm_naked_parm_ref : Error< "parameter references not allowed in naked functions">; +def ext_deprecated_attr_is_a_cxx14_extension : ExtWarn< + "use of the 'deprecated' attribute is a C++14 extension">, InGroup<CXX14>; + // OpenCL warnings and errors. def err_invalid_astype_of_different_size : Error< "invalid reinterpretation: sizes of %0 and %1 must match">; @@ -7261,6 +7418,8 @@ def err_omp_no_dsa_for_variable : Error< "variable %0 must have explicitly specified data sharing attributes">; def err_omp_wrong_dsa : Error< "%0 variable cannot be %1">; +def err_omp_variably_modified_type_not_supported : Error< + "arguments of OpenMP clause '%0' in '#pragma omp %2' directive cannot be of variably-modified type %1">; def note_omp_explicit_dsa : Note< "defined as %0">; def note_omp_predetermined_dsa : Note< @@ -7278,8 +7437,6 @@ def note_omp_implicit_dsa : Note< "implicitly determined as %0">; def err_omp_loop_var_dsa : Error< "loop iteration variable in the associated loop of 'omp %1' directive may not be %0, predetermined as %2">; -def err_omp_global_loop_var_dsa : Error< - "loop iteration variable in the associated loop of 'omp %1' directive may not be a variable with global storage without being explicitly marked as %0">; def err_omp_not_for : Error< "%select{statement after '#pragma omp %1' must be a for loop|" "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">; @@ -7368,7 +7525,7 @@ def note_omp_referenced : Note< def err_omp_reduction_in_task : Error< "reduction variables may not be accessed in an explicit task">; def err_omp_reduction_id_not_compatible : Error< - "variable of type %0 is not valid for specified reduction operation">; + "variable of type %0 is not valid for specified reduction operation: unable to provide default initialization value">; def err_omp_prohibited_region : Error< "region cannot be%select{| closely}0 nested inside '%1' region" "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|" @@ -7404,8 +7561,15 @@ def err_omp_atomic_write_not_expression_statement : Error< "the statement for 'atomic write' must be an expression statement of form 'x = expr;'," " where x is a lvalue expression with scalar type">; def err_omp_atomic_update_not_expression_statement : Error< - "the statement for 'atomic%select{| update}0' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x'," + "the statement for 'atomic update' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x'," + " where x is an l-value expression with scalar type">; +def err_omp_atomic_not_expression_statement : Error< + "the statement for 'atomic' must be an expression statement of form '++x;', '--x;', 'x++;', 'x--;', 'x binop= expr;', 'x = x binop expr' or 'x = expr binop x'," " where x is an l-value expression with scalar type">; +def note_omp_atomic_update: Note< + "%select{expected an expression statement|expected built-in binary or unary operator|expected unary decrement/increment operation|" + "expected expression of scalar type|expected assignment expression|expected built-in binary operator|" + "expected one of '+', '*', '-', '/', '&', '^', '%|', '<<', or '>>' built-in operations|expected in right hand side of expression}0">; def err_omp_atomic_capture_not_expression_statement : Error< "the statement for 'atomic capture' must be an expression statement of form 'v = ++x;', 'v = --x;', 'v = x++;', 'v = x--;', 'v = x binop= expr;', 'v = x = x binop expr' or 'v = x = expr binop x'," " where x and v are both l-value expressions with scalar type">; @@ -7414,6 +7578,8 @@ def err_omp_atomic_capture_not_compound_statement : Error< " '{v = x; x = x binop expr;}', '{v = x; x = expr binop x;}', '{x = x binop expr; v = x;}', '{x = expr binop x; v = x;}' or '{v = x; x = expr;}'," " '{v = x; x++;}', '{v = x; ++x;}', '{++x; v = x;}', '{x++; v = x;}', '{v = x; x--;}', '{v = x; --x;}', '{--x; v = x;}', '{x--; v = x;}'" " where x is an l-value expression with scalar type">; +def note_omp_atomic_capture: Note< + "%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">; def err_omp_atomic_several_clauses : Error< "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">; def note_omp_atomic_previous_clause : Note< @@ -7424,6 +7590,10 @@ def note_omp_nested_teams_construct_here : Note< "nested teams construct here">; def note_omp_nested_statement_here : Note< "%select{statement|directive}0 outside teams construct here">; +def err_omp_single_copyprivate_with_nowait : Error< + "the 'copyprivate' clause must not be used with the 'nowait' clause">; +def note_omp_nowait_clause_here : Note< + "'nowait' clause is here">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index a685db0..796027e 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/include/clang/Basic/DiagnosticSerializationKinds.td @@ -41,6 +41,8 @@ def err_pch_langopt_value_mismatch : Error< "%0 differs in PCH file vs. current file">; def err_pch_diagopt_mismatch : Error<"%0 is currently enabled, but was not in " "the PCH file">; +def err_pch_modulecache_mismatch : Error<"PCH was compiled with module cache " + "path '%0', but the path is currently '%1'">; def err_pch_version_too_old : Error< "PCH file uses an older PCH format that is no longer supported">; @@ -64,9 +66,6 @@ def err_imported_module_relocated : Error< def err_module_different_modmap : Error< "module '%0' %select{uses|does not use}1 additional module map '%2'" "%select{| not}1 used when the module was built">; -def warn_module_conflict : Warning< - "module '%0' conflicts with already-imported module '%1': %2">, - InGroup<ModuleConflict>; def err_pch_macro_def_undef : Error< "macro '%0' was %select{defined|undef'd}1 in the precompiled header but " diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index bd3f27a..37e19e1 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -73,11 +73,7 @@ class FileEntry { mutable std::unique_ptr<vfs::File> File; friend class FileManager; - void closeFile() const { - File.reset(); // rely on destructor to close File - } - - void operator=(const FileEntry &) LLVM_DELETED_FUNCTION; + void operator=(const FileEntry &) = delete; public: FileEntry() @@ -109,6 +105,10 @@ public: /// \brief Check whether the file is a named pipe (and thus can't be opened by /// the native FileManager methods). bool isNamedPipe() const { return IsNamedPipe; } + + void closeFile() const { + File.reset(); // rely on destructor to close File + } }; struct FileData; diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 1de9dd1..bc586e4 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -53,7 +53,8 @@ class IdentifierInfo { 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. - bool IsCXX11CompatKeyword : 1; // True if identifier is a keyword in C++11. + bool IsFutureCompatKeyword : 1; // True if identifier is a keyword in a + // newer Standard or proposed Standard. bool IsPoisoned : 1; // True if identifier is poisoned. bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. bool NeedsHandleIdentifier : 1; // See "RecomputeNeedsHandleIdentifier". @@ -73,8 +74,8 @@ class IdentifierInfo { void *FETokenInfo; // Managed by the language front-end. llvm::StringMapEntry<IdentifierInfo*> *Entry; - IdentifierInfo(const IdentifierInfo&) LLVM_DELETED_FUNCTION; - void operator=(const IdentifierInfo&) LLVM_DELETED_FUNCTION; + IdentifierInfo(const IdentifierInfo&) = delete; + void operator=(const IdentifierInfo&) = delete; friend class IdentifierTable; @@ -124,6 +125,7 @@ public: } /// \brief Return true if this identifier is \#defined to some other value. + /// \note The current definition may be in a module and not currently visible. bool hasMacroDefinition() const { return HasMacro; } @@ -212,13 +214,14 @@ public: RecomputeNeedsHandleIdentifier(); } - /// is/setIsCXX11CompatKeyword - Initialize information about whether or not - /// this language token is a keyword in C++11. This controls compatibility - /// warnings, and is only true when not parsing C++11. Once a compatibility - /// problem has been diagnosed with this keyword, the flag will be cleared. - bool isCXX11CompatKeyword() const { return IsCXX11CompatKeyword; } - void setIsCXX11CompatKeyword(bool Val) { - IsCXX11CompatKeyword = Val; + /// is/setIsFutureCompatKeyword - Initialize information about whether or not + /// this language token is a keyword in a newer or proposed Standard. This + /// controls compatibility warnings, and is only true when not parsing the + /// corresponding Standard. Once a compatibility problem has been diagnosed + /// with this keyword, the flag will be cleared. + bool isFutureCompatKeyword() const { return IsFutureCompatKeyword; } + void setIsFutureCompatKeyword(bool Val) { + IsFutureCompatKeyword = Val; if (Val) NeedsHandleIdentifier = 1; else @@ -308,7 +311,12 @@ public: else RecomputeNeedsHandleIdentifier(); } - + + /// \brief Provide less than operator for lexicographical sorting. + bool operator<(const IdentifierInfo &RHS) const { + return getName() < RHS.getName(); + } + private: /// The Preprocessor::HandleIdentifier does several special (but rare) /// things to identifiers of various sorts. For example, it changes the @@ -319,7 +327,7 @@ private: void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | - isExtensionToken() | isCXX11CompatKeyword() || isOutOfDate() || + isExtensionToken() | isFutureCompatKeyword() || isOutOfDate() || isModulesImport()); } }; @@ -356,8 +364,8 @@ public: /// actual functionality. class IdentifierIterator { private: - IdentifierIterator(const IdentifierIterator &) LLVM_DELETED_FUNCTION; - void operator=(const IdentifierIterator &) LLVM_DELETED_FUNCTION; + IdentifierIterator(const IdentifierIterator &) = delete; + void operator=(const IdentifierIterator &) = delete; protected: IdentifierIterator() { } @@ -727,8 +735,8 @@ public: /// multi-keyword caching. class SelectorTable { void *Impl; // Actually a SelectorTableImpl - SelectorTable(const SelectorTable &) LLVM_DELETED_FUNCTION; - void operator=(const SelectorTable &) LLVM_DELETED_FUNCTION; + SelectorTable(const SelectorTable &) = delete; + void operator=(const SelectorTable &) = delete; public: SelectorTable(); ~SelectorTable(); diff --git a/include/clang/Basic/LLVM.h b/include/clang/Basic/LLVM.h index 3e01d25..0e6ff92 100644 --- a/include/clang/Basic/LLVM.h +++ b/include/clang/Basic/LLVM.h @@ -45,6 +45,7 @@ namespace llvm { class RefCountedBaseVPTR; class raw_ostream; + class raw_pwrite_stream; // TODO: DenseMap, ... } @@ -76,6 +77,7 @@ namespace clang { using llvm::RefCountedBaseVPTR; using llvm::raw_ostream; + using llvm::raw_pwrite_stream; } // end namespace clang. #endif diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index cf9638d..95d3f06 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -84,6 +84,7 @@ BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0, "Encoding extended block type signature") BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1, "Objective-C related result type inference") +LANGOPT(AppExt , 1, 0, "Objective-C App Extension") LANGOPT(Trigraphs , 1, 0,"trigraphs") LANGOPT(LineComment , 1, 0, "'//' comments") LANGOPT(Bool , 1, 0, "bool, true, and false keywords") @@ -114,6 +115,7 @@ LANGOPT(MSBitfields , 1, 0, "Microsoft-compatible structure layout") LANGOPT(Freestanding, 1, 0, "freestanding implementation") LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") +LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly") BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") @@ -122,11 +124,13 @@ BENIGN_LANGOPT(EmitAllDecls , 1, 0, "support for emitting all declarations" LANGOPT(MathErrno , 1, 1, "errno support for math functions") BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time") LANGOPT(Modules , 1, 0, "modules extension to C") -LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") +COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references") -LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules") +COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules") LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery") BENIGN_LANGOPT(ModulesImplicitMaps, 1, 1, "use files called module.modulemap implicitly as module maps") +BENIGN_LANGOPT(ImplicitModules, 1, 1, "build modules that are not specified via -fmodule-file") +COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility") COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") @@ -158,9 +162,12 @@ LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns") LANGOPT(CUDA , 1, 0, "CUDA") LANGOPT(OpenMP , 1, 0, "OpenMP support") 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.)") LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions") +LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts") BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") BENIGN_LANGOPT(DumpRecordLayouts , 1, 0, "dumping the layout of IRgen'd records") BENIGN_LANGOPT(DumpRecordLayoutsSimple , 1, 0, "dumping the layout of IRgen'd records in a simple form") diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 5ac96c5..84836eb 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -21,6 +21,7 @@ #include "clang/Basic/Sanitizers.h" #include "clang/Basic/Visibility.h" #include <string> +#include <vector> namespace clang { @@ -66,13 +67,20 @@ public: enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; + enum MSVCMajorVersion { + MSVC2010 = 16, + MSVC2012 = 17, + MSVC2013 = 18, + MSVC2015 = 19 + }; + public: /// \brief Set of enabled sanitizers. SanitizerSet Sanitize; - /// \brief Path to blacklist file specifying which objects + /// \brief Paths to blacklist files specifying which objects /// (files, functions, variables) should not be instrumented. - std::string SanitizerBlacklistFile; + std::vector<std::string> SanitizerBlacklistFiles; clang::ObjCRuntime ObjCRuntime; @@ -92,6 +100,10 @@ public: /// treat this as the CurrentModule. std::string ImplementationOfModule; + /// \brief The names of any features to enable in module 'requires' decls + /// in addition to the hard-coded list in Module.cpp and the target features. + std::vector<std::string> ModuleFeatures; + /// \brief Options for parsing comments. CommentOptions CommentOpts; @@ -113,6 +125,10 @@ public: !ObjCSubscriptingLegacyRuntime; } + bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { + return MSCompatibilityVersion >= MajorVersion * 10000000U; + } + /// \brief Reset all of the options that are not considered when building a /// module. void resetNonModularOptions(); diff --git a/include/clang/Basic/Linkage.h b/include/clang/Basic/Linkage.h index f3b4769..8b15c8e 100644 --- a/include/clang/Basic/Linkage.h +++ b/include/clang/Basic/Linkage.h @@ -14,6 +14,10 @@ #ifndef LLVM_CLANG_BASIC_LINKAGE_H #define LLVM_CLANG_BASIC_LINKAGE_H +#include <assert.h> +#include <stdint.h> +#include <utility> + namespace clang { /// \brief Describes the different kinds of linkage diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h index e3953a4..7470610 100644 --- a/include/clang/Basic/Module.h +++ b/include/clang/Basic/Module.h @@ -16,11 +16,13 @@ #define LLVM_CLANG_BASIC_MODULE_H #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -63,6 +65,9 @@ public: /// \brief The umbrella header or directory. llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella; + + /// \brief The name of the umbrella entry, as written in the module map. + std::string UmbrellaAsWritten; private: /// \brief The submodules of this module, indexed by name. @@ -85,6 +90,9 @@ private: /// \brief Cache of modules visible to lookup in this module. mutable llvm::DenseSet<const Module*> VisibleModulesCache; + /// The ID used when referencing this module within a VisibleModuleSet. + unsigned VisibilityID; + public: enum HeaderKind { HK_Normal, @@ -100,6 +108,17 @@ public: struct Header { std::string NameAsWritten; const FileEntry *Entry; + + explicit operator bool() { return Entry; } + }; + + /// \brief Information about a directory name as found in the module map + /// file. + struct DirectoryName { + std::string NameAsWritten; + const DirectoryEntry *Entry; + + explicit operator bool() { return Entry; } }; /// \brief The headers that are part of this module. @@ -182,10 +201,7 @@ public: /// particular module. enum NameVisibilityKind { /// \brief All of the names in this module are hidden. - /// Hidden, - /// \brief Only the macro names in this module are visible. - MacrosVisible, /// \brief All of the names in this module are visible. AllVisible }; @@ -193,15 +209,12 @@ public: /// \brief The visibility of names within this particular module. NameVisibilityKind NameVisibility; - /// \brief The location at which macros within this module became visible. - SourceLocation MacroVisibilityLoc; - /// \brief The location of the inferred submodule. SourceLocation InferredSubmoduleLoc; /// \brief The set of modules imported by this module, and on which this /// module depends. - SmallVector<Module *, 2> Imports; + llvm::SmallSetVector<Module *, 2> Imports; /// \brief Describes an exported module. /// @@ -288,7 +301,7 @@ public: /// \brief Construct a new module or submodule. Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, - bool IsFramework, bool IsExplicit); + bool IsFramework, bool IsExplicit, unsigned VisibilityID); ~Module(); @@ -371,12 +384,14 @@ public: /// \brief Retrieve the directory for which this module serves as the /// umbrella. - const DirectoryEntry *getUmbrellaDir() const; + DirectoryName getUmbrellaDir() const; /// \brief Retrieve the header that serves as the umbrella header for this /// module. - const FileEntry *getUmbrellaHeader() const { - return Umbrella.dyn_cast<const FileEntry *>(); + Header getUmbrellaHeader() const { + if (auto *E = Umbrella.dyn_cast<const FileEntry *>()) + return Header{UmbrellaAsWritten, E}; + return Header{}; } /// \brief Determine whether this module has an umbrella directory that is @@ -399,6 +414,10 @@ public: /// \brief The top-level headers associated with this module. ArrayRef<const FileEntry *> getTopHeaders(FileManager &FileMgr); + /// \brief Determine whether this module has declared its intention to + /// directly use another module. + bool directlyUses(const Module *Requested) const; + /// \brief Add the given feature requirement to the list of features /// required by this module. /// @@ -437,6 +456,8 @@ public: return VisibleModulesCache.count(M); } + unsigned getVisibilityID() const { return VisibilityID; } + typedef std::vector<Module *>::iterator submodule_iterator; typedef std::vector<Module *>::const_iterator submodule_const_iterator; @@ -466,6 +487,65 @@ private: void buildVisibleModulesCache() const; }; +/// \brief A set of visible modules. +class VisibleModuleSet { +public: + VisibleModuleSet() : Generation(0) {} + VisibleModuleSet(VisibleModuleSet &&O) + : ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) { + O.ImportLocs.clear(); + ++O.Generation; + } + + /// Move from another visible modules set. Guaranteed to leave the source + /// empty and bump the generation on both. + VisibleModuleSet &operator=(VisibleModuleSet &&O) { + ImportLocs = std::move(O.ImportLocs); + O.ImportLocs.clear(); + ++O.Generation; + ++Generation; + return *this; + } + + /// \brief Get the current visibility generation. Incremented each time the + /// set of visible modules changes in any way. + unsigned getGeneration() const { return Generation; } + + /// \brief Determine whether a module is visible. + bool isVisible(const Module *M) const { + return getImportLoc(M).isValid(); + } + + /// \brief Get the location at which the import of a module was triggered. + SourceLocation getImportLoc(const Module *M) const { + return M->getVisibilityID() < ImportLocs.size() + ? ImportLocs[M->getVisibilityID()] + : SourceLocation(); + } + + /// \brief A callback to call when a module is made visible (directly or + /// indirectly) by a call to \ref setVisible. + typedef llvm::function_ref<void(Module *M)> VisibleCallback; + /// \brief A callback to call when a module conflict is found. \p Path + /// consists of a sequence of modules from the conflicting module to the one + /// made visible, where each was exported by the next. + typedef llvm::function_ref<void(ArrayRef<Module *> Path, + Module *Conflict, StringRef Message)> + ConflictCallback; + /// \brief Make a specific module visible. + void setVisible(Module *M, SourceLocation Loc, + VisibleCallback Vis = [](Module *) {}, + ConflictCallback Cb = [](ArrayRef<Module *>, Module *, + StringRef) {}); + +private: + /// Import locations for each visible module. Indexed by the module's + /// VisibilityID. + std::vector<SourceLocation> ImportLocs; + /// Visibility generation, bumped every time the visibility state changes. + unsigned Generation; +}; + } // end namespace clang diff --git a/include/clang/Basic/PlistSupport.h b/include/clang/Basic/PlistSupport.h index 081f22d..84dd291 100644 --- a/include/clang/Basic/PlistSupport.h +++ b/include/clang/Basic/PlistSupport.h @@ -12,7 +12,6 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" -#include "clang/Lex/Lexer.h" #include "llvm/Support/raw_ostream.h" namespace clang { @@ -89,31 +88,29 @@ inline raw_ostream &EmitString(raw_ostream &o, StringRef s) { } inline void EmitLocation(raw_ostream &o, const SourceManager &SM, - const LangOptions &LangOpts, SourceLocation L, - const FIDMap &FM, unsigned indent, - bool extend = false) { - FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM)); + SourceLocation L, const FIDMap &FM, unsigned indent) { + if (L.isInvalid()) return; - // Add in the length of the token, so that we cover multi-char tokens. - unsigned offset = - extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0; + FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager &>(SM)); Indent(o, indent) << "<dict>\n"; Indent(o, indent) << " <key>line</key>"; EmitInteger(o, Loc.getExpansionLineNumber()) << '\n'; Indent(o, indent) << " <key>col</key>"; - EmitInteger(o, Loc.getExpansionColumnNumber() + offset) << '\n'; + EmitInteger(o, Loc.getExpansionColumnNumber()) << '\n'; Indent(o, indent) << " <key>file</key>"; EmitInteger(o, GetFID(FM, SM, Loc)) << '\n'; Indent(o, indent) << "</dict>\n"; } inline void EmitRange(raw_ostream &o, const SourceManager &SM, - const LangOptions &LangOpts, CharSourceRange R, - const FIDMap &FM, unsigned indent) { + CharSourceRange R, const FIDMap &FM, unsigned indent) { + if (R.isInvalid()) return; + + assert(R.isCharRange() && "cannot handle a token range"); Indent(o, indent) << "<array>\n"; - EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent + 1); - EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent + 1, R.isTokenRange()); + EmitLocation(o, SM, R.getBegin(), FM, indent + 1); + EmitLocation(o, SM, R.getEnd(), FM, indent + 1); Indent(o, indent) << "</array>\n"; } } diff --git a/include/clang/Basic/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h index 2ce268a..e651e18 100644 --- a/include/clang/Basic/SanitizerBlacklist.h +++ b/include/clang/Basic/SanitizerBlacklist.h @@ -28,7 +28,8 @@ class SanitizerBlacklist { SourceManager &SM; public: - SanitizerBlacklist(StringRef BlacklistPath, SourceManager &SM); + SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths, + SourceManager &SM); bool isBlacklistedGlobal(StringRef GlobalName, StringRef Category = StringRef()) const; bool isBlacklistedType(StringRef MangledTypeName, diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def index 91a1ef4..65ababd 100644 --- a/include/clang/Basic/Sanitizers.def +++ b/include/clang/Basic/Sanitizers.def @@ -64,7 +64,9 @@ SANITIZER("null", Null) SANITIZER("object-size", ObjectSize) SANITIZER("return", Return) SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute) -SANITIZER("shift", Shift) +SANITIZER("shift-base", ShiftBase) +SANITIZER("shift-exponent", ShiftExponent) +SANITIZER_GROUP("shift", Shift, ShiftBase | ShiftExponent) SANITIZER("signed-integer-overflow", SignedIntegerOverflow) SANITIZER("unreachable", Unreachable) SANITIZER("vla-bound", VLABound) @@ -76,18 +78,17 @@ SANITIZER("unsigned-integer-overflow", UnsignedIntegerOverflow) // DataFlowSanitizer SANITIZER("dataflow", DataFlow) -// -fsanitize=undefined includes all the sanitizers which have low overhead, no -// ABI or address space layout implications, and only catch undefined behavior. -SANITIZER_GROUP("undefined", Undefined, - Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow | - FloatDivideByZero | Function | IntegerDivideByZero | - NonnullAttribute | Null | ObjectSize | Return | - ReturnsNonnullAttribute | Shift | SignedIntegerOverflow | - Unreachable | VLABound | Vptr) - -// -fsanitize=undefined-trap includes -// all sanitizers included by -fsanitize=undefined, except those that require -// runtime support. This group is generally used in conjunction with the +// Control Flow Integrity +SANITIZER("cfi-cast-strict", CFICastStrict) +SANITIZER("cfi-derived-cast", CFIDerivedCast) +SANITIZER("cfi-unrelated-cast", CFIUnrelatedCast) +SANITIZER("cfi-nvcall", CFINVCall) +SANITIZER("cfi-vcall", CFIVCall) +SANITIZER_GROUP("cfi", CFI, + CFIDerivedCast | CFIUnrelatedCast | CFINVCall | CFIVCall) + +// -fsanitize=undefined-trap includes sanitizers from -fsanitize=undefined +// that can be used without runtime support, generally by providing extra // -fsanitize-undefined-trap-on-error flag. SANITIZER_GROUP("undefined-trap", UndefinedTrap, Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow | @@ -95,6 +96,10 @@ SANITIZER_GROUP("undefined-trap", UndefinedTrap, Null | ObjectSize | Return | ReturnsNonnullAttribute | Shift | SignedIntegerOverflow | Unreachable | VLABound) +// -fsanitize=undefined includes all the sanitizers which have low overhead, no +// ABI or address space layout implications, and only catch undefined behavior. +SANITIZER_GROUP("undefined", Undefined, UndefinedTrap | Function | Vptr) + SANITIZER_GROUP("integer", Integer, SignedIntegerOverflow | UnsignedIntegerOverflow | Shift | IntegerDivideByZero) @@ -104,7 +109,7 @@ SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds) // Magic group, containing all sanitizers. For example, "-fno-sanitize=all" // can be used to disable all the sanitizers. -SANITIZER_GROUP("all", All, ~0) +SANITIZER_GROUP("all", All, ~0ULL) #undef SANITIZER #undef SANITIZER_GROUP diff --git a/include/clang/Basic/Sanitizers.h b/include/clang/Basic/Sanitizers.h index 868b331..3b1797e 100644 --- a/include/clang/Basic/Sanitizers.h +++ b/include/clang/Basic/Sanitizers.h @@ -15,33 +15,64 @@ #ifndef LLVM_CLANG_BASIC_SANITIZERS_H #define LLVM_CLANG_BASIC_SANITIZERS_H +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" + +#include <stdint.h> + namespace clang { -enum class SanitizerKind { -#define SANITIZER(NAME, ID) ID, +typedef uint64_t SanitizerMask; + +namespace SanitizerKind { + +// Assign ordinals to possible values of -fsanitize= flag, which we will use as +// bit positions. +enum SanitizerOrdinal : uint64_t { +#define SANITIZER(NAME, ID) SO_##ID, +#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group, #include "clang/Basic/Sanitizers.def" - Unknown + SO_Count }; -class SanitizerSet { - /// \brief Bitmask of enabled sanitizers. - unsigned Kinds; -public: +// Define the set of sanitizer kinds, as well as the set of sanitizers each +// sanitizer group expands into. +#define SANITIZER(NAME, ID) \ + const SanitizerMask ID = 1ULL << SO_##ID; +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + const SanitizerMask ID = ALIAS; \ + const SanitizerMask ID##Group = 1ULL << SO_##ID##Group; +#include "clang/Basic/Sanitizers.def" + +} + +struct SanitizerSet { SanitizerSet(); - /// \brief Check if a certain sanitizer is enabled. - bool has(SanitizerKind K) const; + /// \brief Check if a certain (single) sanitizer is enabled. + bool has(SanitizerMask K) const; - /// \brief Enable or disable a certain sanitizer. - void set(SanitizerKind K, bool Value); + /// \brief Enable or disable a certain (single) sanitizer. + void set(SanitizerMask K, bool Value); /// \brief Disable all sanitizers. void clear(); /// \brief Returns true if at least one sanitizer is enabled. bool empty() const; + + /// \brief Bitmask of enabled sanitizers. + SanitizerMask Mask; }; +/// Parse a single value from a -fsanitize= or -fno-sanitize= value list. +/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known. +SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups); + +/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers +/// this group enables. +SanitizerMask expandSanitizerGroups(SanitizerMask Kinds); + } // end namespace clang #endif diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 717258d..3aea5ea 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -82,7 +82,7 @@ namespace SrcMgr { /// \brief One instance of this struct is kept for every file loaded or used. /// /// This object owns the MemoryBuffer object. - class ContentCache { + class LLVM_ALIGNAS(8) ContentCache { enum CCFlags { /// \brief Whether the buffer is invalid. InvalidFlag = 0x01, @@ -90,15 +90,6 @@ namespace SrcMgr { DoNotFreeFlag = 0x02 }; - // Note that the first member of this class is an aligned character buffer - // to ensure that this class has an alignment of 8 bytes. This wastes - // 8 bytes for every ContentCache object, but each of these corresponds to - // a file loaded into memory, so the 8 bytes doesn't seem terribly - // important. It is quite awkward to fit this aligner into any other part - // of the class due to the lack of portable ways to combine it with other - // members. - llvm::AlignedCharArray<8, 1> NonceAligner; - /// \brief The actual buffer containing the characters from the input /// file. /// @@ -142,14 +133,9 @@ namespace SrcMgr { /// \brief True if this content cache was initially created for a source /// file considered as a system one. unsigned IsSystemFile : 1; - - ContentCache(const FileEntry *Ent = nullptr) - : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(Ent), - SourceLineCache(nullptr), NumLines(0), BufferOverridden(false), - IsSystemFile(false) { - (void)NonceAligner; // Silence warnings about unused member. - } - + + ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {} + ContentCache(const FileEntry *Ent, const FileEntry *contentEnt) : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt), SourceLineCache(nullptr), NumLines(0), BufferOverridden(false), @@ -231,7 +217,7 @@ namespace SrcMgr { private: // Disable assignments. - ContentCache &operator=(const ContentCache& RHS) LLVM_DELETED_FUNCTION; + ContentCache &operator=(const ContentCache& RHS) = delete; }; // Assert that the \c ContentCache objects will always be 8-byte aligned so @@ -705,8 +691,8 @@ class SourceManager : public RefCountedBase<SourceManager> { SmallVector<std::pair<std::string, FullSourceLoc>, 2> StoredModuleBuildStack; // SourceManager doesn't support copy construction. - explicit SourceManager(const SourceManager&) LLVM_DELETED_FUNCTION; - void operator=(const SourceManager&) LLVM_DELETED_FUNCTION; + explicit SourceManager(const SourceManager&) = delete; + void operator=(const SourceManager&) = delete; public: SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, bool UserFilesAreVolatile = false); @@ -1057,10 +1043,16 @@ public: getImmediateExpansionRange(SourceLocation Loc) const; /// \brief Given a SourceLocation object, return the range of - /// tokens covered by the expansion the ultimate file. + /// tokens covered by the expansion in the ultimate file. std::pair<SourceLocation,SourceLocation> getExpansionRange(SourceLocation Loc) const; + /// \brief Given a SourceRange object, return the range of + /// tokens covered by the expansion in the ultimate file. + SourceRange getExpansionRange(SourceRange Range) const { + return SourceRange(getExpansionRange(Range.getBegin()).first, + getExpansionRange(Range.getEnd()).second); + } /// \brief Given a SourceLocation object, return the spelling /// location referenced by the ID. diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h index f31d604..27dea9f 100644 --- a/include/clang/Basic/SourceManagerInternals.h +++ b/include/clang/Basic/SourceManagerInternals.h @@ -88,17 +88,12 @@ class LineTableInfo { /// at which they occur in the file). std::map<FileID, std::vector<LineEntry> > LineEntries; public: - LineTableInfo() { - } - void clear() { FilenameIDs.clear(); FilenamesByID.clear(); LineEntries.clear(); } - ~LineTableInfo() {} - unsigned getLineTableFilenameID(StringRef Str); const char *getFilename(unsigned ID) const { assert(ID < FilenamesByID.size() && "Invalid FilenameID"); diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index a968d00..7569c16 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -209,8 +209,9 @@ namespace clang { CC_X86_64SysV, // __attribute__((sysv_abi)) CC_AAPCS, // __attribute__((pcs("aapcs"))) CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp"))) - CC_PnaclCall, // __attribute__((pnaclcall)) - CC_IntelOclBicc // __attribute__((intel_ocl_bicc)) + CC_IntelOclBicc, // __attribute__((intel_ocl_bicc)) + CC_SpirFunction, // default for OpenCL functions on SPIR target + CC_SpirKernel // inferred for OpenCL kernels on SPIR target }; /// \brief Checks whether the given calling convention supports variadic @@ -222,6 +223,8 @@ namespace clang { case CC_X86ThisCall: case CC_X86Pascal: case CC_X86VectorCall: + case CC_SpirFunction: + case CC_SpirKernel: return false; default: return true; diff --git a/include/clang/Basic/TargetBuiltins.h b/include/clang/Basic/TargetBuiltins.h index e112c65..eece4e8 100644 --- a/include/clang/Basic/TargetBuiltins.h +++ b/include/clang/Basic/TargetBuiltins.h @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_BASIC_TARGETBUILTINS_H #define LLVM_CLANG_BASIC_TARGETBUILTINS_H +#include <stdint.h> #include "clang/Basic/Builtins.h" #undef PPC @@ -175,6 +176,15 @@ namespace clang { }; } + /// \brief SystemZ builtins + namespace SystemZ { + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsSystemZ.def" + LastTSBuiltin + }; + } } // end namespace clang. #endif diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 7a6462c..8406205 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -66,6 +66,7 @@ protected: unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; unsigned char SuitableAlign; + unsigned char DefaultAlignForAttributeAligned; unsigned char MinGlobalAlign; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short MaxVectorAlign; @@ -314,6 +315,12 @@ public: /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } + /// \brief Return the default alignment for __attribute__((aligned)) on + /// this target, to be used if no alignment value is specified. + unsigned getDefaultAlignForAttributeAligned() const { + return DefaultAlignForAttributeAligned; + } + /// getMinGlobalAlign - Return the minimum alignment of a global variable, /// unless its alignment is explicitly reduced via attributes. unsigned getMinGlobalAlign() const { return MinGlobalAlign; } @@ -638,6 +645,12 @@ public: return std::string(1, *Constraint); } + /// \brief Returns true if NaN encoding is IEEE 754-2008. + /// Only MIPS allows a different encoding. + virtual bool isNan2008() const { + return true; + } + /// \brief Returns a string of target-specific clobbers, in LLVM format. virtual const char *getClobbers() const = 0; @@ -836,7 +849,8 @@ public: enum CallingConvCheckResult { CCCR_OK, - CCCR_Warning + CCCR_Warning, + CCCR_Ignore, }; /// \brief Determines whether a given calling convention is valid for the diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 3319d4e..28aafca 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -10,7 +10,7 @@ // This file defines the TokenKind database. This includes normal tokens like // tok::ampamp (corresponding to the && token) as well as keywords for various // languages. Users of this file must optionally #define the TOK, KEYWORD, -// ALIAS, or PPKEYWORD macros to make use of this file. +// CXX11_KEYWORD, ALIAS, or PPKEYWORD macros to make use of this file. // //===----------------------------------------------------------------------===// @@ -23,6 +23,9 @@ #ifndef KEYWORD #define KEYWORD(X,Y) TOK(kw_ ## X) #endif +#ifndef CXX11_KEYWORD +#define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y)) +#endif #ifndef TYPE_TRAIT #define TYPE_TRAIT(N,I,K) KEYWORD(I,K) #endif @@ -225,9 +228,10 @@ PUNCTUATOR(greatergreatergreater, ">>>") // KEYCXX11 - This is a C++ keyword introduced to C++ in C++11 // KEYGNU - This is a keyword if GNU extensions are enabled // KEYMS - This is a keyword if Microsoft extensions are enabled -// KEYNOMS - This is a keyword that must never be enabled under -// Microsoft mode +// KEYNOMS18 - This is a keyword that must never be enabled under +// MSVC <= v18. // KEYOPENCL - This is a keyword in OpenCL +// KEYNOOPENCL - This is a keyword that is not supported in OpenCL // KEYALTIVEC - This is a keyword in AltiVec // KEYBORLAND - This is a keyword if Borland extensions are enabled // BOOLSUPPORT - This is a keyword if 'bool' is a built-in type @@ -270,7 +274,7 @@ KEYWORD(volatile , KEYALL) KEYWORD(while , KEYALL) KEYWORD(_Alignas , KEYALL) KEYWORD(_Alignof , KEYALL) -KEYWORD(_Atomic , KEYALL|KEYNOMS) +KEYWORD(_Atomic , KEYALL|KEYNOMS18|KEYNOOPENCL) KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) @@ -329,16 +333,16 @@ CXX_KEYWORD_OPERATOR(xor , caret) CXX_KEYWORD_OPERATOR(xor_eq , caretequal) // C++11 keywords -KEYWORD(alignas , KEYCXX11) -KEYWORD(alignof , KEYCXX11) -KEYWORD(char16_t , KEYCXX11|KEYNOMS) -KEYWORD(char32_t , KEYCXX11|KEYNOMS) -KEYWORD(constexpr , KEYCXX11) -KEYWORD(decltype , KEYCXX11) -KEYWORD(noexcept , KEYCXX11) -KEYWORD(nullptr , KEYCXX11) -KEYWORD(static_assert , KEYCXX11) -KEYWORD(thread_local , KEYCXX11) +CXX11_KEYWORD(alignas , 0) +CXX11_KEYWORD(alignof , 0) +CXX11_KEYWORD(char16_t , KEYNOMS18) +CXX11_KEYWORD(char32_t , KEYNOMS18) +CXX11_KEYWORD(constexpr , 0) +CXX11_KEYWORD(decltype , 0) +CXX11_KEYWORD(noexcept , 0) +CXX11_KEYWORD(nullptr , 0) +CXX11_KEYWORD(static_assert , 0) +CXX11_KEYWORD(thread_local , 0) // GNU Extensions (in impl-reserved namespace) KEYWORD(_Decimal32 , KEYALL) @@ -454,7 +458,7 @@ KEYWORD(__private_extern__ , KEYALL) KEYWORD(__module_private__ , KEYALL) // Microsoft Extension. -KEYWORD(__declspec , KEYALL) +KEYWORD(__declspec , KEYMS|KEYBORLAND) KEYWORD(__cdecl , KEYALL) KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) @@ -734,6 +738,7 @@ ANNOTATION(module_end) #undef TYPE_TRAIT_2 #undef TYPE_TRAIT_1 #undef TYPE_TRAIT +#undef CXX11_KEYWORD #undef KEYWORD #undef PUNCTUATOR #undef TOK diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h index 77fd947..784f3f3 100644 --- a/include/clang/Basic/VersionTuple.h +++ b/include/clang/Basic/VersionTuple.h @@ -22,40 +22,48 @@ namespace clang { -/// \brief Represents a version number in the form major[.minor[.subminor]]. +/// \brief Represents a version number in the form major[.minor[.subminor[.build]]]. class VersionTuple { unsigned Major : 31; unsigned Minor : 31; unsigned Subminor : 31; + unsigned Build : 31; unsigned HasMinor : 1; unsigned HasSubminor : 1; + unsigned HasBuild : 1; unsigned UsesUnderscores : 1; public: - VersionTuple() - : Major(0), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false), - UsesUnderscores(false) { } + VersionTuple() + : Major(0), Minor(0), Subminor(0), Build(0), HasMinor(false), + HasSubminor(false), HasBuild(false), UsesUnderscores(false) {} explicit VersionTuple(unsigned Major) - : Major(Major), Minor(0), Subminor(0), HasMinor(false), HasSubminor(false), - UsesUnderscores(false) - { } + : Major(Major), Minor(0), Subminor(0), Build(0), HasMinor(false), + HasSubminor(false), HasBuild(false), UsesUnderscores(false) {} explicit VersionTuple(unsigned Major, unsigned Minor, bool UsesUnderscores = false) - : Major(Major), Minor(Minor), Subminor(0), HasMinor(true), - HasSubminor(false), UsesUnderscores(UsesUnderscores) - { } + : Major(Major), Minor(Minor), Subminor(0), Build(0), HasMinor(true), + HasSubminor(false), HasBuild(false), UsesUnderscores(UsesUnderscores) {} explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, bool UsesUnderscores = false) - : Major(Major), Minor(Minor), Subminor(Subminor), HasMinor(true), - HasSubminor(true), UsesUnderscores(UsesUnderscores) - { } - + : Major(Major), Minor(Minor), Subminor(Subminor), Build(0), + HasMinor(true), HasSubminor(true), HasBuild(false), + UsesUnderscores(UsesUnderscores) {} + + explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, + unsigned Build, bool UsesUnderscores = false) + : Major(Major), Minor(Minor), Subminor(Subminor), Build(Build), + HasMinor(true), HasSubminor(true), HasBuild(true), + UsesUnderscores(UsesUnderscores) {} + /// \brief Determine whether this version information is empty /// (e.g., all version components are zero). - bool empty() const { return Major == 0 && Minor == 0 && Subminor == 0; } + bool empty() const { + return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0; + } /// \brief Retrieve the major version number. unsigned getMajor() const { return Major; } @@ -74,6 +82,13 @@ public: return Subminor; } + /// \brief Retrieve the build version number, if provided. + Optional<unsigned> getBuild() const { + if (!HasBuild) + return None; + return Build; + } + bool usesUnderscores() const { return UsesUnderscores; } @@ -85,7 +100,8 @@ public: /// \brief Determine if two version numbers are equivalent. If not /// provided, minor and subminor version numbers are considered to be zero. friend bool operator==(const VersionTuple& X, const VersionTuple &Y) { - return X.Major == Y.Major && X.Minor == Y.Minor && X.Subminor == Y.Subminor; + return X.Major == Y.Major && X.Minor == Y.Minor && + X.Subminor == Y.Subminor && X.Build == Y.Build; } /// \brief Determine if two version numbers are not equivalent. @@ -101,8 +117,8 @@ public: /// If not provided, minor and subminor version numbers are considered to be /// zero. friend bool operator<(const VersionTuple &X, const VersionTuple &Y) { - return std::tie(X.Major, X.Minor, X.Subminor) < - std::tie(Y.Major, Y.Minor, Y.Subminor); + return std::tie(X.Major, X.Minor, X.Subminor, X.Build) < + std::tie(Y.Major, Y.Minor, Y.Subminor, Y.Build); } /// \brief Determine whether one version number follows another. @@ -136,7 +152,7 @@ public: /// \brief Try to parse the given string as a version number. /// \returns \c true if the string does not match the regular expression - /// [0-9]+(\.[0-9]+(\.[0-9]+)) + /// [0-9]+(\.[0-9]+){0,3} bool tryParse(StringRef string); }; diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h index 07c6183..8586e77 100644 --- a/include/clang/CodeGen/BackendUtil.h +++ b/include/clang/CodeGen/BackendUtil.h @@ -34,7 +34,7 @@ namespace clang { void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, - raw_ostream *OS); + raw_pwrite_stream *OS); } #endif diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h index 102d25d..e32fb14 100644 --- a/include/clang/CodeGen/CGFunctionInfo.h +++ b/include/clang/CodeGen/CGFunctionInfo.h @@ -63,10 +63,10 @@ public: Expand, /// InAlloca - Pass the argument directly using the LLVM inalloca attribute. - /// This is similar to 'direct', except it only applies to arguments stored - /// in memory and forbids any implicit copies. When applied to a return - /// type, it means the value is returned indirectly via an implicit sret - /// parameter stored in the argument struct. + /// This is similar to indirect with byval, except it only applies to + /// arguments stored in memory and forbids any implicit copies. When + /// applied to a return type, it means the value is returned indirectly via + /// an implicit sret parameter stored in the argument struct. InAlloca, KindFirst = Direct, KindLast = InAlloca diff --git a/include/clang/CodeGen/CodeGenAction.h b/include/clang/CodeGen/CodeGenAction.h index f8fd561..264780d 100644 --- a/include/clang/CodeGen/CodeGenAction.h +++ b/include/clang/CodeGen/CodeGenAction.h @@ -45,7 +45,7 @@ protected: void EndSourceFileAction() override; public: - ~CodeGenAction(); + ~CodeGenAction() override; /// setLinkModule - Set the link module to be used by this action. If a link /// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty, diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h index f4c3107..8facc3c 100644 --- a/include/clang/CodeGen/ModuleBuilder.h +++ b/include/clang/CodeGen/ModuleBuilder.h @@ -27,7 +27,6 @@ namespace clang { class CoverageSourceInfo; class LangOptions; class CodeGenOptions; - class TargetOptions; class Decl; class CodeGenerator : public ASTConsumer { @@ -44,7 +43,6 @@ namespace clang { CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags, const std::string &ModuleName, const CodeGenOptions &CGO, - const TargetOptions &TO, llvm::LLVMContext& C, CoverageSourceInfo *CoverageInfo = nullptr); } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index e043001..1622c41 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -25,11 +25,11 @@ def target_feature : Separate<["-"], "target-feature">, HelpText<"Target specific attributes">; def triple : Separate<["-"], "triple">, HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; +def target_abi : Separate<["-"], "target-abi">, + HelpText<"Target a particular ABI type">; } -def target_abi : Separate<["-"], "target-abi">, - HelpText<"Target a particular ABI type">; def target_linker_version : Separate<["-"], "target-linker-version">, HelpText<"Target linker version">; def triple_EQ : Joined<["-"], "triple=">, Alias<triple>; @@ -182,6 +182,8 @@ def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">, HelpText<"Emit CFG checksum for functions in .gcno files.">; def coverage_no_function_names_in_data : Flag<["-"], "coverage-no-function-names-in-data">, HelpText<"Emit function names in .gcda files.">; +def coverage_exit_block_before_body : Flag<["-"], "coverage-exit-block-before-body">, + HelpText<"Emit the exit block before the body blocks in .gcno files.">; def coverage_version_EQ : Joined<["-"], "coverage-version=">, HelpText<"Four-byte version string for gcov files.">; def test_coverage : Flag<["-"], "test-coverage">, @@ -239,6 +241,20 @@ def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">, HelpText<"Run the BB vectorization passes">; def dependent_lib : Joined<["--"], "dependent-lib=">, HelpText<"Add dependent library">; +def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">, + HelpText<"Sanitizer coverage type">; +def fsanitize_coverage_indirect_calls + : Flag<["-"], "fsanitize-coverage-indirect-calls">, + HelpText<"Enable sanitizer coverage for indirect calls">; +def fsanitize_coverage_trace_bb + : Flag<["-"], "fsanitize-coverage-trace-bb">, + HelpText<"Enable basic block tracing in sanitizer coverage">; +def fsanitize_coverage_trace_cmp + : Flag<["-"], "fsanitize-coverage-trace-cmp">, + HelpText<"Enable cmp instruction tracing in sanitizer coverage">; +def fsanitize_coverage_8bit_counters + : Flag<["-"], "fsanitize-coverage-8bit-counters">, + HelpText<"Enable frequency counters in sanitizer coverage">; //===----------------------------------------------------------------------===// // Dependency Output Options @@ -342,6 +358,15 @@ def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">, def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">, HelpText<"Use the current working directory as the home directory of " "module maps specified by -fmodule-map-file=<FILE>">; +def fmodule_feature : Separate<["-"], "fmodule-feature">, + MetaVarName<"<feature>">, + HelpText<"Enable <feature> in module map requires declarations">; +def fmodules_local_submodule_visibility : + Flag<["-"], "fmodules-local-submodule-visibility">, + HelpText<"Enforce name visibility rules across submodules of the same " + "top-level module.">; +def fconcepts_ts : Flag<["-"], "fconcepts-ts">, + HelpText<"Enable C++ Extensions for Concepts.">; let Group = Action_Group in { @@ -398,6 +423,11 @@ def migrate : Flag<["-"], "migrate">, HelpText<"Migrate source code">; } +def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">, + HelpText<"Preserve order of LLVM use-lists when serializing">; +def no_emit_llvm_uselists : Flag<["-"], "no-emit-llvm-uselists">, + HelpText<"Don't preserve order of LLVM use-lists when serializing">; + def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, HelpText<"Directory for temporary files produced during ARC or ObjC migration">; def arcmt_check : Flag<["-"], "arcmt-check">, @@ -513,14 +543,14 @@ def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, HelpText<"Defines the __DEPRECATED macro">; def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, HelpText<"Undefines the __DEPRECATED macro">; -def fsized_deallocation : Flag<["-"], "fsized-deallocation">, - HelpText<"Enable C++14 sized global deallocation functions">; def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">, HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">; def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">, HelpText<"Control vtordisp placement on win32 targets">; def fno_rtti_data : Flag<["-"], "fno-rtti-data">, HelpText<"Control emission of RTTI data">; +def fnative_half_type: Flag<["-"], "fnative-half-type">, + HelpText<"Use the native half type for __fp16 instead of promoting to float">; def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, HelpText<"Allow function arguments and returns of type half">; @@ -574,14 +604,14 @@ def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record"> def cl_opt_disable : Flag<["-"], "cl-opt-disable">, HelpText<"OpenCL only. This option disables all optimizations. The default is optimizations are enabled.">; +def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, + HelpText<"OpenCL only. This option does nothing and is for compatibility with OpenCL 1.0">; def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">; def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">; def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, HelpText<"OpenCL only. Generate kernel argument metadata.">; -def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, - HelpText<"OpenCL only. Allow optimizations to ignore the signedness of the floating-point zero.">; def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable">; def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, @@ -599,6 +629,14 @@ def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, def fcuda_is_device : Flag<["-"], "fcuda-is-device">, HelpText<"Generate code for CUDA device">; +def fcuda_allow_host_calls_from_host_device : Flag<["-"], + "fcuda-allow-host-calls-from-host-device">, + HelpText<"Allow host device functions to call host functions">; +def fcuda_disable_target_call_checks : Flag<["-"], + "fcuda-disable-target-call-checks">, + HelpText<"Disable all cross-target (host, device, etc.) call checks in CUDA">; +def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">, + HelpText<"Incorporate CUDA device-side binary into host object file.">; } // let Flags = [CC1Option] diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td index 363dd49..959a72e 100644 --- a/include/clang/Driver/CLCompatOptions.td +++ b/include/clang/Driver/CLCompatOptions.td @@ -58,10 +58,19 @@ def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>; def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, MetaVarName<"<macro[=value]>">, Alias<D>; def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>; +def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ftrapping_math>; +def _SLASH_fp_except_ : CLFlag<"fp:except-">, HelpText<"">, Alias<fno_trapping_math>; +def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias<ffast_math>; +def _SLASH_fp_precise : CLFlag<"fp:precise">, HelpText<"">, Alias<fno_fast_math>; +def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>; +def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>, + HelpText<"Assume thread-local variables are defined in the executable">; def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">; def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">; def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, Alias<fwritable_strings>; +def _SLASH_Gs : CLJoined<"Gs">, HelpText<"Set stack probe size">, + Alias<mstack_probe_size>; def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, Alias<ffunction_sections>; def _SLASH_Gy_ : CLFlag<"Gy-">, HelpText<"Don't put each function in its own section">, @@ -78,6 +87,7 @@ def _SLASH_I : CLJoinedOrSeparate<"I">, Alias<I>; def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, Alias<funsigned_char>; +def _SLASH_O0 : CLFlag<"O0">, Alias<O0>; def _SLASH_O : CLJoined<"O">, HelpText<"Optimization level">, MetaVarName<"<n>">, Alias<O>; def _SLASH_Ob0 : CLFlag<"Ob0">, HelpText<"Disable inlining">, @@ -127,11 +137,25 @@ def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">, def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>; def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>, AliasArgs<["no-macro-redefined"]>; +def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>, + AliasArgs<["no-deprecated-declarations"]>; def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, Alias<vtordisp_mode_EQ>; +def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, + HelpText<"Enable C++14 sized global deallocation functions">, + Alias<fsized_deallocation>; +def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">, + HelpText<"Disable C++14 sized global deallocation functions">, + Alias<fno_sized_deallocation>; def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">, HelpText<"Treat string literals as const">, Alias<W_Joined>, AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>; +def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">, + HelpText<"Enable thread-safe initialization of static variables">, + Alias<fthreadsafe_statics>; +def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">, + HelpText<"Disable thread-safe initialization of static variables">, + Alias<fno_threadsafe_statics>; def _SLASH_Zc_trigraphs : CLFlag<"Zc:trigraphs">, HelpText<"Enable trigraphs">, Alias<ftrigraphs>; def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">, @@ -155,6 +179,7 @@ def _SLASH_arch : CLCompileJoined<"arch:">, HelpText<"Set architecture for code generation">; def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>; +def _SLASH_volatile_Group : OptionGroup<"</volatile group>">, Group<cl_compile_Group>; def _SLASH_EH : CLJoined<"EH">, HelpText<"Exception handling model">; def _SLASH_EP : CLFlag<"EP">, @@ -193,13 +218,22 @@ def _SLASH_o : CLJoinedOrSeparate<"o">, HelpText<"Set output file or directory (ends in / or \\)">, MetaVarName<"<file or directory>">; def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">; +def _SLASH_Qvec : CLFlag<"Qvec">, + HelpText<"Enable the loop vectorization passes">, + Alias<fvectorize>; +def _SLASH_Qvec_ : CLFlag<"Qvec-">, + HelpText<"Disable the loop vectorization passes">, + Alias<fno_vectorize>; def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, HelpText<"Specify a C source file">, MetaVarName<"<filename>">; def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, HelpText<"Specify a C++ source file">, MetaVarName<"<filename>">; def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; - +def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, Group<_SLASH_volatile_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Volatile loads and stores have standard semantics">; +def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, Group<_SLASH_volatile_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Volatile loads and stores have acquire and release semantics">; // Ignored: @@ -207,6 +241,7 @@ def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; +def _SLASH_Fd : CLIgnoredJoined<"Fd">; def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">; def _SLASH_Gd : CLIgnoredFlag<"Gd">; def _SLASH_GF : CLIgnoredFlag<"GF">; @@ -215,10 +250,10 @@ def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; def _SLASH_nologo : CLIgnoredFlag<"nologo">; def _SLASH_Ob1 : CLIgnoredFlag<"Ob1">; def _SLASH_Ob2 : CLIgnoredFlag<"Ob2">; +def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">; def _SLASH_RTC : CLIgnoredJoined<"RTC">; def _SLASH_sdl : CLIgnoredFlag<"sdl">; def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">; -def _SLASH_volatile_iso : CLIgnoredFlag<"volatile:iso">; def _SLASH_w : CLIgnoredJoined<"w">; def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">; def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; @@ -240,9 +275,7 @@ def _SLASH_FA_joined : CLJoined<"FA">; def _SLASH_favor : CLJoined<"favor">; def _SLASH_FC : CLFlag<"FC">; def _SLASH_F : CLFlag<"F">; -def _SLASH_Fd : CLJoined<"Fd">; def _SLASH_Fm : CLJoined<"Fm">; -def _SLASH_fp : CLJoined<"fp">; def _SLASH_Fp : CLJoined<"Fp">; def _SLASH_Fr : CLJoined<"Fr">; def _SLASH_FR : CLJoined<"FR">; @@ -250,7 +283,6 @@ def _SLASH_FU : CLJoinedOrSeparate<"FU">; def _SLASH_Fx : CLFlag<"Fx">; def _SLASH_G1 : CLFlag<"G1">; def _SLASH_G2 : CLFlag<"G2">; -def _SLASH_GA : CLFlag<"GA">; def _SLASH_Ge : CLFlag<"Ge">; def _SLASH_Gh : CLFlag<"Gh">; def _SLASH_GH : CLFlag<"GH">; @@ -260,7 +292,6 @@ def _SLASH_Gm : CLFlag<"Gm">; def _SLASH_Gm_ : CLFlag<"Gm-">; def _SLASH_Gr : CLFlag<"Gr">; def _SLASH_GS : CLFlag<"GS">; -def _SLASH_Gs : CLJoined<"Gs">; def _SLASH_GT : CLFlag<"GT">; def _SLASH_GX : CLFlag<"GX">; def _SLASH_Gv : CLFlag<"Gv">; @@ -280,7 +311,6 @@ def _SLASH_Qpar : CLFlag<"Qpar">; def _SLASH_Qvec_report : CLJoined<"Qvec-report">; def _SLASH_u : CLFlag<"u">; def _SLASH_V : CLFlag<"V">; -def _SLASH_volatile_ms : CLFlag<"volatile:ms">; def _SLASH_WL : CLFlag<"WL">; def _SLASH_Wp64 : CLFlag<"Wp64">; def _SLASH_X : CLFlag<"X">; diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index 67d67c3..09521c2 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -61,6 +61,12 @@ class Driver { CLMode } Mode; + enum SaveTempsMode { + SaveTempsNone, + SaveTempsCwd, + SaveTempsObj + } SaveTemps; + public: // Diag - Forwarding function for diagnostics. DiagnosticBuilder Diag(unsigned DiagID) const { @@ -232,6 +238,9 @@ public: InstalledDir = Value; } + bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; } + bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; } + /// @} /// @name Primary Functionality /// @{ @@ -348,8 +357,8 @@ public: /// \p Phase on the \p Input, taking in to account arguments /// like -fsyntax-only or --analyze. std::unique_ptr<Action> - ConstructPhaseAction(const llvm::opt::ArgList &Args, phases::ID Phase, - std::unique_ptr<Action> Input) const; + ConstructPhaseAction(const ToolChain &TC, const llvm::opt::ArgList &Args, + phases::ID Phase, std::unique_ptr<Action> Input) const; /// BuildJobsForAction - Construct the jobs to perform for the /// action \p A. @@ -393,7 +402,7 @@ public: /// handle this action. bool ShouldUseClangCompiler(const JobAction &JA) const; - bool IsUsingLTO(const llvm::opt::ArgList &Args) const; + bool IsUsingLTO(const ToolChain &TC, const llvm::opt::ArgList &Args) const; private: /// \brief Retrieves a ToolChain for a particular target triple. diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h index b510676..bc7e3ec 100644 --- a/include/clang/Driver/Job.h +++ b/include/clang/Driver/Job.h @@ -175,7 +175,7 @@ private: public: JobList(); - virtual ~JobList() {} + ~JobList() override {} void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo = nullptr) const override; diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h index dcf609a..20bb80d 100644 --- a/include/clang/Driver/Multilib.h +++ b/include/clang/Driver/Multilib.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_DRIVER_MULTILIB_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "llvm/Option/Option.h" #include <functional> @@ -102,11 +103,7 @@ public: StringRef InstallDir, StringRef Triple, const Multilib &M)> IncludeDirsFunc; - struct FilterCallback { - virtual ~FilterCallback() {}; - /// \return true iff the filter should remove the Multilib from the set - virtual bool operator()(const Multilib &M) const = 0; - }; + typedef llvm::function_ref<bool(const Multilib &)> FilterCallback; private: multilib_list Multilibs; @@ -127,12 +124,12 @@ public: MultilibSet &Either(const Multilib &M1, const Multilib &M2, const Multilib &M3, const Multilib &M4, const Multilib &M5); - MultilibSet &Either(const std::vector<Multilib> &Ms); + MultilibSet &Either(ArrayRef<Multilib> Ms); /// Filter out some subset of the Multilibs using a user defined callback - MultilibSet &FilterOut(const FilterCallback &F); + MultilibSet &FilterOut(FilterCallback F); /// Filter out those Multilibs whose gccSuffix matches the given expression - MultilibSet &FilterOut(std::string Regex); + MultilibSet &FilterOut(const char *Regex); /// Add a completed Multilib to the set void push_back(const Multilib &M); @@ -157,18 +154,17 @@ public: void print(raw_ostream &OS) const; MultilibSet &setIncludeDirsCallback(IncludeDirsFunc F) { - IncludeCallback = F; + IncludeCallback = std::move(F); return *this; } - IncludeDirsFunc includeDirsCallback() const { return IncludeCallback; } + const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; } private: /// Apply the filter to Multilibs and return the subset that remains - static multilib_list filterCopy(const FilterCallback &F, - const multilib_list &Ms); + static multilib_list filterCopy(FilterCallback F, const multilib_list &Ms); /// Apply the filter to the multilib_list, removing those that don't match - static void filterInPlace(const FilterCallback &F, multilib_list &Ms); + static void filterInPlace(FilterCallback F, multilib_list &Ms); }; raw_ostream &operator<<(raw_ostream &OS, const MultilibSet &MS); diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index b68a46b..dec917b 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -250,6 +250,8 @@ def MQ : JoinedOrSeparate<["-"], "MQ">, Group<M_Group>, Flags<[CC1Option]>, HelpText<"Specify name of main file output to quote in depfile">; def MT : JoinedOrSeparate<["-"], "MT">, Group<M_Group>, Flags<[CC1Option]>, HelpText<"Specify name of main file output in depfile">; +def MV : Flag<["-"], "MV">, Group<M_Group>, Flags<[CC1Option]>, + HelpText<"Use NMake/Jom format for the depfile">; def Mach : Flag<["-"], "Mach">; def O0 : Flag<["-"], "O0">, Group<O_Group>, Flags<[CC1Option]>; def O4 : Flag<["-"], "O4">, Group<O_Group>, Flags<[CC1Option]>; @@ -404,6 +406,11 @@ def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, Flags<[DriverOption, CC1Option]>, HelpText<"Disable generation of linker directives for automatic library linking">; +def fgnu_inline_asm : Flag<["-"], "fgnu-inline-asm">, Group<f_Group>, Flags<[DriverOption]>; +def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>, + Flags<[DriverOption, CC1Option]>, + HelpText<"Disable GNU style inline asm">; + def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">, Group<f_Group>, Flags<[DriverOption, CC1Option]>, HelpText<"Enable sample-based profile guided optimizations">; @@ -411,7 +418,10 @@ def fauto_profile_EQ : Joined<["-"], "fauto-profile=">, Alias<fprofile_sample_use_EQ>; def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Generate instrumented code to collect execution counts">; + HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">; +def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">, + Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<file>">, + HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>; def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">, Group<f_Group>, Flags<[CC1Option]>, @@ -428,12 +438,13 @@ def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Fl def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>; def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>; def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>; -def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use colors in diagnostics">; -def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>; +def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, + Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">; +def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>, + Flags<[CoreOption, DriverOption]>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>; -def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use ANSI escape codes for diagnostics">; +def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group<f_Group>, + Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, MetaVarName<"<arg>">; @@ -456,7 +467,7 @@ def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group> def fdebug_pass_structure : Flag<["-"], "fdebug-pass-structure">, Group<f_Group>; def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group<f_clang_Group>; def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group<f_clang_Group>, - Flags<[CC1Option]>, HelpText<"Print fix-its in machine parseable form">; + Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">; def fdiagnostics_print_source_range_info : Flag<["-"], "fdiagnostics-print-source-range-info">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Print source range spans in numeric form">; @@ -518,9 +529,15 @@ def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">, def fno_sanitize_blacklist : Flag<["-"], "fno-sanitize-blacklist">, Group<f_clang_Group>, HelpText<"Don't use blacklist file for sanitizers">; -def fsanitize_coverage : Joined<["-"], "fsanitize-coverage=">, - Group<f_clang_Group>, Flags<[CC1Option]>, - HelpText<"Enable coverage instrumentation for Sanitizers">; +def fsanitize_coverage + : CommaJoined<["-"], "fsanitize-coverage=">, + Group<f_clang_Group>, Flags<[CoreOption]>, + HelpText<"Specify the type of coverage instrumentation for Sanitizers">; +def fno_sanitize_coverage + : CommaJoined<["-"], "fno-sanitize-coverage=">, + Group<f_clang_Group>, Flags<[CoreOption]>, + HelpText<"Disable specified features of coverage instrumentation for " + "Sanitizers">; def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Enable origins tracking in MemorySanitizer">; @@ -556,12 +573,16 @@ def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations"> Group<f_Group>; def fassociative_math : Flag<["-"], "fassociative-math">, Group<f_Group>; def fno_associative_math : Flag<["-"], "fno-associative-math">, Group<f_Group>; -def freciprocal_math : Flag<["-"], "freciprocal-math">, Group<f_Group>; +def freciprocal_math : + Flag<["-"], "freciprocal-math">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Allow division operations to be reassociated">; def fno_reciprocal_math : Flag<["-"], "fno-reciprocal-math">, Group<f_Group>; def ffinite_math_only : Flag<["-"], "ffinite-math-only">, Group<f_Group>, Flags<[CC1Option]>; def fno_finite_math_only : Flag<["-"], "fno-finite-math-only">, Group<f_Group>; def fsigned_zeros : Flag<["-"], "fsigned-zeros">, Group<f_Group>; -def fno_signed_zeros : Flag<["-"], "fno-signed-zeros">, Group<f_Group>; +def fno_signed_zeros : + Flag<["-"], "fno-signed-zeros">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Allow optimizations that ignore the sign of floating point zeros">; def fhonor_nans : Flag<["-"], "fhonor-nans">, Group<f_Group>; def fno_honor_nans : Flag<["-"], "fno-honor-nans">, Group<f_Group>; def fhonor_infinities : Flag<["-"], "fhonor-infinities">, Group<f_Group>; @@ -589,6 +610,10 @@ def frewrite_map_file_EQ : Joined<["-"], "frewrite-map-file=">, Group<f_Group>, Flags<[DriverOption]>; +def fuse_line_directives : Flag<["-"], "fuse-line-directives">, Group<f_Group>, + Flags<[CC1Option]>; +def fno_use_line_directives : Flag<["-"], "fno-use-line-directives">, Group<f_Group>; + def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Assert that the compilation takes place in a freestanding environment">; def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>, @@ -614,13 +639,14 @@ def flto_EQ : Joined<["-"], "flto=">, Group<clang_ignored_gcc_optimization_f_Gro def flto : Flag<["-"], "flto">, Group<f_Group>; def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>; def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, - Group<f_Group>; + Group<f_Group>, Flags<[DriverOption, CoreOption]>; def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group<f_Group>; def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>; def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable full Microsoft Visual C++ compatibility">; +def fms_volatile : Joined<["-"], "fms-volatile">, Group<f_Group>, Flags<[CC1Option]>; def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>, HelpText<"Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default))">; def fms_compatibility_version @@ -693,6 +719,9 @@ def fmodules_implicit_maps : def fno_modules_implicit_maps : Flag <["-"], "fno-modules-implicit-maps">, Group<f_Group>, Flags<[DriverOption, CC1Option]>; +def fno_implicit_modules : + Flag <["-"], "fno-implicit-modules">, + Group<f_Group>, Flags<[DriverOption, CC1Option]>; def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group<f_Group>, Flags<[CC1Option]>; def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>; @@ -717,8 +746,10 @@ def fno_math_builtin : Flag<["-"], "fno-math-builtin">, Group<f_Group>, Flags<[C HelpText<"Disable implicit builtin knowledge of math functions">; def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>, Flags<[CC1Option]>; -def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>; -def fno_diagnostics_color : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>; +def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>, + Flags<[CoreOption, CC1Option]>; +def fno_diagnostics_color : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>, + Flags<[CoreOption, DriverOption]>; def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Compile common globals like normal definitions">; def fno_constant_cfstrings : Flag<["-"], "fno-constant-cfstrings">, Group<f_Group>, @@ -741,6 +772,8 @@ def fno_exceptions : Flag<["-"], "fno-exceptions">, Group<f_Group>; def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>; def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>; def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>; +def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Use the given vector functions library">; def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>, HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>; def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>, @@ -753,6 +786,12 @@ def fno_modules_decluse : Flag <["-"], "fno-modules-decluse">, Group<f_Group>, Flags<[DriverOption]>; def fno_modules_strict_decluse : Flag <["-"], "fno-strict-modules-decluse">, Group<f_Group>, Flags<[DriverOption]>; +def fimplicit_modules : Flag <["-"], "fimplicit-modules">, Group<f_Group>, + Flags<[DriverOption]>; +def fmodule_file_deps : Flag <["-"], "fmodule-file-deps">, Group<f_Group>, + Flags<[DriverOption]>; +def fno_module_file_deps : Flag <["-"], "fno-module-file-deps">, Group<f_Group>, + Flags<[DriverOption]>; def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>; def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>; def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>; @@ -802,6 +841,14 @@ def fobjc_atdefs : Flag<["-"], "fobjc-atdefs">, Group<clang_ignored_f_Group>; def fobjc_call_cxx_cdtors : Flag<["-"], "fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>; def fobjc_exceptions: Flag<["-"], "fobjc-exceptions">, Group<f_Group>, HelpText<"Enable Objective-C exceptions">, Flags<[CC1Option]>; +def fapplication_extension : Flag<["-"], "fapplication-extension">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Restrict code to those available for App Extensions">; +def fno_application_extension : Flag<["-"], "fno-application-extension">, + Group<f_Group>; +def fsized_deallocation : Flag<["-"], "fsized-deallocation">, Flags<[CC1Option]>, + HelpText<"Enable C++14 sized global deallocation functions">, Group<f_Group>; +def fno_sized_deallocation: Flag<["-"], "fno-sized-deallocation">, Group<f_Group>; def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use GC exclusively for Objective-C related memory management">; @@ -829,7 +876,7 @@ def fno_objc_nonfragile_abi : Flag<["-"], "fno-objc-nonfragile-abi">, Group<f_Gr def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispatch">, Group<f_Group>; def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>; def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>; -def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>; +def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>; def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>; def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">; @@ -877,8 +924,8 @@ def fspell_checking : Flag<["-"], "fspell-checking">, Group<f_Group>; def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group<f_Group>; def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>; def fsigned_char : Flag<["-"], "fsigned-char">, Group<f_Group>; -def fno_signed_char : Flag<["-"], "fno-signed-char">, Flags<[CC1Option]>, - Group<clang_ignored_f_Group>, HelpText<"Char is unsigned">; +def fno_signed_char : Flag<["-"], "fno-signed-char">, Group<f_Group>, + Flags<[CC1Option]>, HelpText<"Char is unsigned">; def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>, HelpText<"Force the usage of stack protectors for all functions">; @@ -898,7 +945,8 @@ def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Opti HelpText<"Enable optimizations based on the strict definition of an enum's " "value range">; def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>; -def fsyntax_only : Flag<["-"], "fsyntax-only">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>; +def fsyntax_only : Flag<["-"], "fsyntax-only">, + Flags<[DriverOption,CoreOption,CC1Option]>, Group<Action_Group>; def ftabstop_EQ : Joined<["-"], "ftabstop=">, Group<f_Group>; def ftemplate_depth_EQ : Joined<["-"], "ftemplate-depth=">, Group<f_Group>; def ftemplate_depth_ : Joined<["-"], "ftemplate-depth-">, Group<f_Group>; @@ -958,7 +1006,7 @@ def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>, HelpText<"Do not process trigraph sequences">, Flags<[CC1Option]>; def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>; def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>; -def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">, Group<clang_ignored_f_Group>; +def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">; def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>; def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>; def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>, @@ -987,6 +1035,14 @@ def fdata_sections : Flag <["-"], "fdata-sections">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Place each data in its own section (ELF Only)">; def fno_data_sections : Flag <["-"], "fno-data-sections">, Group<f_Group>, Flags<[CC1Option]>; + +def funique_section_names : Flag <["-"], "funique-section-names">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Use unique names for text and data sections (ELF Only)">; +def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">, + Group<f_Group>, Flags<[CC1Option]>; + + def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">; def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>, @@ -1105,7 +1161,8 @@ def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>; def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>; def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>; def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group<m_Group>; -def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>; +def mglobal_merge : Flag<["-"], "mglobal-merge">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Enable merging of globals">; def mhard_float : Flag<["-"], "mhard-float">, Group<m_Group>; def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>; def mios_version_min_EQ : Joined<["-"], "mios-version-min=">, @@ -1124,6 +1181,8 @@ def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Opti HelpText<"Force realign the stack at entry to every function">; def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Set the stack alignment">; +def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Set the stack probe size">; def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"The thread model to use, e.g. posix, single (posix by default)">; @@ -1144,9 +1203,12 @@ def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>; def mno_sse2 : Flag<["-"], "mno-sse2">, Group<m_x86_Features_Group>; def mno_sse3 : Flag<["-"], "mno-sse3">, Group<m_x86_Features_Group>; def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>; -def mno_sse4 : Flag<["-"], "mno-sse4">, Group<m_x86_Features_Group>; def mno_sse4_1 : Flag<["-"], "mno-sse4.1">, Group<m_x86_Features_Group>; def mno_sse4_2 : Flag<["-"], "mno-sse4.2">, Group<m_x86_Features_Group>; +// -mno-sse4 turns off sse4.1 which has the effect of turning off everything +// later than 4.1. -msse4 turns on 4.2 which has the effect of turning on +// everything earlier than 4.2. +def mno_sse4 : Flag<["-"], "mno-sse4">, Alias<mno_sse4_1>; def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>; def mno_ssse3 : Flag<["-"], "mno-ssse3">, Group<m_x86_Features_Group>; def mno_aes : Flag<["-"], "mno-aes">, Group<m_x86_Features_Group>; @@ -1218,10 +1280,22 @@ def mpower8_vector : Flag<["-"], "mpower8-vector">, Group<m_ppc_Features_Group>; def mno_power8_vector : Flag<["-"], "mno-power8-vector">, Group<m_ppc_Features_Group>; +def mpower8_crypto : Flag<["-"], "mcrypto">, + Group<m_ppc_Features_Group>; +def mnopower8_crypto : Flag<["-"], "mno-crypto">, + Group<m_ppc_Features_Group>; +def mdirect_move : Flag<["-"], "mdirect-move">, + Group<m_ppc_Features_Group>; +def mnodirect_move : Flag<["-"], "mno-direct-move">, + Group<m_ppc_Features_Group>; +def mhtm : Flag<["-"], "mhtm">, Group<m_ppc_Features_Group>; +def mno_htm : Flag<["-"], "mno-htm">, Group<m_ppc_Features_Group>; def mfprnd : Flag<["-"], "mfprnd">, Group<m_ppc_Features_Group>; def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_ppc_Features_Group>; def mcmpb : Flag<["-"], "mcmpb">, Group<m_ppc_Features_Group>; def mno_cmpb : Flag<["-"], "mno-cmpb">, Group<m_ppc_Features_Group>; +def misel : Flag<["-"], "misel">, Group<m_ppc_Features_Group>; +def mno_isel : Flag<["-"], "mno-isel">, Group<m_ppc_Features_Group>; def mmfcrf : Flag<["-"], "mmfcrf">, Group<m_ppc_Features_Group>; def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Group<m_ppc_Features_Group>; def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_ppc_Features_Group>; @@ -1230,6 +1304,11 @@ def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>; def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_ppc_Features_Group>; def mcrbits : Flag<["-"], "mcrbits">, Group<m_ppc_Features_Group>; def mno_crbits : Flag<["-"], "mno-crbits">, Group<m_ppc_Features_Group>; +def minvariant_function_descriptors : + Flag<["-"], "minvariant-function-descriptors">, Group<m_ppc_Features_Group>; +def mno_invariant_function_descriptors : + Flag<["-"], "mno-invariant-function-descriptors">, + Group<m_ppc_Features_Group>; def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable AltiVec vector initializer syntax">; @@ -1237,6 +1316,9 @@ def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]> def maltivec : Flag<["-"], "maltivec">, Alias<faltivec>; def mno_altivec : Flag<["-"], "mno-altivec">, Alias<fno_altivec>; +def mvx : Flag<["-"], "mvx">, Group<m_Group>; +def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>; + def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>; def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>; def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>, @@ -1258,9 +1340,9 @@ def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>; def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>; def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>; def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>; -def msse4 : Flag<["-"], "msse4">, Group<m_x86_Features_Group>; def msse4_1 : Flag<["-"], "msse4.1">, Group<m_x86_Features_Group>; def msse4_2 : Flag<["-"], "msse4.2">, Group<m_x86_Features_Group>; +def msse4 : Flag<["-"], "msse4">, Alias<msse4_2>; def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>; def mssse3 : Flag<["-"], "mssse3">, Group<m_x86_Features_Group>; def maes : Flag<["-"], "maes">, Group<m_x86_Features_Group>; @@ -1342,6 +1424,12 @@ def mips32 : Flag<["-"], "mips32">, def mips32r2 : Flag<["-"], "mips32r2">, Alias<march_EQ>, AliasArgs<["mips32r2"]>, HelpText<"Equivalent to -march=mips32r2">, Flags<[HelpHidden]>; +def mips32r3 : Flag<["-"], "mips32r3">, + Alias<march_EQ>, AliasArgs<["mips32r3"]>, + HelpText<"Equivalent to -march=mips32r3">, Flags<[HelpHidden]>; +def mips32r5 : Flag<["-"], "mips32r5">, + Alias<march_EQ>, AliasArgs<["mips32r5"]>, + HelpText<"Equivalent to -march=mips32r5">, Flags<[HelpHidden]>; def mips32r6 : Flag<["-"], "mips32r6">, Alias<march_EQ>, AliasArgs<["mips32r6"]>, HelpText<"Equivalent to -march=mips32r6">, Flags<[HelpHidden]>; @@ -1351,6 +1439,12 @@ def mips64 : Flag<["-"], "mips64">, def mips64r2 : Flag<["-"], "mips64r2">, Alias<march_EQ>, AliasArgs<["mips64r2"]>, HelpText<"Equivalent to -march=mips64r2">, Flags<[HelpHidden]>; +def mips64r3 : Flag<["-"], "mips64r3">, + Alias<march_EQ>, AliasArgs<["mips64r3"]>, + HelpText<"Equivalent to -march=mips64r3">, Flags<[HelpHidden]>; +def mips64r5 : Flag<["-"], "mips64r5">, + Alias<march_EQ>, AliasArgs<["mips64r5"]>, + HelpText<"Equivalent to -march=mips64r5">, Flags<[HelpHidden]>; def mips64r6 : Flag<["-"], "mips64r6">, Alias<march_EQ>, AliasArgs<["mips64r6"]>, HelpText<"Equivalent to -march=mips64r6">, Flags<[HelpHidden]>; @@ -1440,7 +1534,10 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>, def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>; def rtlib_EQ : Joined<["-", "--"], "rtlib=">; def r : Flag<["-"], "r">; +def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>, + HelpText<"Save intermediate compilation results.">; def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>, + Alias<save_temps_EQ>, AliasArgs<["cwd"]>, HelpText<"Save intermediate compilation results">; def via_file_asm : Flag<["-", "--"], "via-file-asm">, InternalDebugOpt, HelpText<"Write assembly to file for input to assemble jobs">; diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index 3524da0..bfa63e7 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -13,19 +13,19 @@ #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" #include <string> +#include <vector> namespace clang { namespace driver { -class Driver; class ToolChain; class SanitizerArgs { SanitizerSet Sanitizers; SanitizerSet RecoverableSanitizers; - std::string BlacklistFile; - int SanitizeCoverage; + std::vector<std::string> BlacklistFiles; + int CoverageFeatures; int MsanTrackOrigins; int AsanFieldPadding; bool AsanZeroBaseShadow; @@ -48,16 +48,15 @@ class SanitizerArgs { bool needsUbsanRt() const; bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); } - bool sanitizesVptr() const { return Sanitizers.has(SanitizerKind::Vptr); } bool requiresPIE() const; bool needsUnwindTables() const; + bool needsLTO() const; bool linkCXXRuntimes() const { return LinkCXXRuntimes; } void addArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; private: void clear(); - bool getDefaultBlacklist(const Driver &D, std::string &BLPath); }; } // namespace driver diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 3092e81..560df19 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -53,10 +53,20 @@ public: RLT_Libgcc }; + enum RTTIMode { + RM_EnabledExplicitly, + RM_EnabledImplicitly, + RM_DisabledExplicitly, + RM_DisabledImplicitly + }; + private: const Driver &D; const llvm::Triple Triple; const llvm::opt::ArgList &Args; + // We need to initialize CachedRTTIArg before CachedRTTIMode + const llvm::opt::Arg *const CachedRTTIArg; + const RTTIMode CachedRTTIMode; /// The list of toolchain specific path prefixes to search for /// files. @@ -134,6 +144,12 @@ public: const SanitizerArgs& getSanitizerArgs() const; + // Returns the Arg * that explicitly turned on/off rtti, or nullptr. + const llvm::opt::Arg *getRTTIArg() const { return CachedRTTIArg; } + + // Returns the RTTIMode for the toolchain with the current arguments. + RTTIMode getRTTIMode() const { return CachedRTTIMode; } + // Tool access. /// TranslateArgs - Create a new derived argument list for any argument diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def index 3209679..adc12d3 100644 --- a/include/clang/Driver/Types.def +++ b/include/clang/Driver/Types.def @@ -42,7 +42,8 @@ TYPE("cpp-output", PP_C, INVALID, "i", "u") TYPE("c", C, PP_C, "c", "u") TYPE("cl", CL, PP_C, "cl", "u") -TYPE("cuda", CUDA, PP_CXX, "cpp", "u") +TYPE("cuda-cpp-output", PP_CUDA, INVALID, "cui", "u") +TYPE("cuda", CUDA, PP_CUDA, "cu", "u") 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/Format/Format.h b/include/clang/Format/Format.h index 60c54ab..3fdee99 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -247,6 +247,17 @@ struct FormatStyle { /// \brief If \c true, aligns trailing comments. bool AlignTrailingComments; + /// \brief If \c true, aligns consecutive assignments. + /// + /// This will align the assignment operators of consecutive lines. This + /// will result in formattings like + /// \code + /// int aaaa = 12; + /// int b = 23; + /// int ccc = 23; + /// \endcode + bool AlignConsecutiveAssignments; + /// \brief If \c true, aligns escaped newlines as far left as possible. /// Otherwise puts them into the right-most column. bool AlignEscapedNewlinesLeft; @@ -527,14 +538,6 @@ std::error_code parseConfiguration(StringRef Text, FormatStyle *Style); /// \brief Gets configuration in a YAML string. std::string configurationAsText(const FormatStyle &Style); -/// \brief Reformats the given \p Ranges in the token stream coming out of -/// \c Lex. -/// -/// DEPRECATED: Do not use. -tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex, - SourceManager &SourceMgr, - ArrayRef<CharSourceRange> Ranges); - /// \brief Reformats the given \p Ranges in the file \p ID. /// /// Each range is extended on either end to its next bigger logic unit, i.e. @@ -543,16 +546,22 @@ tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex, /// /// Returns the \c Replacements necessary to make all \p Ranges comply with /// \p Style. +/// +/// If \c IncompleteFormat is non-null, its value will be set to true if any +/// of the affected ranges were not formatted due to a non-recoverable syntax +/// error. tooling::Replacements reformat(const FormatStyle &Style, SourceManager &SourceMgr, FileID ID, - ArrayRef<CharSourceRange> Ranges); + ArrayRef<CharSourceRange> Ranges, + bool *IncompleteFormat = nullptr); /// \brief Reformats the given \p Ranges in \p Code. /// -/// Otherwise identical to the reformat() function consuming a \c Lexer. +/// Otherwise identical to the reformat() function using a file ID. tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, - StringRef FileName = "<stdin>"); + StringRef FileName = "<stdin>", + bool *IncompleteFormat = nullptr); /// \brief Returns the \c LangOpts that the formatter expects you to set. /// diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 634224d..405774b 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -416,8 +416,8 @@ private: /// \brief Clear out and deallocate void ClearCachedCompletionResults(); - ASTUnit(const ASTUnit &) LLVM_DELETED_FUNCTION; - void operator=(const ASTUnit &) LLVM_DELETED_FUNCTION; + ASTUnit(const ASTUnit &) = delete; + void operator=(const ASTUnit &) = delete; explicit ASTUnit(bool MainFileIsAST); @@ -484,8 +484,8 @@ public: } }; friend class ConcurrencyCheck; - - ~ASTUnit(); + + ~ASTUnit() override; bool isMainFileAST() const { return MainFileIsAST; } @@ -675,8 +675,8 @@ public: /// \brief Returns an iterator range for the local preprocessing entities /// of the local Preprocessor, if this is a parsed source file, or the loaded /// preprocessing entities of the primary module if this is an AST file. - std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> - getLocalPreprocessingEntities() const; + llvm::iterator_range<PreprocessingRecord::iterator> + getLocalPreprocessingEntities() const; /// \brief Type for a function iterating over a number of declarations. /// \returns true to continue iteration and false to abort. @@ -880,7 +880,7 @@ public: } void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, bool Complain) override {} + SourceLocation ImportLoc) override {} GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { return nullptr; } diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index b44672d..adf1c87 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -35,11 +35,12 @@ CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe. CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files. CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files. -CODEGENOPT(CUDAIsDevice , 1, 0) ///< Set when compiling for CUDA device. +CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files. CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors. CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker ///< aliases to base ctors when possible. CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. +CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled. CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory. CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing. @@ -68,6 +69,7 @@ CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions t ///< be generated. 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. CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled. CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is ///< enabled. @@ -75,11 +77,11 @@ CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled. CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is ///< enabled. CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. -CODEGENOPT(NoGlobalMerge , 1, 0) ///< Set when -mno-global-merge is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero -CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. +CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. +CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. ///< Disables use of the inline keyword. CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss. @@ -108,7 +110,16 @@ CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero ///< offset in AddressSanitizer. CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer -CODEGENOPT(SanitizeCoverage, 3, 0) ///< Enable sanitizer coverage instrumentation. +CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage + ///< instrumentation. +CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage + ///< for indirect calls. +CODEGENOPT(SanitizeCoverageTraceBB, 1, 0) ///< Enable basic block tracing in + ///< in sanitizer coverage. +CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing + ///< in sanitizer coverage. +CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters + ///< in sanitizer coverage. CODEGENOPT(SanitizeUndefinedTrapOnError, 1, 0) ///< Set on /// -fsanitize-undefined-trap-on-error CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. @@ -138,9 +149,13 @@ CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or ///< .ctors. VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack ///< alignment, if not 0. +VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack + ///< probe size, even if 0. CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information ///< in debug info. +CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists. + /// The user specified number of registers to be used for integral arguments, /// or 0 if unspecified. VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) @@ -157,6 +172,9 @@ VALUE_CODEGENOPT(DwarfVersion, 3, 0) /// The kind of inlining to perform. ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) +// Vector functions library to use. +ENUM_CODEGENOPT(VecLib, VectorLibrary, 1, NoLibrary) + /// The default TLS model to use. ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel) diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 8196064..0c5ce58 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -46,6 +46,11 @@ public: OnlyAlwaysInlining // Only run the always inlining pass. }; + enum VectorLibrary { + NoLibrary, // Don't use any vector library. + Accelerate // Use the Accelerate framework. + }; + enum ObjCDispatchMethodKind { Legacy = 0, NonLegacy = 1, @@ -149,12 +154,20 @@ public: /// A list of dependent libraries. std::vector<std::string> DependentLibraries; + /// Name of the profile file to use as output for -fprofile-instr-generate + std::string InstrProfileOutput; + /// Name of the profile file to use with -fprofile-sample-use. std::string SampleProfileFile; /// Name of the profile file to use as input for -fprofile-instr-use std::string InstrProfileInput; + /// A list of file names passed with -fcuda-include-gpubinary options to + /// forward to CUDA runtime back-end for incorporating them into host-side + /// object file. + std::vector<std::string> CudaGpuBinaryFileNames; + /// Regular expression to select optimizations for which we should enable /// optimization remarks. Transformation passes whose name matches this /// expression (and support this feature), will emit a diagnostic diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h index c01f91d..a78c96d 100644 --- a/include/clang/Frontend/CommandLineSourceLoc.h +++ b/include/clang/Frontend/CommandLineSourceLoc.h @@ -59,7 +59,7 @@ namespace llvm { /// /// Source locations are of the form filename:line:column. template<> - class parser<clang::ParsedSourceLocation> + class parser<clang::ParsedSourceLocation> final : public basic_parser<clang::ParsedSourceLocation> { public: inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue, diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 0f49b34..8d0d939 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -121,6 +121,10 @@ class CompilerInstance : public ModuleLoader { /// \brief Module names that have an override for the target file. llvm::StringMap<std::string> ModuleFileOverrides; + /// \brief Module files that we've explicitly loaded via \ref loadModuleFile, + /// and their dependencies. + llvm::StringSet<> ExplicitlyLoadedModuleFiles; + /// \brief The location of the module-import keyword for the last module /// import. SourceLocation LastModuleImportLoc; @@ -147,21 +151,29 @@ class CompilerInstance : public ModuleLoader { struct OutputFile { std::string Filename; std::string TempFilename; - raw_ostream *OS; + std::unique_ptr<raw_ostream> OS; OutputFile(const std::string &filename, const std::string &tempFilename, - raw_ostream *os) - : Filename(filename), TempFilename(tempFilename), OS(os) { } + std::unique_ptr<raw_ostream> OS) + : Filename(filename), TempFilename(tempFilename), OS(std::move(OS)) {} + OutputFile(OutputFile &&O) + : Filename(std::move(O.Filename)), + TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {} }; + /// If the output doesn't support seeking (terminal, pipe). we switch + /// the stream to a buffer_ostream. These are the buffer and the original + /// stream. + std::unique_ptr<llvm::raw_fd_ostream> NonSeekStream; + /// The list of active output files. std::list<OutputFile> OutputFiles; - CompilerInstance(const CompilerInstance &) LLVM_DELETED_FUNCTION; - void operator=(const CompilerInstance &) LLVM_DELETED_FUNCTION; + CompilerInstance(const CompilerInstance &) = delete; + void operator=(const CompilerInstance &) = delete; public: explicit CompilerInstance(bool BuildingModule = false); - ~CompilerInstance(); + ~CompilerInstance() override; /// @name High-Level Operations /// { @@ -514,7 +526,7 @@ public: /// addOutputFile - Add an output file onto the list of tracked output files. /// /// \param OutFile - The output file info. - void addOutputFile(const OutputFile &OutFile); + void addOutputFile(OutputFile &&OutFile); /// clearOutputFiles - Clear the output file list, destroying the contained /// output streams. @@ -575,6 +587,8 @@ public: /// and replace any existing one with it. void createPreprocessor(TranslationUnitKind TUKind); + std::string getSpecificModuleCachePath(); + /// Create the AST context. void createASTContext(); @@ -588,7 +602,7 @@ public: /// Create an external AST source to read a PCH file. /// /// \return - The new object on success, or null on failure. - static ExternalASTSource *createPCHExternalASTSource( + static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource( StringRef Path, const std::string &Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, void *DeserializationListener, bool OwnDeserializationListener, @@ -622,21 +636,19 @@ public: /// atomically replace the target output on success). /// /// \return - Null on error. - llvm::raw_fd_ostream * - createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "", - StringRef Extension = ""); + raw_pwrite_stream *createDefaultOutputFile(bool Binary = true, + StringRef BaseInput = "", + StringRef Extension = ""); /// Create a new output file and add it to the list of tracked output files, /// optionally deriving the output path name. /// /// \return - Null on error. - llvm::raw_fd_ostream * - createOutputFile(StringRef OutputPath, - bool Binary, bool RemoveFileOnSignal, - StringRef BaseInput, - StringRef Extension, - bool UseTemporary, - bool CreateMissingDirectories = false); + raw_pwrite_stream *createOutputFile(StringRef OutputPath, bool Binary, + bool RemoveFileOnSignal, + StringRef BaseInput, StringRef Extension, + bool UseTemporary, + bool CreateMissingDirectories = false); /// Create a new output file, optionally deriving the output path name. /// @@ -663,7 +675,7 @@ public: /// stored here on success. /// \param TempPathName [out] - If given, the temporary file path name /// will be stored here on success. - static llvm::raw_fd_ostream * + std::unique_ptr<raw_pwrite_stream> createOutputFile(StringRef OutputPath, std::error_code &Error, bool Binary, bool RemoveFileOnSignal, StringRef BaseInput, StringRef Extension, bool UseTemporary, @@ -704,7 +716,7 @@ public: bool IsInclusionDirective) override; void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, bool Complain) override; + SourceLocation ImportLoc) override; bool hadModuleLoaderFatalFailure() const { return ModuleLoader::HadFatalFailure; diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h index f05ab80..7d12548 100644 --- a/include/clang/Frontend/CompilerInvocation.h +++ b/include/clang/Frontend/CompilerInvocation.h @@ -50,7 +50,7 @@ bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags = nullptr); class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { - void operator=(const CompilerInvocationBase &) LLVM_DELETED_FUNCTION; + void operator=(const CompilerInvocationBase &) = delete; public: /// Options controlling the language variant. diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h index 5da1459..2221b54 100644 --- a/include/clang/Frontend/DependencyOutputOptions.h +++ b/include/clang/Frontend/DependencyOutputOptions.h @@ -15,6 +15,9 @@ namespace clang { +/// DependencyOutputFormat - Format for the compiler dependency file. +enum class DependencyOutputFormat { Make, NMake }; + /// DependencyOutputOptions - Options for controlling the compiler dependency /// file generation. class DependencyOutputOptions { @@ -27,7 +30,10 @@ public: unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info. unsigned IncludeModuleFiles : 1; ///< Include module file dependencies. - + + /// The format for the dependency file. + DependencyOutputFormat OutputFormat; + /// The file to write dependency output to. std::string OutputFile; @@ -55,6 +61,7 @@ public: AddMissingHeaderDeps = 0; PrintShowIncludes = 0; IncludeModuleFiles = 0; + OutputFormat = DependencyOutputFormat::Make; } }; diff --git a/include/clang/Frontend/DiagnosticRenderer.h b/include/clang/Frontend/DiagnosticRenderer.h index 5becadf..84a0f50 100644 --- a/include/clang/Frontend/DiagnosticRenderer.h +++ b/include/clang/Frontend/DiagnosticRenderer.h @@ -155,8 +155,8 @@ public: DiagnosticNoteRenderer(const LangOptions &LangOpts, DiagnosticOptions *DiagOpts) : DiagnosticRenderer(LangOpts, DiagOpts) {} - - virtual ~DiagnosticNoteRenderer(); + + ~DiagnosticNoteRenderer() override; void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, const SourceManager &SM) override; diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index 850f87c..b150828 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -85,11 +85,10 @@ public: /// create the PCHGenerator instance returned by CreateASTConsumer. /// /// \returns true if an error occurred, false otherwise. - static bool ComputeASTConsumerArguments(CompilerInstance &CI, - StringRef InFile, - std::string &Sysroot, - std::string &OutputFile, - raw_ostream *&OS); + static raw_ostream *ComputeASTConsumerArguments(CompilerInstance &CI, + StringRef InFile, + std::string &Sysroot, + std::string &OutputFile); }; class GenerateModuleAction : public ASTFrontendAction { @@ -119,11 +118,10 @@ public: /// create the PCHGenerator instance returned by CreateASTConsumer. /// /// \returns true if an error occurred, false otherwise. - bool ComputeASTConsumerArguments(CompilerInstance &CI, - StringRef InFile, - std::string &Sysroot, - std::string &OutputFile, - raw_ostream *&OS); + raw_ostream *ComputeASTConsumerArguments(CompilerInstance &CI, + StringRef InFile, + std::string &Sysroot, + std::string &OutputFile); }; class SyntaxOnlyAction : public ASTFrontendAction { @@ -188,7 +186,7 @@ protected: public: ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles); - virtual ~ASTMergeAction(); + ~ASTMergeAction() override; bool usesPreprocessorOnly() const override; TranslationUnitKind getTranslationUnitKind() override; diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index 71c5aa4..c3aa226 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -71,6 +71,7 @@ enum InputKind { IK_PreprocessedObjCXX, IK_OpenCL, IK_CUDA, + IK_PreprocessedCuda, IK_AST, IK_LLVM_IR }; diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h index c9122da..873af03 100644 --- a/include/clang/Frontend/MultiplexConsumer.h +++ b/include/clang/Frontend/MultiplexConsumer.h @@ -30,7 +30,7 @@ class MultiplexConsumer : public SemaConsumer { public: // Takes ownership of the pointers in C. MultiplexConsumer(std::vector<std::unique_ptr<ASTConsumer>> C); - ~MultiplexConsumer(); + ~MultiplexConsumer() override; // ASTConsumer void Initialize(ASTContext &Context) override; @@ -49,7 +49,7 @@ public: llvm::StringRef Value) override; void HandleDependentLibrary(llvm::StringRef Lib) override; void CompleteTentativeDefinition(VarDecl *D) override; - void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override; + void HandleVTable(CXXRecordDecl *RD) override; ASTMutationListener *GetASTMutationListener() override; ASTDeserializationListener *GetASTDeserializationListener() override; void PrintStats() override; diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h index e273dd6..f86c490 100644 --- a/include/clang/Frontend/PreprocessorOutputOptions.h +++ b/include/clang/Frontend/PreprocessorOutputOptions.h @@ -19,6 +19,7 @@ public: unsigned ShowCPP : 1; ///< Print normal preprocessed output. unsigned ShowComments : 1; ///< Show comments. unsigned ShowLineMarkers : 1; ///< Show \#line markers. + unsigned UseLineDirectives : 1; ///< Use \#line instead of GCC-style \# N. unsigned ShowMacroComments : 1; ///< Show comments, even in macros. unsigned ShowMacros : 1; ///< Print macro definitions. unsigned RewriteIncludes : 1; ///< Preprocess include directives only. @@ -28,6 +29,7 @@ public: ShowCPP = 0; ShowComments = 0; ShowLineMarkers = 1; + UseLineDirectives = 0; ShowMacroComments = 0; ShowMacros = 0; RewriteIncludes = 0; diff --git a/include/clang/Frontend/TextDiagnostic.h b/include/clang/Frontend/TextDiagnostic.h index 42c78af..d41f15a 100644 --- a/include/clang/Frontend/TextDiagnostic.h +++ b/include/clang/Frontend/TextDiagnostic.h @@ -40,8 +40,8 @@ public: const LangOptions &LangOpts, DiagnosticOptions *DiagOpts); - virtual ~TextDiagnostic(); - + ~TextDiagnostic() override; + /// \brief Print the diagonstic level to a raw_ostream. /// /// This is a static helper that handles colorizing the level and formatting diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index f8a71fe..04a5705 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -40,7 +40,7 @@ class TextDiagnosticPrinter : public DiagnosticConsumer { public: TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions *diags, bool OwnsOutputStream = false); - virtual ~TextDiagnosticPrinter(); + ~TextDiagnosticPrinter() override; /// setPrefix - Set the diagnostic printer prefix string, which will be /// printed at the start of any diagnostics. If empty, no prefix string is diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 4cd93b9..cd0ebf6 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -159,9 +159,8 @@ void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders = false, StringRef OutputPath = "", bool ShowDepth = true, bool MSStyle = false); -/// CacheTokens - Cache tokens for use with PCH. Note that this requires -/// a seekable stream. -void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS); +/// Cache tokens for use with PCH. Note that this requires a seekable stream. +void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS); /// The ChainedIncludesSource class converts headers to chained PCHs in /// memory, mainly for testing. diff --git a/include/clang/Frontend/VerifyDiagnosticConsumer.h b/include/clang/Frontend/VerifyDiagnosticConsumer.h index 80e140b..475f07f 100644 --- a/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ b/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -180,8 +180,8 @@ public: } private: - Directive(const Directive &) LLVM_DELETED_FUNCTION; - void operator=(const Directive &) LLVM_DELETED_FUNCTION; + Directive(const Directive &) = delete; + void operator=(const Directive &) = delete; }; typedef std::vector<std::unique_ptr<Directive>> DirectiveList; @@ -246,7 +246,7 @@ public: /// the currently-attached diagnostic client when a diagnostic does not match /// what is expected (as indicated in the source file). VerifyDiagnosticConsumer(DiagnosticsEngine &Diags); - ~VerifyDiagnosticConsumer(); + ~VerifyDiagnosticConsumer() override; void BeginSourceFile(const LangOptions &LangOpts, const Preprocessor *PP) override; diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h index 3195dee..55e35cc 100644 --- a/include/clang/Index/USRGeneration.h +++ b/include/clang/Index/USRGeneration.h @@ -15,7 +15,7 @@ namespace clang { class Decl; -class MacroDefinition; +class MacroDefinitionRecord; class SourceManager; namespace index { @@ -52,8 +52,8 @@ void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS); /// \brief Generate a USR for a macro, including the USR prefix. /// /// \returns true on error, false on success. -bool generateUSRForMacro(const MacroDefinition *MD, const SourceManager &SM, - SmallVectorImpl<char> &Buf); +bool generateUSRForMacro(const MacroDefinitionRecord *MD, + const SourceManager &SM, SmallVectorImpl<char> &Buf); } // namespace index } // namespace clang diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h index 2f9231d..33e7a2d 100644 --- a/include/clang/Lex/ExternalPreprocessorSource.h +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -17,6 +17,7 @@ namespace clang { class IdentifierInfo; +class Module; /// \brief Abstract interface for external sources of preprocessor /// information. @@ -32,6 +33,9 @@ public: /// \brief Update an out-of-date identifier. virtual void updateOutOfDateIdentifier(IdentifierInfo &II) = 0; + + /// \brief Map a module ID to a module. + virtual Module *getModule(unsigned ModuleID) = 0; }; } diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 993c861..183361e 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -32,8 +32,8 @@ namespace clang { /// symlinks to files. Its advantages are that it is dense and more efficient /// to create and process than a directory of symlinks. class HeaderMap { - HeaderMap(const HeaderMap &) LLVM_DELETED_FUNCTION; - void operator=(const HeaderMap &) LLVM_DELETED_FUNCTION; + HeaderMap(const HeaderMap &) = delete; + void operator=(const HeaderMap &) = delete; std::unique_ptr<const llvm::MemoryBuffer> FileBuffer; bool NeedsBSwap; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 158f67d..0406c6d 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -32,6 +32,7 @@ class FileEntry; class FileManager; class HeaderSearchOptions; class IdentifierInfo; +class Preprocessor; /// \brief The preprocessor keeps track of this information for each /// file that is \#included. @@ -255,8 +256,8 @@ class HeaderSearch { const LangOptions &LangOpts; // HeaderSearch doesn't support default or copy construction. - HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION; - void operator=(const HeaderSearch&) LLVM_DELETED_FUNCTION; + HeaderSearch(const HeaderSearch&) = delete; + void operator=(const HeaderSearch&) = delete; friend class DirectoryLookup; @@ -419,8 +420,8 @@ public: /// /// \return false if \#including the file will have no effect or true /// if we should include it. - bool ShouldEnterIncludeFile(const FileEntry *File, bool isImport); - + bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File, + bool isImport); /// \brief Return whether the specified file is a normal header, /// a system header, or a C++ friendly system header. @@ -478,9 +479,6 @@ public: /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); - /// Returns true if modules are enabled. - bool enabledModules() const { return LangOpts.Modules; } - /// \brief Retrieve the name of the module file that should be used to /// load the given module. /// diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index c1f968b..07564b9 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -89,8 +89,8 @@ class Lexer : public PreprocessorLexer { // CurrentConflictMarkerState - The kind of conflict marker we are handling. ConflictMarkerKind CurrentConflictMarkerState; - Lexer(const Lexer &) LLVM_DELETED_FUNCTION; - void operator=(const Lexer &) LLVM_DELETED_FUNCTION; + Lexer(const Lexer &) = delete; + void operator=(const Lexer &) = delete; friend class Preprocessor; void InitLexer(const char *BufStart, const char *BufPtr, const char *BufEnd); @@ -323,6 +323,26 @@ public: const SourceManager &SM, const LangOptions &LangOpts); + /// \brief Given a token range, produce a corresponding CharSourceRange that + /// is not a token range. This allows the source range to be used by + /// components that don't have access to the lexer and thus can't find the + /// end of the range for themselves. + static CharSourceRange getAsCharRange(SourceRange Range, + const SourceManager &SM, + const LangOptions &LangOpts) { + SourceLocation End = getLocForEndOfToken(Range.getEnd(), 0, SM, LangOpts); + return End.isInvalid() ? CharSourceRange() + : CharSourceRange::getCharRange( + Range.getBegin(), End.getLocWithOffset(-1)); + } + static CharSourceRange getAsCharRange(CharSourceRange Range, + const SourceManager &SM, + const LangOptions &LangOpts) { + return Range.isTokenRange() + ? getAsCharRange(Range.getAsRange(), SM, LangOpts) + : Range; + } + /// \brief Returns true if the given MacroID location points at the first /// token of the macro expansion. /// diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index f60a152..5210e3f 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -57,13 +57,13 @@ public: NumericLiteralParser(StringRef TokSpelling, SourceLocation TokLoc, Preprocessor &PP); - bool hadError; - bool isUnsigned; - bool isLong; // This is *not* set for long long. - bool isLongLong; - bool isFloat; // 1.0f - bool isImaginary; // 1.0i - uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. + bool hadError : 1; + bool isUnsigned : 1; + bool isLong : 1; // This is *not* set for long long. + bool isLongLong : 1; + bool isFloat : 1; // 1.0f + bool isImaginary : 1; // 1.0i + uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. bool isIntegerLiteral() const { return !saw_period && !saw_exponent; diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h index d858ec2..243b143 100644 --- a/include/clang/Lex/MacroArgs.h +++ b/include/clang/Lex/MacroArgs.h @@ -56,7 +56,8 @@ class MacroArgs { MacroArgs(unsigned NumToks, bool varargsElided) : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(nullptr) {} - ~MacroArgs() {} + ~MacroArgs() = default; + public: /// MacroArgs ctor function - Create a new MacroArgs object with the specified /// macro and argument info. diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index ca5d497..81d075c 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -17,11 +17,15 @@ #include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Allocator.h" #include <cassert> namespace clang { +class Module; +class ModuleMacro; class Preprocessor; /// \brief Encapsulates the data about a macro definition (e.g. its tokens). @@ -109,7 +113,7 @@ class MacroInfo { // Only the Preprocessor gets to create and destroy these. MacroInfo(SourceLocation DefLoc); - ~MacroInfo() {} + ~MacroInfo() = default; public: /// \brief Return the location that the macro was defined at. @@ -241,6 +245,7 @@ public: tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } tokens_iterator tokens_end() const { return ReplacementTokens.end(); } bool tokens_empty() const { return ReplacementTokens.empty(); } + ArrayRef<Token> tokens() const { return ReplacementTokens; } /// \brief Add the specified token to the replacement text for the macro. void AddTokenToBody(const Token &Tok) { @@ -302,15 +307,8 @@ class DefMacroDirective; /// /// MacroDirectives, associated with an identifier, are used to model the macro /// history. Usually a macro definition (MacroInfo) is where a macro name -/// becomes active (MacroDirective) but modules can have their own macro -/// history, separate from the local (current translation unit) macro history. -/// -/// For example, if "@import A;" imports macro FOO, there will be a new local -/// MacroDirective created to indicate that "FOO" became active at the import -/// location. Module "A" itself will contain another MacroDirective in its macro -/// history (at the point of the definition of FOO) and both MacroDirectives -/// will point to the same MacroInfo object. -/// +/// becomes active (MacroDirective) but #pragma push_macro / pop_macro can +/// create additional DefMacroDirectives for the same MacroInfo. class MacroDirective { public: enum Kind { @@ -331,47 +329,15 @@ protected: /// \brief True if the macro directive was loaded from a PCH file. bool IsFromPCH : 1; - // Used by DefMacroDirective -----------------------------------------------// - - /// \brief Whether the definition of this macro is ambiguous, due to - /// multiple definitions coming in from multiple modules. - bool IsAmbiguous : 1; - // Used by VisibilityMacroDirective ----------------------------------------// /// \brief Whether the macro has public visibility (when described in a /// module). bool IsPublic : 1; - // Used by DefMacroDirective and UndefMacroDirective -----------------------// - - /// \brief True if this macro was imported from a module. - bool IsImported : 1; - - /// \brief For an imported directive, the number of modules whose macros are - /// overridden by this directive. Only used if IsImported. - unsigned NumOverrides : 26; - - unsigned *getModuleDataStart(); - const unsigned *getModuleDataStart() const { - return const_cast<MacroDirective*>(this)->getModuleDataStart(); - } - - MacroDirective(Kind K, SourceLocation Loc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None) + MacroDirective(Kind K, SourceLocation Loc) : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false), - IsAmbiguous(false), IsPublic(true), IsImported(ImportedFromModuleID), - NumOverrides(Overrides.size()) { - assert(NumOverrides == Overrides.size() && "too many overrides"); - assert((IsImported || !NumOverrides) && "overrides for non-module macro"); - - if (IsImported) { - unsigned *Extra = getModuleDataStart(); - *Extra++ = ImportedFromModuleID; - std::copy(Overrides.begin(), Overrides.end(), Extra); - } - } + IsPublic(true) {} public: Kind getKind() const { return Kind(MDKind); } @@ -394,34 +360,13 @@ public: void setIsFromPCH() { IsFromPCH = true; } - /// \brief True if this macro was imported from a module. - /// Note that this is never the case for a VisibilityMacroDirective. - bool isImported() const { return IsImported; } - - /// \brief If this directive was imported from a module, get the submodule - /// whose directive this is. Note that this may be different from the module - /// that owns the MacroInfo for a DefMacroDirective due to #pragma pop_macro - /// and similar effects. - unsigned getOwningModuleID() const { - if (isImported()) - return *getModuleDataStart(); - return 0; - } - - /// \brief Get the module IDs of modules whose macros are overridden by this - /// directive. Only valid if this is an imported directive. - ArrayRef<unsigned> getOverriddenModules() const { - assert(IsImported && "can only get overridden modules for imported macro"); - return llvm::makeArrayRef(getModuleDataStart() + 1, NumOverrides); - } - class DefInfo { DefMacroDirective *DefDirective; SourceLocation UndefLoc; bool IsPublic; public: - DefInfo() : DefDirective(nullptr) { } + DefInfo() : DefDirective(nullptr), IsPublic(true) { } DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc, bool isPublic) @@ -444,7 +389,7 @@ public: bool isValid() const { return DefDirective != nullptr; } bool isInvalid() const { return !isValid(); } - LLVM_EXPLICIT operator bool() const { return isValid(); } + explicit operator bool() const { return isValid(); } inline DefInfo getPreviousDefinition(); const DefInfo getPreviousDefinition() const { @@ -487,30 +432,17 @@ class DefMacroDirective : public MacroDirective { MacroInfo *Info; public: - explicit DefMacroDirective(MacroInfo *MI) - : MacroDirective(MD_Define, MI->getDefinitionLoc()), Info(MI) { - assert(MI && "MacroInfo is null"); - } - - DefMacroDirective(MacroInfo *MI, SourceLocation Loc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None) - : MacroDirective(MD_Define, Loc, ImportedFromModuleID, Overrides), - Info(MI) { + DefMacroDirective(MacroInfo *MI, SourceLocation Loc) + : MacroDirective(MD_Define, Loc), Info(MI) { assert(MI && "MacroInfo is null"); } + explicit DefMacroDirective(MacroInfo *MI) + : DefMacroDirective(MI, MI->getDefinitionLoc()) {} /// \brief The data for the macro definition. const MacroInfo *getInfo() const { return Info; } MacroInfo *getInfo() { return Info; } - /// \brief Determine whether this macro definition is ambiguous with - /// other macro definitions. - bool isAmbiguous() const { return IsAmbiguous; } - - /// \brief Set whether this macro definition is ambiguous. - void setAmbiguous(bool Val) { IsAmbiguous = Val; } - static bool classof(const MacroDirective *MD) { return MD->getKind() == MD_Define; } @@ -520,11 +452,9 @@ public: /// \brief A directive for an undefined macro. class UndefMacroDirective : public MacroDirective { public: - explicit UndefMacroDirective(SourceLocation UndefLoc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None) - : MacroDirective(MD_Undefine, UndefLoc, ImportedFromModuleID, Overrides) { - assert((UndefLoc.isValid() || ImportedFromModuleID) && "Invalid UndefLoc!"); + explicit UndefMacroDirective(SourceLocation UndefLoc) + : MacroDirective(MD_Undefine, UndefLoc) { + assert(UndefLoc.isValid() && "Invalid UndefLoc!"); } static bool classof(const MacroDirective *MD) { @@ -537,7 +467,7 @@ public: class VisibilityMacroDirective : public MacroDirective { public: explicit VisibilityMacroDirective(SourceLocation Loc, bool Public) - : MacroDirective(MD_Visibility, Loc) { + : MacroDirective(MD_Visibility, Loc) { IsPublic = Public; } @@ -551,13 +481,6 @@ public: static bool classof(const VisibilityMacroDirective *) { return true; } }; -inline unsigned *MacroDirective::getModuleDataStart() { - if (auto *Def = dyn_cast<DefMacroDirective>(this)) - return reinterpret_cast<unsigned*>(Def + 1); - else - return reinterpret_cast<unsigned*>(cast<UndefMacroDirective>(this) + 1); -} - inline SourceLocation MacroDirective::DefInfo::getLocation() const { if (isInvalid()) return SourceLocation(); @@ -577,6 +500,123 @@ MacroDirective::DefInfo::getPreviousDefinition() { return DefDirective->getPrevious()->getDefinition(); } -} // end namespace clang +/// \brief Represents a macro directive exported by a module. +/// +/// There's an instance of this class for every macro #define or #undef that is +/// the final directive for a macro name within a module. These entities also +/// represent the macro override graph. +/// +/// These are stored in a FoldingSet in the preprocessor. +class ModuleMacro : public llvm::FoldingSetNode { + /// The name defined by the macro. + IdentifierInfo *II; + /// The body of the #define, or nullptr if this is a #undef. + MacroInfo *Macro; + /// The module that exports this macro. + Module *OwningModule; + /// The number of module macros that override this one. + unsigned NumOverriddenBy; + /// The number of modules whose macros are directly overridden by this one. + unsigned NumOverrides; + //ModuleMacro *OverriddenMacros[NumOverrides]; + + friend class Preprocessor; + + ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides) + : II(II), Macro(Macro), OwningModule(OwningModule), + NumOverriddenBy(0), NumOverrides(Overrides.size()) { + std::copy(Overrides.begin(), Overrides.end(), + reinterpret_cast<ModuleMacro **>(this + 1)); + } + +public: + static ModuleMacro *create(Preprocessor &PP, Module *OwningModule, + IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides); + + void Profile(llvm::FoldingSetNodeID &ID) const { + return Profile(ID, OwningModule, II); + } + static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule, + IdentifierInfo *II) { + ID.AddPointer(OwningModule); + ID.AddPointer(II); + } + + /// Get the ID of the module that exports this macro. + Module *getOwningModule() const { return OwningModule; } + + /// Get definition for this exported #define, or nullptr if this + /// represents a #undef. + MacroInfo *getMacroInfo() const { return Macro; } + + /// Iterators over the overridden module IDs. + /// \{ + typedef ModuleMacro *const *overrides_iterator; + overrides_iterator overrides_begin() const { + return reinterpret_cast<overrides_iterator>(this + 1); + } + overrides_iterator overrides_end() const { + return overrides_begin() + NumOverrides; + } + ArrayRef<ModuleMacro *> overrides() const { + return llvm::makeArrayRef(overrides_begin(), overrides_end()); + } + /// \} + + /// Get the number of macros that override this one. + unsigned getNumOverridingMacros() const { return NumOverriddenBy; } +}; + +/// \brief A description of the current definition of a macro. +/// +/// The definition of a macro comprises a set of (at least one) defining +/// entities, which are either local MacroDirectives or imported ModuleMacros. +class MacroDefinition { + llvm::PointerIntPair<DefMacroDirective *, 1, bool> LatestLocalAndAmbiguous; + ArrayRef<ModuleMacro *> ModuleMacros; + +public: + MacroDefinition() : LatestLocalAndAmbiguous(), ModuleMacros() {} + MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs, + bool IsAmbiguous) + : LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {} + + /// \brief Determine whether there is a definition of this macro. + explicit operator bool() const { + return getLocalDirective() || !ModuleMacros.empty(); + } + + /// \brief Get the MacroInfo that should be used for this definition. + MacroInfo *getMacroInfo() const { + if (!ModuleMacros.empty()) + return ModuleMacros.back()->getMacroInfo(); + if (auto *MD = getLocalDirective()) + return MD->getMacroInfo(); + return nullptr; + } + + /// \brief \c true if the definition is ambiguous, \c false otherwise. + bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); } + + /// \brief Get the latest non-imported, non-\#undef'd macro definition + /// for this macro. + DefMacroDirective *getLocalDirective() const { + return LatestLocalAndAmbiguous.getPointer(); + } + + /// \brief Get the active module macros for this macro. + ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; } + + template <typename Fn> void forAllDefinitions(Fn F) const { + if (auto *MD = getLocalDirective()) + F(MD->getMacroInfo()); + for (auto *MM : getModuleMacros()) + F(MM->getMacroInfo()); + } +}; + +} // end namespace clang #endif diff --git a/include/clang/Lex/ModuleLoader.h b/include/clang/Lex/ModuleLoader.h index 36605c9..ae79650 100644 --- a/include/clang/Lex/ModuleLoader.h +++ b/include/clang/Lex/ModuleLoader.h @@ -99,8 +99,7 @@ public: /// \brief Make the given module visible. virtual void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, - SourceLocation ImportLoc, - bool Complain) = 0; + SourceLocation ImportLoc) = 0; /// \brief Load, create, or return global module. /// This function returns an existing global module index, if one diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index ed885a7..83a410d 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -64,6 +64,9 @@ private: /// \brief The top-level modules that are known. llvm::StringMap<Module *> Modules; + /// \brief The number of modules we have created in total. + unsigned NumCreatedModules; + public: /// \brief Flags describing the role of a module header. enum ModuleHeaderRole { @@ -104,7 +107,7 @@ public: // \brief Whether this known header is valid (i.e., it has an // associated module). - LLVM_EXPLICIT operator bool() const { + explicit operator bool() const { return Storage.getPointer() != nullptr; } }; @@ -434,11 +437,13 @@ public: /// \brief Sets the umbrella header of the given module to the given /// header. - void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader); + void setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, + Twine NameAsWritten); /// \brief Sets the umbrella directory of the given module to the given /// directory. - void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir); + void setUmbrellaDir(Module *Mod, const DirectoryEntry *UmbrellaDir, + Twine NameAsWritten); /// \brief Adds this header to the given module. /// \param Role The role of the header wrt the module. diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h index 056c58a..1ddb5d6 100644 --- a/include/clang/Lex/PPCallbacks.h +++ b/include/clang/Lex/PPCallbacks.h @@ -27,6 +27,7 @@ namespace clang { class SourceLocation; class Token; class IdentifierInfo; + class MacroDefinition; class MacroDirective; class MacroArgs; @@ -54,11 +55,12 @@ public: /// \brief Callback invoked whenever a source file is skipped as the result /// of header guard optimization. /// - /// \param ParentFile The file that \#included the skipped file. + /// \param SkippedFile The file that is skipped instead of entering \#include /// - /// \param FilenameTok The token in ParentFile that indicates the - /// skipped file. - virtual void FileSkipped(const FileEntry &ParentFile, + /// \param FilenameTok The file name token in \#include "FileName" directive + /// or macro expanded file name token from \#include MACRO(PARAMS) directive. + /// Note that FilenameTok contains corresponding quotes/angles symbols. + virtual void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) { } @@ -238,9 +240,9 @@ public: /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a /// macro invocation is found. - virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, - SourceRange Range, const MacroArgs *Args) { - } + virtual void MacroExpands(const Token &MacroNameTok, + const MacroDefinition &MD, SourceRange Range, + const MacroArgs *Args) {} /// \brief Hook called whenever a macro definition is seen. virtual void MacroDefined(const Token &MacroNameTok, @@ -251,12 +253,12 @@ public: /// /// MD is released immediately following this callback. virtual void MacroUndefined(const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { } /// \brief Hook called whenever the 'defined' operator is seen. /// \param MD The MacroDirective if the name was a macro, null otherwise. - virtual void Defined(const Token &MacroNameTok, const MacroDirective *MD, + virtual void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) { } @@ -293,17 +295,17 @@ public: /// \brief Hook called whenever an \#ifdef is seen. /// \param Loc the source location of the directive. /// \param MacroNameTok Information on the token being tested. - /// \param MD The MacroDirective if the name was a macro, null otherwise. + /// \param MD The MacroDefinition if the name was a macro, null otherwise. virtual void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { } /// \brief Hook called whenever an \#ifndef is seen. /// \param Loc the source location of the directive. /// \param MacroNameTok Information on the token being tested. - /// \param MD The MacroDirective if the name was a macro, null otherwise. + /// \param MD The MacroDefiniton if the name was a macro, null otherwise. virtual void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) { + const MacroDefinition &MD) { } /// \brief Hook called whenever an \#else is seen. @@ -336,11 +338,11 @@ public: Second->FileChanged(Loc, Reason, FileType, PrevFID); } - void FileSkipped(const FileEntry &ParentFile, + void FileSkipped(const FileEntry &SkippedFile, const Token &FilenameTok, SrcMgr::CharacteristicKind FileType) override { - First->FileSkipped(ParentFile, FilenameTok, FileType); - Second->FileSkipped(ParentFile, FilenameTok, FileType); + First->FileSkipped(SkippedFile, FilenameTok, FileType); + Second->FileSkipped(SkippedFile, FilenameTok, FileType); } bool FileNotFound(StringRef FileName, @@ -434,7 +436,7 @@ public: Second->PragmaWarningPop(Loc); } - void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD, + void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { First->MacroExpands(MacroNameTok, MD, Range, Args); Second->MacroExpands(MacroNameTok, MD, Range, Args); @@ -446,12 +448,12 @@ public: } void MacroUndefined(const Token &MacroNameTok, - const MacroDirective *MD) override { + const MacroDefinition &MD) override { First->MacroUndefined(MacroNameTok, MD); Second->MacroUndefined(MacroNameTok, MD); } - void Defined(const Token &MacroNameTok, const MacroDirective *MD, + void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) override { First->Defined(MacroNameTok, MD, Range); Second->Defined(MacroNameTok, MD, Range); @@ -478,14 +480,14 @@ public: /// \brief Hook called whenever an \#ifdef is seen. void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override { + const MacroDefinition &MD) override { First->Ifdef(Loc, MacroNameTok, MD); Second->Ifdef(Loc, MacroNameTok, MD); } /// \brief Hook called whenever an \#ifndef is seen. void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override { + const MacroDefinition &MD) override { First->Ifndef(Loc, MacroNameTok, MD); Second->Ifndef(Loc, MacroNameTok, MD); } diff --git a/include/clang/Lex/PPConditionalDirectiveRecord.h b/include/clang/Lex/PPConditionalDirectiveRecord.h index 00d2d57..8c52275 100644 --- a/include/clang/Lex/PPConditionalDirectiveRecord.h +++ b/include/clang/Lex/PPConditionalDirectiveRecord.h @@ -91,9 +91,9 @@ private: void Elif(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue, SourceLocation IfLoc) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; void Else(SourceLocation Loc, SourceLocation IfLoc) override; void Endif(SourceLocation Loc, SourceLocation IfLoc) override; }; diff --git a/include/clang/Lex/PTHLexer.h b/include/clang/Lex/PTHLexer.h index 54c91f6..904be79 100644 --- a/include/clang/Lex/PTHLexer.h +++ b/include/clang/Lex/PTHLexer.h @@ -44,8 +44,8 @@ class PTHLexer : public PreprocessorLexer { /// to process when doing quick skipping of preprocessor blocks. const unsigned char* CurPPCondPtr; - PTHLexer(const PTHLexer &) LLVM_DELETED_FUNCTION; - void operator=(const PTHLexer &) LLVM_DELETED_FUNCTION; + PTHLexer(const PTHLexer &) = delete; + void operator=(const PTHLexer &) = delete; /// ReadToken - Used by PTHLexer to read tokens TokBuf. void ReadToken(Token& T); @@ -64,8 +64,7 @@ protected: PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D, const unsigned char* ppcond, PTHManager &PM); public: - - ~PTHLexer() {} + ~PTHLexer() override {} /// Lex - Return the next token. bool Lex(Token &Tok); diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h index 64ecf5f..a4198f8 100644 --- a/include/clang/Lex/PTHManager.h +++ b/include/clang/Lex/PTHManager.h @@ -19,6 +19,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Lex/PTHLexer.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/OnDiskHashTable.h" #include <string> @@ -91,8 +92,8 @@ class PTHManager : public IdentifierInfoLookup { std::unique_ptr<PTHStringIdLookup> stringIdLookup, unsigned numIds, const unsigned char *spellingBase, const char *originalSourceFile); - PTHManager(const PTHManager &) LLVM_DELETED_FUNCTION; - void operator=(const PTHManager &) LLVM_DELETED_FUNCTION; + PTHManager(const PTHManager &) = delete; + void operator=(const PTHManager &) = delete; /// getSpellingAtPTHOffset - Used by PTHLexer classes to get the cached /// spelling for a token. @@ -112,7 +113,7 @@ public: // The current PTH version. enum { Version = 10 }; - ~PTHManager(); + ~PTHManager() override; /// getOriginalSourceFile - Return the full path to the original header /// file name that was used to generate the PTH cache. diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h index 4123bae..70fcfda 100644 --- a/include/clang/Lex/Pragma.h +++ b/include/clang/Lex/Pragma.h @@ -93,7 +93,7 @@ class PragmaNamespace : public PragmaHandler { llvm::StringMap<PragmaHandler*> Handlers; public: explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {} - virtual ~PragmaNamespace(); + ~PragmaNamespace() override; /// FindHandler - Check to see if there is already a handler for the /// specified name. If not, return the handler for the null name if it diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h index 4609fe3..53367ab 100644 --- a/include/clang/Lex/PreprocessingRecord.h +++ b/include/clang/Lex/PreprocessingRecord.h @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include <vector> @@ -35,11 +36,11 @@ void* operator new(size_t bytes, clang::PreprocessingRecord& PR, unsigned alignment = 8) throw(); /// \brief Frees memory allocated in a Clang preprocessing record. -void operator delete(void* ptr, clang::PreprocessingRecord& PR, +void operator delete(void *ptr, clang::PreprocessingRecord &PR, unsigned) throw(); namespace clang { - class MacroDefinition; + class MacroDefinitionRecord; class FileEntry; /// \brief Base class that describes a preprocessed entity, which may be a @@ -132,19 +133,20 @@ namespace clang { PD->getKind() <= LastPreprocessingDirective; } }; - + /// \brief Record the location of a macro definition. - class MacroDefinition : public PreprocessingDirective { + class MacroDefinitionRecord : public PreprocessingDirective { /// \brief The name of the macro being defined. const IdentifierInfo *Name; public: - explicit MacroDefinition(const IdentifierInfo *Name, SourceRange Range) - : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) { } - + explicit MacroDefinitionRecord(const IdentifierInfo *Name, + SourceRange Range) + : PreprocessingDirective(MacroDefinitionKind, Range), Name(Name) {} + /// \brief Retrieve the name of the macro being defined. const IdentifierInfo *getName() const { return Name; } - + /// \brief Retrieve the location of the macro name in the definition. SourceLocation getLocation() const { return getSourceRange().getBegin(); } @@ -158,31 +160,31 @@ namespace clang { class MacroExpansion : public PreprocessedEntity { /// \brief The definition of this macro or the name of the macro if it is /// a builtin macro. - llvm::PointerUnion<IdentifierInfo *, MacroDefinition *> NameOrDef; + llvm::PointerUnion<IdentifierInfo *, MacroDefinitionRecord *> NameOrDef; public: MacroExpansion(IdentifierInfo *BuiltinName, SourceRange Range) - : PreprocessedEntity(MacroExpansionKind, Range), - NameOrDef(BuiltinName) { } + : PreprocessedEntity(MacroExpansionKind, Range), + NameOrDef(BuiltinName) {} - MacroExpansion(MacroDefinition *Definition, SourceRange Range) - : PreprocessedEntity(MacroExpansionKind, Range), - NameOrDef(Definition) { } + MacroExpansion(MacroDefinitionRecord *Definition, SourceRange Range) + : PreprocessedEntity(MacroExpansionKind, Range), NameOrDef(Definition) { + } /// \brief True if it is a builtin macro. bool isBuiltinMacro() const { return NameOrDef.is<IdentifierInfo *>(); } - + /// \brief The name of the macro being expanded. const IdentifierInfo *getName() const { - if (MacroDefinition *Def = getDefinition()) + if (MacroDefinitionRecord *Def = getDefinition()) return Def->getName(); - return NameOrDef.get<IdentifierInfo*>(); + return NameOrDef.get<IdentifierInfo *>(); } - + /// \brief The definition of the macro being expanded. May return null if /// this is a builtin macro. - MacroDefinition *getDefinition() const { - return NameOrDef.dyn_cast<MacroDefinition *>(); + MacroDefinitionRecord *getDefinition() const { + return NameOrDef.dyn_cast<MacroDefinitionRecord *>(); } // Implement isa/cast/dyncast/etc. @@ -329,7 +331,7 @@ namespace clang { } /// \brief Mapping from MacroInfo structures to their definitions. - llvm::DenseMap<const MacroInfo *, MacroDefinition *> MacroDefinitions; + llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *> MacroDefinitions; /// \brief External source of preprocessed entities. ExternalPreprocessingRecordSource *ExternalSource; @@ -360,12 +362,12 @@ namespace clang { unsigned allocateLoadedEntities(unsigned NumEntities); /// \brief Register a new macro definition. - void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinition *Def); - + void RegisterMacroDefinition(MacroInfo *Macro, MacroDefinitionRecord *Def); + public: /// \brief Construct a new preprocessing record. explicit PreprocessingRecord(SourceManager &SM); - + /// \brief Allocate memory in the preprocessing record. void *Allocate(unsigned Size, unsigned Align = 8) { return BumpAlloc.Allocate(Size, Align); @@ -378,125 +380,44 @@ namespace clang { SourceManager &getSourceManager() const { return SourceMgr; } - // Iteration over the preprocessed entities. - class iterator { + /// Iteration over the preprocessed entities. + /// + /// In a complete iteration, the iterator walks the range [-M, N), + /// where negative values are used to indicate preprocessed entities + /// loaded from the external source while non-negative values are used to + /// indicate preprocessed entities introduced by the current preprocessor. + /// However, to provide iteration in source order (for, e.g., chained + /// precompiled headers), dereferencing the iterator flips the negative + /// values (corresponding to loaded entities), so that position -M + /// corresponds to element 0 in the loaded entities vector, position -M+1 + /// corresponds to element 1 in the loaded entities vector, etc. This + /// gives us a reasonably efficient, source-order walk. + /// + /// We define this as a wrapping iterator around an int. The + /// iterator_adaptor_base class forwards the iterator methods to basic + /// integer arithmetic. + class iterator : public llvm::iterator_adaptor_base< + iterator, int, std::random_access_iterator_tag, + PreprocessedEntity *, int, PreprocessedEntity *, + PreprocessedEntity *> { PreprocessingRecord *Self; - - /// \brief Position within the preprocessed entity sequence. - /// - /// In a complete iteration, the Position field walks the range [-M, N), - /// where negative values are used to indicate preprocessed entities - /// loaded from the external source while non-negative values are used to - /// indicate preprocessed entities introduced by the current preprocessor. - /// However, to provide iteration in source order (for, e.g., chained - /// precompiled headers), dereferencing the iterator flips the negative - /// values (corresponding to loaded entities), so that position -M - /// corresponds to element 0 in the loaded entities vector, position -M+1 - /// corresponds to element 1 in the loaded entities vector, etc. This - /// gives us a reasonably efficient, source-order walk. - int Position; - - public: - typedef PreprocessedEntity *value_type; - typedef value_type& reference; - typedef value_type* pointer; - typedef std::random_access_iterator_tag iterator_category; - typedef int difference_type; - - iterator() : Self(nullptr), Position(0) { } - + iterator(PreprocessingRecord *Self, int Position) - : Self(Self), Position(Position) { } - - value_type operator*() const { - bool isLoaded = Position < 0; + : iterator::iterator_adaptor_base(Position), Self(Self) {} + friend class PreprocessingRecord; + + public: + iterator() : iterator(nullptr, 0) {} + + PreprocessedEntity *operator*() const { + bool isLoaded = this->I < 0; unsigned Index = isLoaded ? - Self->LoadedPreprocessedEntities.size() + Position : Position; + Self->LoadedPreprocessedEntities.size() + this->I : this->I; PPEntityID ID = Self->getPPEntityID(Index, isLoaded); return Self->getPreprocessedEntity(ID); } - - value_type operator[](difference_type D) { - return *(*this + D); - } - - iterator &operator++() { - ++Position; - return *this; - } - - iterator operator++(int) { - iterator Prev(*this); - ++Position; - return Prev; - } - - iterator &operator--() { - --Position; - return *this; - } - - iterator operator--(int) { - iterator Prev(*this); - --Position; - return Prev; - } - - friend bool operator==(const iterator &X, const iterator &Y) { - return X.Position == Y.Position; - } - - friend bool operator!=(const iterator &X, const iterator &Y) { - return X.Position != Y.Position; - } - - friend bool operator<(const iterator &X, const iterator &Y) { - return X.Position < Y.Position; - } - - friend bool operator>(const iterator &X, const iterator &Y) { - return X.Position > Y.Position; - } - - friend bool operator<=(const iterator &X, const iterator &Y) { - return X.Position < Y.Position; - } - - friend bool operator>=(const iterator &X, const iterator &Y) { - return X.Position > Y.Position; - } - - friend iterator& operator+=(iterator &X, difference_type D) { - X.Position += D; - return X; - } - - friend iterator& operator-=(iterator &X, difference_type D) { - X.Position -= D; - return X; - } - - friend iterator operator+(iterator X, difference_type D) { - X.Position += D; - return X; - } - - friend iterator operator+(difference_type D, iterator X) { - X.Position += D; - return X; - } - - friend difference_type operator-(const iterator &X, const iterator &Y) { - return X.Position - Y.Position; - } - - friend iterator operator-(iterator X, difference_type D) { - X.Position -= D; - return X; - } - friend class PreprocessingRecord; + PreprocessedEntity *operator->() const { return **this; } }; - friend class iterator; /// \brief Begin iterator for all preprocessed entities. iterator begin() { @@ -518,23 +439,24 @@ namespace clang { return iterator(this, PreprocessedEntities.size()); } - /// \brief begin/end iterator pair for the given range of loaded + /// \brief iterator range for the given range of loaded /// preprocessed entities. - std::pair<iterator, iterator> - getIteratorsForLoadedRange(unsigned start, unsigned count) { + llvm::iterator_range<iterator> getIteratorsForLoadedRange(unsigned start, + unsigned count) { unsigned end = start + count; assert(end <= LoadedPreprocessedEntities.size()); - return std::make_pair( - iterator(this, int(start)-LoadedPreprocessedEntities.size()), - iterator(this, int(end)-LoadedPreprocessedEntities.size())); + return llvm::make_range( + iterator(this, int(start) - LoadedPreprocessedEntities.size()), + iterator(this, int(end) - LoadedPreprocessedEntities.size())); } - /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities - /// that source range \p R encompasses. + /// \brief Returns a range of preprocessed entities that source range \p R + /// encompasses. /// /// \param R the range to look for preprocessed entities. /// - std::pair<iterator, iterator> getPreprocessedEntitiesInRange(SourceRange R); + llvm::iterator_range<iterator> + getPreprocessedEntitiesInRange(SourceRange R); /// \brief Returns true if the preprocessed entity that \p PPEI iterator /// points to is coming from the file \p FID. @@ -555,10 +477,10 @@ namespace clang { ExternalPreprocessingRecordSource *getExternalSource() const { return ExternalSource; } - + /// \brief Retrieve the macro definition that corresponds to the given /// \c MacroInfo. - MacroDefinition *findMacroDefinition(const MacroInfo *MI); + MacroDefinitionRecord *findMacroDefinition(const MacroInfo *MI); /// \brief Retrieve all ranges that got skipped while preprocessing. const std::vector<SourceRange> &getSkippedRanges() const { @@ -566,10 +488,10 @@ namespace clang { } private: - void MacroExpands(const Token &Id, const MacroDirective *MD, + void MacroExpands(const Token &Id, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override; void MacroDefined(const Token &Id, const MacroDirective *MD) override; - void MacroUndefined(const Token &Id, const MacroDirective *MD) override; + void MacroUndefined(const Token &Id, const MacroDefinition &MD) override; void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, @@ -577,11 +499,11 @@ namespace clang { StringRef RelativePath, const Module *Imported) override; void Ifdef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; void Ifndef(SourceLocation Loc, const Token &MacroNameTok, - const MacroDirective *MD) override; + const MacroDefinition &MD) override; /// \brief Hook called whenever the 'defined' operator is seen. - void Defined(const Token &MacroNameTok, const MacroDirective *MD, + void Defined(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range) override; void SourceRangeSkipped(SourceRange Range) override; diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 326f519..ea15dbd 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -31,6 +31,7 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" #include <memory> #include <vector> @@ -356,19 +357,185 @@ class Preprocessor : public RefCountedBase<Preprocessor> { struct MacroExpandsInfo { Token Tok; - MacroDirective *MD; + MacroDefinition MD; SourceRange Range; - MacroExpandsInfo(Token Tok, MacroDirective *MD, SourceRange Range) + MacroExpandsInfo(Token Tok, MacroDefinition MD, SourceRange Range) : Tok(Tok), MD(MD), Range(Range) { } }; SmallVector<MacroExpandsInfo, 2> DelayedMacroExpandsCallbacks; + /// Information about a name that has been used to define a module macro. + struct ModuleMacroInfo { + ModuleMacroInfo(MacroDirective *MD) + : MD(MD), ActiveModuleMacrosGeneration(0), IsAmbiguous(false) {} + + /// The most recent macro directive for this identifier. + MacroDirective *MD; + /// The active module macros for this identifier. + llvm::TinyPtrVector<ModuleMacro*> ActiveModuleMacros; + /// The generation number at which we last updated ActiveModuleMacros. + /// \see Preprocessor::VisibleModules. + unsigned ActiveModuleMacrosGeneration; + /// Whether this macro name is ambiguous. + bool IsAmbiguous; + /// The module macros that are overridden by this macro. + llvm::TinyPtrVector<ModuleMacro*> OverriddenMacros; + }; + + /// The state of a macro for an identifier. + class MacroState { + mutable llvm::PointerUnion<MacroDirective *, ModuleMacroInfo *> State; + + ModuleMacroInfo *getModuleInfo(Preprocessor &PP, + const IdentifierInfo *II) const { + // FIXME: Find a spare bit on IdentifierInfo and store a + // HasModuleMacros flag. + if (!II->hasMacroDefinition() || !PP.getLangOpts().Modules || + !PP.CurSubmoduleState->VisibleModules.getGeneration()) + return nullptr; + + auto *Info = State.dyn_cast<ModuleMacroInfo*>(); + if (!Info) { + Info = new (PP.getPreprocessorAllocator()) + ModuleMacroInfo(State.get<MacroDirective *>()); + State = Info; + } + + if (PP.CurSubmoduleState->VisibleModules.getGeneration() != + Info->ActiveModuleMacrosGeneration) + PP.updateModuleMacroInfo(II, *Info); + return Info; + } + + public: + MacroState() : MacroState(nullptr) {} + MacroState(MacroDirective *MD) : State(MD) {} + MacroState(MacroState &&O) LLVM_NOEXCEPT : State(O.State) { + O.State = (MacroDirective *)nullptr; + } + MacroState &operator=(MacroState &&O) LLVM_NOEXCEPT { + auto S = O.State; + O.State = (MacroDirective *)nullptr; + State = S; + return *this; + } + ~MacroState() { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + Info->~ModuleMacroInfo(); + } + + MacroDirective *getLatest() const { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + return Info->MD; + return State.get<MacroDirective*>(); + } + void setLatest(MacroDirective *MD) { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + Info->MD = MD; + else + State = MD; + } + + bool isAmbiguous(Preprocessor &PP, const IdentifierInfo *II) const { + auto *Info = getModuleInfo(PP, II); + return Info ? Info->IsAmbiguous : false; + } + ArrayRef<ModuleMacro *> + getActiveModuleMacros(Preprocessor &PP, const IdentifierInfo *II) const { + if (auto *Info = getModuleInfo(PP, II)) + return Info->ActiveModuleMacros; + return None; + } + + MacroDirective::DefInfo findDirectiveAtLoc(SourceLocation Loc, + SourceManager &SourceMgr) const { + // FIXME: Incorporate module macros into the result of this. + return getLatest()->findDirectiveAtLoc(Loc, SourceMgr); + } + + void overrideActiveModuleMacros(Preprocessor &PP, IdentifierInfo *II) { + if (auto *Info = getModuleInfo(PP, II)) { + for (auto *Active : Info->ActiveModuleMacros) + Info->OverriddenMacros.push_back(Active); + Info->ActiveModuleMacros.clear(); + Info->IsAmbiguous = false; + } + } + ArrayRef<ModuleMacro*> getOverriddenMacros() const { + if (auto *Info = State.dyn_cast<ModuleMacroInfo*>()) + return Info->OverriddenMacros; + return None; + } + void setOverriddenMacros(Preprocessor &PP, + ArrayRef<ModuleMacro *> Overrides) { + auto *Info = State.dyn_cast<ModuleMacroInfo*>(); + if (!Info) { + if (Overrides.empty()) + return; + Info = new (PP.getPreprocessorAllocator()) + ModuleMacroInfo(State.get<MacroDirective *>()); + State = Info; + } + Info->OverriddenMacros.clear(); + Info->OverriddenMacros.insert(Info->OverriddenMacros.end(), + Overrides.begin(), Overrides.end()); + Info->ActiveModuleMacrosGeneration = 0; + } + }; + /// For each IdentifierInfo that was associated with a macro, we /// keep a mapping to the history of all macro definitions and #undefs in /// the reverse order (the latest one is in the head of the list). - llvm::DenseMap<const IdentifierInfo*, MacroDirective*> Macros; + /// + /// This mapping lives within the \p CurSubmoduleState. + typedef llvm::DenseMap<const IdentifierInfo *, MacroState> MacroMap; + friend class ASTReader; - + + struct SubmoduleState; + + /// \brief Information about a submodule that we're currently building. + struct BuildingSubmoduleInfo { + BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, + SubmoduleState *OuterSubmoduleState) + : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) { + } + + /// The module that we are building. + Module *M; + /// The location at which the module was included. + SourceLocation ImportLoc; + /// The previous SubmoduleState. + SubmoduleState *OuterSubmoduleState; + }; + SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack; + + /// \brief Information about a submodule's preprocessor state. + struct SubmoduleState { + /// The macros for the submodule. + MacroMap Macros; + /// The set of modules that are visible within the submodule. + VisibleModuleSet VisibleModules; + // FIXME: CounterValue? + // FIXME: PragmaPushMacroInfo? + }; + std::map<Module*, SubmoduleState> Submodules; + + /// The preprocessor state for preprocessing outside of any submodule. + SubmoduleState NullSubmoduleState; + + /// The current submodule state. Will be \p NullSubmoduleState if we're not + /// in a submodule. + SubmoduleState *CurSubmoduleState; + + /// The set of known macros exported from modules. + llvm::FoldingSet<ModuleMacro> ModuleMacros; + + /// The list of module macros, for each identifier, that are not overridden by + /// any other module macro. + llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>> + LeafModuleMacros; + /// \brief Macros that we want to warn because they are not used at the end /// of the translation unit. /// @@ -427,7 +594,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \c createPreprocessingRecord() prior to preprocessing. PreprocessingRecord *Record; -private: // Cached tokens state. + /// Cached tokens state. typedef SmallVector<Token, 1> CachedTokensTy; /// \brief Cached tokens are stored here when we do backtracking or @@ -507,6 +674,7 @@ public: HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; } IdentifierTable &getIdentifierTable() { return Identifiers; } + const IdentifierTable &getIdentifierTable() const { return Identifiers; } SelectorTable &getSelectorTable() { return Selectors; } Builtin::Context &getBuiltinInfo() { return BuiltinInfo; } llvm::BumpPtrAllocator &getPreprocessorAllocator() { return BP; } @@ -601,59 +769,114 @@ public: } /// \} - /// \brief Given an identifier, return its latest MacroDirective if it is - /// \#defined or null if it isn't \#define'd. - MacroDirective *getMacroDirective(IdentifierInfo *II) const { + bool isMacroDefined(StringRef Id) { + return isMacroDefined(&Identifiers.get(Id)); + } + bool isMacroDefined(const IdentifierInfo *II) { + return II->hasMacroDefinition() && + (!getLangOpts().Modules || (bool)getMacroDefinition(II)); + } + + MacroDefinition getMacroDefinition(const IdentifierInfo *II) { + if (!II->hasMacroDefinition()) + return MacroDefinition(); + + MacroState &S = CurSubmoduleState->Macros[II]; + auto *MD = S.getLatest(); + while (MD && isa<VisibilityMacroDirective>(MD)) + MD = MD->getPrevious(); + return MacroDefinition(dyn_cast_or_null<DefMacroDirective>(MD), + S.getActiveModuleMacros(*this, II), + S.isAmbiguous(*this, II)); + } + + MacroDefinition getMacroDefinitionAtLoc(const IdentifierInfo *II, + SourceLocation Loc) { + if (!II->hadMacroDefinition()) + return MacroDefinition(); + + MacroState &S = CurSubmoduleState->Macros[II]; + MacroDirective::DefInfo DI; + if (auto *MD = S.getLatest()) + DI = MD->findDirectiveAtLoc(Loc, getSourceManager()); + // FIXME: Compute the set of active module macros at the specified location. + return MacroDefinition(DI.getDirective(), + S.getActiveModuleMacros(*this, II), + S.isAmbiguous(*this, II)); + } + + /// \brief Given an identifier, return its latest non-imported MacroDirective + /// if it is \#define'd and not \#undef'd, or null if it isn't \#define'd. + MacroDirective *getLocalMacroDirective(const IdentifierInfo *II) const { if (!II->hasMacroDefinition()) return nullptr; - MacroDirective *MD = getMacroDirectiveHistory(II); - assert(MD->isDefined() && "Macro is undefined!"); + auto *MD = getLocalMacroDirectiveHistory(II); + if (!MD || MD->getDefinition().isUndefined()) + return nullptr; + return MD; } - const MacroInfo *getMacroInfo(IdentifierInfo *II) const { + const MacroInfo *getMacroInfo(const IdentifierInfo *II) const { return const_cast<Preprocessor*>(this)->getMacroInfo(II); } - MacroInfo *getMacroInfo(IdentifierInfo *II) { - if (MacroDirective *MD = getMacroDirective(II)) - return MD->getMacroInfo(); + MacroInfo *getMacroInfo(const IdentifierInfo *II) { + if (!II->hasMacroDefinition()) + return nullptr; + if (auto MD = getMacroDefinition(II)) + return MD.getMacroInfo(); return nullptr; } - /// \brief Given an identifier, return the (probably #undef'd) MacroInfo - /// representing the most recent macro definition. + /// \brief Given an identifier, return the latest non-imported macro + /// directive for that identifier. /// - /// One can iterate over all previous macro definitions from the most recent - /// one. This should only be called for identifiers that hadMacroDefinition(). - MacroDirective *getMacroDirectiveHistory(const IdentifierInfo *II) const; + /// One can iterate over all previous macro directives from the most recent + /// one. + MacroDirective *getLocalMacroDirectiveHistory(const IdentifierInfo *II) const; /// \brief Add a directive to the macro directive history for this identifier. void appendMacroDirective(IdentifierInfo *II, MacroDirective *MD); DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI, - SourceLocation Loc, - unsigned ImportedFromModuleID, - ArrayRef<unsigned> Overrides) { - DefMacroDirective *MD = - AllocateDefMacroDirective(MI, Loc, ImportedFromModuleID, Overrides); + SourceLocation Loc) { + DefMacroDirective *MD = AllocateDefMacroDirective(MI, Loc); appendMacroDirective(II, MD); return MD; } - DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, MacroInfo *MI){ - return appendDefMacroDirective(II, MI, MI->getDefinitionLoc(), 0, None); + DefMacroDirective *appendDefMacroDirective(IdentifierInfo *II, + MacroInfo *MI) { + return appendDefMacroDirective(II, MI, MI->getDefinitionLoc()); } /// \brief Set a MacroDirective that was loaded from a PCH file. void setLoadedMacroDirective(IdentifierInfo *II, MacroDirective *MD); + /// \brief Register an exported macro for a module and identifier. + ModuleMacro *addModuleMacro(Module *Mod, IdentifierInfo *II, MacroInfo *Macro, + ArrayRef<ModuleMacro *> Overrides, bool &IsNew); + ModuleMacro *getModuleMacro(Module *Mod, IdentifierInfo *II); + + /// \brief Get the list of leaf (non-overridden) module macros for a name. + ArrayRef<ModuleMacro*> getLeafModuleMacros(const IdentifierInfo *II) const { + auto I = LeafModuleMacros.find(II); + if (I != LeafModuleMacros.end()) + return I->second; + return None; + } + /// \{ /// Iterators for the macro history table. Currently defined macros have /// IdentifierInfo::hasMacroDefinition() set and an empty /// MacroInfo::getUndefLoc() at the head of the list. - typedef llvm::DenseMap<const IdentifierInfo *, - MacroDirective*>::const_iterator macro_iterator; + typedef MacroMap::const_iterator macro_iterator; macro_iterator macro_begin(bool IncludeExternalMacros = true) const; macro_iterator macro_end(bool IncludeExternalMacros = true) const; + llvm::iterator_range<macro_iterator> + macros(bool IncludeExternalMacros = true) const { + return llvm::make_range(macro_begin(IncludeExternalMacros), + macro_end(IncludeExternalMacros)); + } /// \} /// \brief Return the name of the macro defined before \p Loc that has @@ -806,6 +1029,12 @@ public: void LexAfterModuleImport(Token &Result); + void makeModuleVisible(Module *M, SourceLocation Loc); + + SourceLocation getModuleImportLoc(Module *M) const { + return CurSubmoduleState->VisibleModules.getImportLoc(M); + } + /// \brief Lex a string literal, which may be the concatenation of multiple /// string literals and may even come from macro expansion. /// \returns true on success, false if a error diagnostic has been generated. @@ -923,7 +1152,7 @@ public: /// location of an annotation token. SourceLocation getLastCachedTokenLocation() const { assert(CachedLexPos != 0); - return CachedTokens[CachedLexPos-1].getLocation(); + return CachedTokens[CachedLexPos-1].getLastLoc(); } /// \brief Replace the last token with an annotation token. @@ -1188,6 +1417,7 @@ public: void DumpToken(const Token &Tok, bool DumpFlags = false) const; void DumpLocation(SourceLocation Loc) const; void DumpMacro(const MacroInfo &MI) const; + void dumpMacroInfo(const IdentifierInfo *II); /// \brief Given a location that specifies the start of a /// token, return a new location that specifies a character within the token. @@ -1406,17 +1636,19 @@ private: void PropagateLineStartLeadingSpaceInfo(Token &Result); + void EnterSubmodule(Module *M, SourceLocation ImportLoc); + void LeaveSubmodule(); + + /// Update the set of active module macros and ambiguity flag for a module + /// macro name. + void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info); + /// \brief Allocate a new MacroInfo object. MacroInfo *AllocateMacroInfo(); - DefMacroDirective * - AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None); - UndefMacroDirective * - AllocateUndefMacroDirective(SourceLocation UndefLoc, - unsigned ImportedFromModuleID = 0, - ArrayRef<unsigned> Overrides = None); + DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI, + SourceLocation Loc); + UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc); VisibilityMacroDirective *AllocateVisibilityMacroDirective(SourceLocation Loc, bool isPublic); @@ -1470,7 +1702,7 @@ private: /// If an identifier token is read that is to be expanded as a macro, handle /// it and return the next token as 'Tok'. If we lexed a token, return true; /// otherwise the caller should lex again. - bool HandleMacroExpandedIdentifier(Token &Tok, MacroDirective *MD); + bool HandleMacroExpandedIdentifier(Token &Tok, const MacroDefinition &MD); /// \brief Cache macro expanded tokens for TokenLexers. // @@ -1572,11 +1804,18 @@ private: void HandleImportDirective(SourceLocation HashLoc, Token &Tok); void HandleMicrosoftImportDirective(Token &Tok); +public: // Module inclusion testing. - /// \brief Find the module for the source or header file that \p FilenameLoc - /// points to. - Module *getModuleForLocation(SourceLocation FilenameLoc); + /// \brief Find the module that owns the source or header file that + /// \p Loc points to. If the location is in a file that was included + /// into a module, or is outside any module, returns nullptr. + Module *getModuleForLocation(SourceLocation Loc); + + /// \brief Find the module that contains the specified location, either + /// directly or indirectly. + Module *getModuleContainingLocation(SourceLocation Loc); +private: // Macro handling. void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); void HandleUndefDirective(Token &Tok); diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h index 3a91fa7..6d6cf05 100644 --- a/include/clang/Lex/PreprocessorLexer.h +++ b/include/clang/Lex/PreprocessorLexer.h @@ -69,8 +69,8 @@ protected: /// we are currently in. SmallVector<PPConditionalInfo, 4> ConditionalStack; - PreprocessorLexer(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; - void operator=(const PreprocessorLexer &) LLVM_DELETED_FUNCTION; + PreprocessorLexer(const PreprocessorLexer &) = delete; + void operator=(const PreprocessorLexer &) = delete; friend class Preprocessor; PreprocessorLexer(Preprocessor *pp, FileID fid); diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index 4a53c9c..e087809 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -35,8 +35,8 @@ class IdentifierInfo; /// can be represented by a single typename annotation token that carries /// information about the SourceRange of the tokens and the type object. class Token { - /// The location of the token. - SourceLocation Loc; + /// The location of the token. This is actually a SourceLocation. + unsigned Loc; // Conceptually these next two fields could be in a union. However, this // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical @@ -114,13 +114,15 @@ public: /// \brief Return a source location identifier for the specified /// offset in the current file. - SourceLocation getLocation() const { return Loc; } + SourceLocation getLocation() const { + return SourceLocation::getFromRawEncoding(Loc); + } unsigned getLength() const { assert(!isAnnotation() && "Annotation tokens have no length field"); return UintData; } - void setLocation(SourceLocation L) { Loc = L; } + void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } void setLength(unsigned Len) { assert(!isAnnotation() && "Annotation tokens have no length field"); UintData = Len; @@ -128,7 +130,7 @@ public: SourceLocation getAnnotationEndLoc() const { assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); - return SourceLocation::getFromRawEncoding(UintData); + return SourceLocation::getFromRawEncoding(UintData ? UintData : Loc); } void setAnnotationEndLoc(SourceLocation L) { assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); @@ -139,6 +141,11 @@ public: return isAnnotation() ? getAnnotationEndLoc() : getLocation(); } + SourceLocation getEndLoc() const { + return isAnnotation() ? getAnnotationEndLoc() + : getLocation().getLocWithOffset(getLength()); + } + /// \brief SourceRange of the group of tokens that this annotation token /// represents. SourceRange getAnnotationRange() const { @@ -157,7 +164,7 @@ public: Flags = 0; PtrData = nullptr; UintData = 0; - Loc = SourceLocation(); + Loc = SourceLocation().getRawEncoding(); } IdentifierInfo *getIdentifierInfo() const { diff --git a/include/clang/Lex/TokenLexer.h b/include/clang/Lex/TokenLexer.h index 306f98e..3119736 100644 --- a/include/clang/Lex/TokenLexer.h +++ b/include/clang/Lex/TokenLexer.h @@ -99,8 +99,8 @@ class TokenLexer { /// should not be subject to further macro expansion. bool DisableMacroExpansion : 1; - TokenLexer(const TokenLexer &) LLVM_DELETED_FUNCTION; - void operator=(const TokenLexer &) LLVM_DELETED_FUNCTION; + TokenLexer(const TokenLexer &) = delete; + void operator=(const TokenLexer &) = delete; public: /// Create a TokenLexer for the specified macro with the specified actual /// arguments. Note that this ctor takes ownership of the ActualArgs pointer. diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index f12bec6..caba77b 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -235,7 +235,7 @@ class Parser : public CodeCompletionHandler { public: Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies); - ~Parser(); + ~Parser() override; const LangOptions &getLangOpts() const { return PP.getLangOpts(); } const TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); } @@ -245,8 +245,8 @@ public: const Token &getCurToken() const { return Tok; } Scope *getCurScope() const { return Actions.getCurScope(); } - void incrementMSLocalManglingNumber() const { - return Actions.incrementMSLocalManglingNumber(); + void incrementMSManglingNumber() const { + return Actions.incrementMSManglingNumber(); } Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); } @@ -745,8 +745,8 @@ public: /// the parser will exit the scope. class ParseScope { Parser *Self; - ParseScope(const ParseScope &) LLVM_DELETED_FUNCTION; - void operator=(const ParseScope &) LLVM_DELETED_FUNCTION; + ParseScope(const ParseScope &) = delete; + void operator=(const ParseScope &) = delete; public: // ParseScope - Construct a new object to manage a scope in the @@ -759,7 +759,7 @@ public: Self->EnterScope(ScopeFlags); else { if (BeforeCompoundStmt) - Self->incrementMSLocalManglingNumber(); + Self->incrementMSManglingNumber(); this->Self = nullptr; } @@ -790,8 +790,8 @@ private: class ParseScopeFlags { Scope *CurScope; unsigned OldFlags; - ParseScopeFlags(const ParseScopeFlags &) LLVM_DELETED_FUNCTION; - void operator=(const ParseScopeFlags &) LLVM_DELETED_FUNCTION; + ParseScopeFlags(const ParseScopeFlags &) = delete; + void operator=(const ParseScopeFlags &) = delete; public: ParseScopeFlags(Parser *Self, unsigned ScopeFlags, bool ManageFlags = true); @@ -887,7 +887,7 @@ private: class LateParsedClass : public LateParsedDeclaration { public: LateParsedClass(Parser *P, ParsingClass *C); - virtual ~LateParsedClass(); + ~LateParsedClass() override; void ParseLexedMethodDeclarations() override; void ParseLexedMemberInitializers() override; @@ -1166,7 +1166,6 @@ private: ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo, const VirtSpecifiers& VS, - FunctionDefinitionKind DefinitionKind, ExprResult& Init); void ParseCXXNonStaticMemberInitializer(Decl *VarD); void ParseLexedAttributes(ParsingClass &Class); @@ -1241,6 +1240,7 @@ private: bool ParseObjCProtocolReferences(SmallVectorImpl<Decl *> &P, SmallVectorImpl<SourceLocation> &PLocs, bool WarnOnDeclarations, + bool ForObjCContainer, SourceLocation &LAngleLoc, SourceLocation &EndProtoLoc); bool ParseObjCProtocolQualifiers(DeclSpec &DS); @@ -1362,12 +1362,9 @@ private: typedef SmallVector<SourceLocation, 20> CommaLocsTy; /// ParseExpressionList - Used for C/C++ (argument-)expression-list. - bool - ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, - SmallVectorImpl<SourceLocation> &CommaLocs, - void (Sema::*Completer)(Scope *S, Expr *Data, - ArrayRef<Expr *> Args) = nullptr, - Expr *Data = nullptr); + bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs, + SmallVectorImpl<SourceLocation> &CommaLocs, + std::function<void()> Completer = nullptr); /// ParseSimpleExpressionList - A simple comma-separated list of expressions, /// used for misc language extensions. @@ -1661,7 +1658,6 @@ private: // MS: SEH Statements and Blocks StmtResult ParseSEHTryBlock(); - StmtResult ParseSEHTryBlockCommon(SourceLocation Loc); StmtResult ParseSEHExceptBlock(SourceLocation Loc); StmtResult ParseSEHFinallyBlock(SourceLocation Loc); StmtResult ParseSEHLeaveStatement(); @@ -1984,6 +1980,9 @@ private: void DiagnoseMisplacedCXX11Attribute(ParsedAttributesWithRange &Attrs, SourceLocation CorrectLocation); + void handleDeclspecAlignBeforeClassKey(ParsedAttributesWithRange &Attrs, + DeclSpec &DS, Sema::TagUseKind TUK); + void ProhibitAttributes(ParsedAttributesWithRange &attrs) { if (!attrs.Range.isValid()) return; DiagnoseProhibitedAttributes(attrs); @@ -2088,7 +2087,15 @@ private: } void ParseMicrosoftAttributes(ParsedAttributes &attrs, SourceLocation *endLoc = nullptr); - void ParseMicrosoftDeclSpec(ParsedAttributes &Attrs); + void MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, + SourceLocation *End = nullptr) { + const auto &LO = getLangOpts(); + if ((LO.MicrosoftExt || LO.Borland || LO.CUDA) && + Tok.is(tok::kw___declspec)) + ParseMicrosoftDeclSpecs(Attrs, End); + } + void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, + SourceLocation *End = nullptr); bool ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc, ParsedAttributes &Attrs); @@ -2219,6 +2226,8 @@ private: BalancedDelimiterTracker &Tracker, bool IsAmbiguous, bool RequiresArg = false); + bool ParseRefQualifier(bool &RefQualifierIsLValueRef, + SourceLocation &RefQualifierLoc); bool isFunctionDeclaratorIdentifierList(); void ParseFunctionDeclaratorIdentifierList( Declarator &D, @@ -2287,6 +2296,10 @@ private: AccessSpecifier AS, bool EnteringContext, DeclSpecContext DSC, ParsedAttributesWithRange &Attributes); + void SkipCXXMemberSpecification(SourceLocation StartLoc, + SourceLocation AttrFixitLoc, + unsigned TagType, + Decl *TagDecl); void ParseCXXMemberSpecification(SourceLocation StartLoc, SourceLocation AttrFixitLoc, ParsedAttributesWithRange &Attrs, @@ -2294,10 +2307,12 @@ private: Decl *TagDecl); ExprResult ParseCXXMemberInitializer(Decl *D, bool IsFunction, SourceLocation &EqualLoc); - void ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo, + bool ParseCXXMemberDeclaratorBeforeInitializer(Declarator &DeclaratorInfo, VirtSpecifiers &VS, ExprResult &BitfieldSize, LateParsedAttrList &LateAttrs); + void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D, + VirtSpecifiers &VS); void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), ParsingDeclRAIIObject *DiagsFromTParams = nullptr); diff --git a/include/clang/Rewrite/Core/DeltaTree.h b/include/clang/Rewrite/Core/DeltaTree.h index 248f2a0..fbffb38 100644 --- a/include/clang/Rewrite/Core/DeltaTree.h +++ b/include/clang/Rewrite/Core/DeltaTree.h @@ -27,7 +27,7 @@ namespace clang { /// as well, without traversing the whole tree. class DeltaTree { void *Root; // "DeltaTreeNode *" - void operator=(const DeltaTree &) LLVM_DELETED_FUNCTION; + void operator=(const DeltaTree &) = delete; public: DeltaTree(); diff --git a/include/clang/Rewrite/Core/RewriteBuffer.h b/include/clang/Rewrite/Core/RewriteBuffer.h new file mode 100644 index 0000000..d69c69b --- /dev/null +++ b/include/clang/Rewrite/Core/RewriteBuffer.h @@ -0,0 +1,117 @@ +//===--- RewriteBuffer.h - Buffer rewriting interface -----------*- 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_REWRITE_CORE_REWRITEBUFFER_H +#define LLVM_CLANG_REWRITE_CORE_REWRITEBUFFER_H + +#include "clang/Basic/LLVM.h" +#include "clang/Rewrite/Core/DeltaTree.h" +#include "clang/Rewrite/Core/RewriteRope.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + class Rewriter; + +/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original +/// input with modifications get a new RewriteBuffer associated with them. The +/// RewriteBuffer captures the modified text itself as well as information used +/// to map between SourceLocation's in the original input and offsets in the +/// RewriteBuffer. For example, if text is inserted into the buffer, any +/// locations after the insertion point have to be mapped. +class RewriteBuffer { + friend class Rewriter; + /// Deltas - Keep track of all the deltas in the source code due to insertions + /// and deletions. + DeltaTree Deltas; + RewriteRope Buffer; +public: + typedef RewriteRope::const_iterator iterator; + iterator begin() const { return Buffer.begin(); } + iterator end() const { return Buffer.end(); } + unsigned size() const { return Buffer.size(); } + + /// Initialize - Start this rewrite buffer out with a copy of the unmodified + /// input buffer. + void Initialize(const char *BufStart, const char *BufEnd) { + Buffer.assign(BufStart, BufEnd); + } + void Initialize(StringRef Input) { + Initialize(Input.begin(), Input.end()); + } + + /// \brief Write to \p Stream the result of applying all changes to the + /// original buffer. + /// Note that it isn't safe to use this function to overwrite memory mapped + /// files in-place (PR17960). Consider using a higher-level utility such as + /// Rewriter::overwriteChangedFiles() instead. + /// + /// The original buffer is not actually changed. + raw_ostream &write(raw_ostream &Stream) const; + + /// RemoveText - Remove the specified text. + void RemoveText(unsigned OrigOffset, unsigned Size, + bool removeLineIfEmpty = false); + + /// InsertText - Insert some text at the specified point, where the offset in + /// the buffer is specified relative to the original SourceBuffer. The + /// text is inserted after the specified location. + /// + void InsertText(unsigned OrigOffset, StringRef Str, + bool InsertAfter = true); + + + /// InsertTextBefore - Insert some text before the specified point, where the + /// offset in the buffer is specified relative to the original + /// SourceBuffer. The text is inserted before the specified location. This is + /// method is the same as InsertText with "InsertAfter == false". + void InsertTextBefore(unsigned OrigOffset, StringRef Str) { + InsertText(OrigOffset, Str, false); + } + + /// InsertTextAfter - Insert some text at the specified point, where the + /// offset in the buffer is specified relative to the original SourceBuffer. + /// The text is inserted after the specified location. + void InsertTextAfter(unsigned OrigOffset, StringRef Str) { + InsertText(OrigOffset, Str); + } + + /// ReplaceText - This method replaces a range of characters in the input + /// buffer with a new string. This is effectively a combined "remove/insert" + /// operation. + void ReplaceText(unsigned OrigOffset, unsigned OrigLength, + StringRef NewStr); + +private: // Methods only usable by Rewriter. + + /// getMappedOffset - Given an offset into the original SourceBuffer that this + /// RewriteBuffer is based on, map it into the offset space of the + /// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a + /// position where text is inserted, the location returned will be after any + /// inserted text at the position. + unsigned getMappedOffset(unsigned OrigOffset, + bool AfterInserts = false) const{ + return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset; + } + + /// AddInsertDelta - When an insertion is made at a position, this + /// method is used to record that information. + void AddInsertDelta(unsigned OrigOffset, int Change) { + return Deltas.AddDelta(2*OrigOffset, Change); + } + + /// AddReplaceDelta - When a replacement/deletion is made at a position, this + /// method is used to record that information. + void AddReplaceDelta(unsigned OrigOffset, int Change) { + return Deltas.AddDelta(2*OrigOffset+1, Change); + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Rewrite/Core/RewriteRope.h b/include/clang/Rewrite/Core/RewriteRope.h index 1c6f3eb..5002554 100644 --- a/include/clang/Rewrite/Core/RewriteRope.h +++ b/include/clang/Rewrite/Core/RewriteRope.h @@ -136,7 +136,7 @@ namespace clang { class RopePieceBTree { void /*RopePieceBTreeNode*/ *Root; - void operator=(const RopePieceBTree &) LLVM_DELETED_FUNCTION; + void operator=(const RopePieceBTree &) = delete; public: RopePieceBTree(); RopePieceBTree(const RopePieceBTree &RHS); diff --git a/include/clang/Rewrite/Core/Rewriter.h b/include/clang/Rewrite/Core/Rewriter.h index 1ab7be6..800372e 100644 --- a/include/clang/Rewrite/Core/Rewriter.h +++ b/include/clang/Rewrite/Core/Rewriter.h @@ -16,110 +16,15 @@ #define LLVM_CLANG_REWRITE_CORE_REWRITER_H #include "clang/Basic/SourceLocation.h" -#include "clang/Rewrite/Core/DeltaTree.h" -#include "clang/Rewrite/Core/RewriteRope.h" -#include "llvm/ADT/StringRef.h" +#include "clang/Rewrite/Core/RewriteBuffer.h" #include <cstring> #include <map> #include <string> namespace clang { class LangOptions; - class Rewriter; class SourceManager; -/// RewriteBuffer - As code is rewritten, SourceBuffer's from the original -/// input with modifications get a new RewriteBuffer associated with them. The -/// RewriteBuffer captures the modified text itself as well as information used -/// to map between SourceLocation's in the original input and offsets in the -/// RewriteBuffer. For example, if text is inserted into the buffer, any -/// locations after the insertion point have to be mapped. -class RewriteBuffer { - friend class Rewriter; - /// Deltas - Keep track of all the deltas in the source code due to insertions - /// and deletions. - DeltaTree Deltas; - RewriteRope Buffer; -public: - typedef RewriteRope::const_iterator iterator; - iterator begin() const { return Buffer.begin(); } - iterator end() const { return Buffer.end(); } - unsigned size() const { return Buffer.size(); } - - /// \brief Write to \p Stream the result of applying all changes to the - /// original buffer. - /// Note that it isn't safe to use this function to overwrite memory mapped - /// files in-place (PR17960). Consider using a higher-level utility such as - /// Rewriter::overwriteChangedFiles() instead. - /// - /// The original buffer is not actually changed. - raw_ostream &write(raw_ostream &Stream) const; - - /// RemoveText - Remove the specified text. - void RemoveText(unsigned OrigOffset, unsigned Size, - bool removeLineIfEmpty = false); - - /// InsertText - Insert some text at the specified point, where the offset in - /// the buffer is specified relative to the original SourceBuffer. The - /// text is inserted after the specified location. - /// - void InsertText(unsigned OrigOffset, StringRef Str, - bool InsertAfter = true); - - - /// InsertTextBefore - Insert some text before the specified point, where the - /// offset in the buffer is specified relative to the original - /// SourceBuffer. The text is inserted before the specified location. This is - /// method is the same as InsertText with "InsertAfter == false". - void InsertTextBefore(unsigned OrigOffset, StringRef Str) { - InsertText(OrigOffset, Str, false); - } - - /// InsertTextAfter - Insert some text at the specified point, where the - /// offset in the buffer is specified relative to the original SourceBuffer. - /// The text is inserted after the specified location. - void InsertTextAfter(unsigned OrigOffset, StringRef Str) { - InsertText(OrigOffset, Str); - } - - /// ReplaceText - This method replaces a range of characters in the input - /// buffer with a new string. This is effectively a combined "remove/insert" - /// operation. - void ReplaceText(unsigned OrigOffset, unsigned OrigLength, - StringRef NewStr); - -private: // Methods only usable by Rewriter. - - /// Initialize - Start this rewrite buffer out with a copy of the unmodified - /// input buffer. - void Initialize(const char *BufStart, const char *BufEnd) { - Buffer.assign(BufStart, BufEnd); - } - - /// getMappedOffset - Given an offset into the original SourceBuffer that this - /// RewriteBuffer is based on, map it into the offset space of the - /// RewriteBuffer. If AfterInserts is true and if the OrigOffset indicates a - /// position where text is inserted, the location returned will be after any - /// inserted text at the position. - unsigned getMappedOffset(unsigned OrigOffset, - bool AfterInserts = false) const{ - return Deltas.getDeltaAt(2*OrigOffset+AfterInserts)+OrigOffset; - } - - /// AddInsertDelta - When an insertion is made at a position, this - /// method is used to record that information. - void AddInsertDelta(unsigned OrigOffset, int Change) { - return Deltas.AddDelta(2*OrigOffset, Change); - } - - /// AddReplaceDelta - When a replacement/deletion is made at a position, this - /// method is used to record that information. - void AddReplaceDelta(unsigned OrigOffset, int Change) { - return Deltas.AddDelta(2*OrigOffset+1, Change); - } -}; - - /// Rewriter - This is the main interface to the rewrite buffers. Its primary /// job is to dispatch high-level requests to the low-level RewriteBuffers that /// are involved. diff --git a/include/clang/Rewrite/Core/TokenRewriter.h b/include/clang/Rewrite/Core/TokenRewriter.h index 598477f..0f71e81 100644 --- a/include/clang/Rewrite/Core/TokenRewriter.h +++ b/include/clang/Rewrite/Core/TokenRewriter.h @@ -43,8 +43,8 @@ namespace clang { /// std::unique_ptr<ScratchBuffer> ScratchBuf; - TokenRewriter(const TokenRewriter &) LLVM_DELETED_FUNCTION; - void operator=(const TokenRewriter &) LLVM_DELETED_FUNCTION; + TokenRewriter(const TokenRewriter &) = delete; + void operator=(const TokenRewriter &) = delete; public: /// TokenRewriter - This creates a TokenRewriter for the file with the /// specified FileID. diff --git a/include/clang/Rewrite/Frontend/FixItRewriter.h b/include/clang/Rewrite/Frontend/FixItRewriter.h index 5994172..ad828e5 100644 --- a/include/clang/Rewrite/Frontend/FixItRewriter.h +++ b/include/clang/Rewrite/Frontend/FixItRewriter.h @@ -86,7 +86,7 @@ public: const LangOptions &LangOpts, FixItOptions *FixItOpts); /// \brief Destroy the fix-it rewriter. - ~FixItRewriter(); + ~FixItRewriter() override; /// \brief Check whether there are modifications for a given file. bool IsModified(FileID ID) const { diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h index c8ea8b2..6c290e4 100644 --- a/include/clang/Rewrite/Frontend/FrontendActions.h +++ b/include/clang/Rewrite/Frontend/FrontendActions.h @@ -43,7 +43,7 @@ protected: public: FixItAction(); - ~FixItAction(); + ~FixItAction() override; }; /// \brief Emits changes to temporary files and uses them for the original diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 5e543a5..58b1b9e 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -204,10 +204,10 @@ private: return *reinterpret_cast<const PropertyData*>(this + 1); } - AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION; - void operator=(const AttributeList &) LLVM_DELETED_FUNCTION; - void operator delete(void *) LLVM_DELETED_FUNCTION; - ~AttributeList() LLVM_DELETED_FUNCTION; + AttributeList(const AttributeList &) = delete; + void operator=(const AttributeList &) = delete; + void operator delete(void *) = delete; + ~AttributeList() = delete; size_t allocated_size() const; @@ -670,7 +670,7 @@ public: : pool(factory), list(nullptr) { } - ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION; + ParsedAttributes(const ParsedAttributes &) = delete; AttributePool &getPool() const { return pool; } @@ -822,6 +822,7 @@ enum AttributeDeclKind { ExpectedFunctionMethodOrClass, ExpectedFunctionMethodOrParameter, ExpectedClass, + ExpectedEnum, ExpectedVariable, ExpectedMethod, ExpectedVariableFunctionOrLabel, @@ -842,6 +843,7 @@ enum AttributeDeclKind { ExpectedFunctionVariableOrClass, ExpectedObjectiveCProtocol, ExpectedFunctionGlobalVarMethodOrProperty, + ExpectedStructOrUnionOrTypedef, ExpectedStructOrTypedef, ExpectedObjectiveCInterfaceOrProtocol, ExpectedKernelFunction diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 92a4e9a..de65c43 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -17,6 +17,7 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/Type.h" #include "clang/Sema/CodeCompleteOptions.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" @@ -440,15 +441,15 @@ private: /// entity being completed by this result. const char *BriefComment; - CodeCompletionString(const CodeCompletionString &) LLVM_DELETED_FUNCTION; - void operator=(const CodeCompletionString &) LLVM_DELETED_FUNCTION; + CodeCompletionString(const CodeCompletionString &) = delete; + void operator=(const CodeCompletionString &) = delete; CodeCompletionString(const Chunk *Chunks, unsigned NumChunks, unsigned Priority, CXAvailabilityKind Availability, const char **Annotations, unsigned NumAnnotations, StringRef ParentName, const char *BriefComment); - ~CodeCompletionString() { } + ~CodeCompletionString() = default; friend class CodeCompletionBuilder; friend class CodeCompletionResult; @@ -498,20 +499,7 @@ public: class CodeCompletionAllocator : public llvm::BumpPtrAllocator { public: /// \brief Copy the given string into this allocator. - const char *CopyString(StringRef String); - - /// \brief Copy the given string into this allocator. - const char *CopyString(Twine String); - - // \brief Copy the given string into this allocator. - const char *CopyString(const char *String) { - return CopyString(StringRef(String)); - } - - /// \brief Copy the given string into this allocator. - const char *CopyString(const std::string &String) { - return CopyString(StringRef(String)); - } + const char *CopyString(const Twine &String); }; /// \brief Allocator for a cached set of global code completions. @@ -885,7 +873,8 @@ public: CodeCompletionString *CreateSignatureString(unsigned CurrentArg, Sema &S, CodeCompletionAllocator &Allocator, - CodeCompletionTUInfo &CCTUInfo) const; + CodeCompletionTUInfo &CCTUInfo, + bool IncludeBriefComments) const; }; CodeCompleteConsumer(const CodeCompleteOptions &CodeCompleteOpts, diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index d368826..de39d83 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -57,7 +57,7 @@ namespace clang { /// These can be in 3 states: /// 1) Not present, identified by isEmpty() /// 2) Present, identified by isNotEmpty() -/// 2.a) Valid, idenified by isValid() +/// 2.a) Valid, identified by isValid() /// 2.b) Invalid, identified by isInvalid(). /// /// isSet() is deprecated because it mostly corresponded to "valid" but was @@ -407,8 +407,8 @@ private: return (T == TST_typeofExpr || T == TST_decltype); } - DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION; - void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION; + DeclSpec(const DeclSpec &) = delete; + void operator=(const DeclSpec &) = delete; public: static bool isDeclRep(TST T) { return (T == TST_enum || T == TST_struct || @@ -845,8 +845,8 @@ private: /// \brief Represents a C++ unqualified-id that has been parsed. class UnqualifiedId { private: - UnqualifiedId(const UnqualifiedId &Other) LLVM_DELETED_FUNCTION; - const UnqualifiedId &operator=(const UnqualifiedId &) LLVM_DELETED_FUNCTION; + UnqualifiedId(const UnqualifiedId &Other) = delete; + const UnqualifiedId &operator=(const UnqualifiedId &) = delete; public: /// \brief Describes the kind of unqualified-id parsed. @@ -1415,7 +1415,8 @@ struct DeclaratorChunk { static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, - SourceLocation RestrictQualLoc) { + SourceLocation RestrictQualLoc, + SourceLocation AtomicQualLoc) { DeclaratorChunk I; I.Kind = Pointer; I.Loc = Loc; @@ -1423,6 +1424,7 @@ struct DeclaratorChunk { I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding(); I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding(); I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding(); + I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding(); I.Ptr.AttrList = nullptr; return I; } @@ -2180,7 +2182,7 @@ public: VS_Sealed = 4 }; - VirtSpecifiers() : Specifiers(0) { } + VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { } bool SetSpecifier(Specifier VS, SourceLocation Loc, const char *&PrevSpec); @@ -2198,12 +2200,16 @@ public: static const char *getSpecifierName(Specifier VS); + SourceLocation getFirstLocation() const { return FirstLocation; } SourceLocation getLastLocation() const { return LastLocation; } + Specifier getLastSpecifier() const { return LastSpecifier; } private: unsigned Specifiers; + Specifier LastSpecifier; SourceLocation VS_overrideLoc, VS_finalLoc; + SourceLocation FirstLocation; SourceLocation LastLocation; }; diff --git a/include/clang/Sema/DelayedDiagnostic.h b/include/clang/Sema/DelayedDiagnostic.h index 7fd6779..155b3aa 100644 --- a/include/clang/Sema/DelayedDiagnostic.h +++ b/include/clang/Sema/DelayedDiagnostic.h @@ -240,8 +240,8 @@ class DelayedDiagnosticPool { const DelayedDiagnosticPool *Parent; SmallVector<DelayedDiagnostic, 4> Diagnostics; - DelayedDiagnosticPool(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION; - void operator=(const DelayedDiagnosticPool &) LLVM_DELETED_FUNCTION; + DelayedDiagnosticPool(const DelayedDiagnosticPool &) = delete; + void operator=(const DelayedDiagnosticPool &) = delete; public: DelayedDiagnosticPool(const DelayedDiagnosticPool *parent) : Parent(parent) {} ~DelayedDiagnosticPool() { @@ -250,6 +250,17 @@ public: i->Destroy(); } + DelayedDiagnosticPool(DelayedDiagnosticPool &&Other) + : Parent(Other.Parent), Diagnostics(std::move(Other.Diagnostics)) { + Other.Diagnostics.clear(); + } + DelayedDiagnosticPool &operator=(DelayedDiagnosticPool &&Other) { + Parent = Other.Parent; + Diagnostics = std::move(Other.Diagnostics); + Other.Diagnostics.clear(); + return *this; + } + const DelayedDiagnosticPool *getParent() const { return Parent; } /// Does this pool, or any of its ancestors, contain any diagnostics? diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index c0ef712..ef3d2db 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -27,6 +27,7 @@ template <class T, unsigned n> class SmallSetVector; namespace clang { class CXXConstructorDecl; +class CXXDeleteExpr; class CXXRecordDecl; class DeclaratorDecl; class LookupResult; @@ -55,7 +56,7 @@ public: ExternalASTSource::SemaSource = true; } - ~ExternalSemaSource(); + ~ExternalSemaSource() override; /// \brief Initialize the semantic source with the Sema instance /// being used to perform semantic analysis on the abstract syntax @@ -79,6 +80,9 @@ public: virtual void ReadUndefinedButUsed( llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined); + virtual void ReadMismatchingDeleteExpressions(llvm::MapVector< + FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &); + /// \brief Do last resort, unqualified lookup on a LookupResult that /// Sema cannot find. /// @@ -128,14 +132,6 @@ public: /// introduce the same declarations repeatedly. virtual void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) {} - /// \brief Read the set of dynamic classes known to the external Sema source. - /// - /// The external source should append its own dynamic classes to - /// the given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - virtual void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) {} - /// \brief Read the set of potentially unused typedefs known to the source. /// /// The external source should append its own potentially unused local @@ -145,16 +141,6 @@ public: virtual void ReadUnusedLocalTypedefNameCandidates( llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {}; - /// \brief Read the set of locally-scoped external declarations known to the - /// external Sema source. - /// - /// The external source should append its own locally-scoped external - /// declarations to the given vector of declarations. Note that this routine - /// may be invoked multiple times; the external source should take care not - /// to introduce the same declarations repeatedly. - virtual void ReadLocallyScopedExternCDecls( - SmallVectorImpl<NamedDecl *> &Decls) {} - /// \brief Read the set of referenced selectors known to the /// external Sema source. /// @@ -200,7 +186,7 @@ public: /// external source should take care not to introduce the same map entries /// repeatedly. virtual void ReadLateParsedTemplates( - llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {} + llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) {} /// \copydoc Sema::CorrectTypo /// \note LookupKind must correspond to a valid Sema::LookupNameKind diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index 9f342b2..74de00f 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -844,6 +844,21 @@ private: /// \brief The incomplete type that caused a failure. QualType FailedIncompleteType; + + /// \brief The fixit that needs to be applied to make this initialization + /// succeed. + std::string ZeroInitializationFixit; + SourceLocation ZeroInitializationFixitLoc; + +public: + /// \brief Call for initializations are invalid but that would be valid + /// zero initialzations if Fixit was applied. + void SetZeroInitializationFixit(const std::string& Fixit, SourceLocation L) { + ZeroInitializationFixit = Fixit; + ZeroInitializationFixitLoc = L; + } + +private: /// \brief Prints a follow-up note that highlights the location of /// the initialized entity, if it's remote. @@ -921,7 +936,7 @@ public: void setSequenceKind(enum SequenceKind SK) { SequenceKind = SK; } /// \brief Determine whether the initialization sequence is valid. - LLVM_EXPLICIT operator bool() const { return !Failed(); } + explicit operator bool() const { return !Failed(); } /// \brief Determine whether the initialization sequence is invalid. bool Failed() const { return SequenceKind == FailedSequence; } diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 1c6c7bb..5bfee8b 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -291,9 +291,6 @@ public: if (!D->isHidden()) return true; - if (SemaRef.ActiveTemplateInstantiations.empty()) - return false; - // During template instantiation, we can refer to hidden declarations, if // they were visible in any module along the path of instantiation. return isVisibleSlow(SemaRef, D); @@ -735,22 +732,18 @@ public: } class iterator - : public std::iterator<std::forward_iterator_tag, NamedDecl *> { - typedef llvm::DenseMap<NamedDecl*,NamedDecl*>::iterator inner_iterator; - inner_iterator iter; - + : public llvm::iterator_adaptor_base< + iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator, + std::forward_iterator_tag, NamedDecl *> { friend class ADLResult; - iterator(const inner_iterator &iter) : iter(iter) {} - public: - iterator() {} - iterator &operator++() { ++iter; return *this; } - iterator operator++(int) { return iterator(iter++); } + iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter) + : iterator_adaptor_base(std::move(Iter)) {} - value_type operator*() const { return iter->second; } + public: + iterator() {} - bool operator==(const iterator &other) const { return iter == other.iter; } - bool operator!=(const iterator &other) const { return iter != other.iter; } + value_type operator*() const { return I->second; } }; iterator begin() { return iterator(Decls.begin()); } diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h index f06d196..af7083a 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -51,7 +51,7 @@ public: /// MultiplexExternalSemaSource(ExternalSemaSource& s1, ExternalSemaSource& s2); - ~MultiplexExternalSemaSource(); + ~MultiplexExternalSemaSource() override; ///\brief Appends new source to the source list. /// @@ -86,10 +86,14 @@ public: /// stream into an array of specifiers. CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; + /// \brief Resolve a handle to a list of ctor initializers into the list of + /// initializers themselves. + CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; + /// \brief Find all declarations with the given name in the /// given context. - bool - FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override; + bool FindExternalVisibleDeclsByName(const DeclContext *DC, + DeclarationName Name) override; /// \brief Ensures that the table of all visible declarations inside this /// context is up to date. @@ -226,6 +230,10 @@ public: void ReadUndefinedButUsed( llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override; + void ReadMismatchingDeleteExpressions(llvm::MapVector< + FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & + Exprs) override; + /// \brief Do last resort, unqualified lookup on a LookupResult that /// Sema cannot find. /// @@ -274,14 +282,6 @@ public: /// introduce the same declarations repeatedly. void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl*> &Decls) override; - /// \brief Read the set of dynamic classes known to the external Sema source. - /// - /// The external source should append its own dynamic classes to - /// the given vector of declarations. Note that this routine may be - /// invoked multiple times; the external source should take care not to - /// introduce the same declarations repeatedly. - void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl*> &Decls) override; - /// \brief Read the set of potentially unused typedefs known to the source. /// /// The external source should append its own potentially unused local @@ -291,16 +291,6 @@ public: void ReadUnusedLocalTypedefNameCandidates( llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; - /// \brief Read the set of locally-scoped extern "C" declarations known to the - /// external Sema source. - /// - /// The external source should append its own locally-scoped external - /// declarations to the given vector of declarations. Note that this routine - /// may be invoked multiple times; the external source should take care not - /// to introduce the same declarations repeatedly. - void ReadLocallyScopedExternCDecls( - SmallVectorImpl<NamedDecl*> &Decls) override; - /// \brief Read the set of referenced selectors known to the /// external Sema source. /// @@ -345,8 +335,8 @@ public: /// external source should take care not to introduce the same map entries /// repeatedly. void ReadLateParsedTemplates( - llvm::DenseMap<const FunctionDecl *, - LateParsedTemplate *> &LPTMap) override; + llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) + override; /// \copydoc ExternalSemaSource::CorrectTypo /// \note Returns the first nonempty correction. diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 4447db2..2007dcb 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -718,8 +718,8 @@ namespace clang { llvm::AlignedCharArray<llvm::AlignOf<ImplicitConversionSequence>::Alignment, 16 * sizeof(ImplicitConversionSequence)> InlineSpace; - OverloadCandidateSet(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION; - void operator=(const OverloadCandidateSet &) LLVM_DELETED_FUNCTION; + OverloadCandidateSet(const OverloadCandidateSet &) = delete; + void operator=(const OverloadCandidateSet &) = delete; void destroyCandidates(); diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index 8031562..8acf9e8 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -79,7 +79,7 @@ namespace clang { Ptr = Traits::getAsVoidPointer(P); } - LLVM_EXPLICIT operator bool() const { return Ptr != nullptr; } + explicit operator bool() const { return Ptr != nullptr; } void *getAsOpaquePtr() const { return Ptr; } static OpaquePtr getFromOpaquePtr(void *P) { return OpaquePtr(P); } diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index 97e447d..dfc6f9c 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -115,8 +115,14 @@ public: /// This scope corresponds to an enum. EnumScope = 0x40000, - /// This scope corresponds to a SEH try. + /// This scope corresponds to an SEH try. SEHTryScope = 0x80000, + + /// This scope corresponds to an SEH except. + SEHExceptScope = 0x100000, + + /// We are currently in the filter expression of an SEH except block. + SEHFilterScope = 0x200000, }; private: /// The parent scope for this scope. This is null for the translation-unit @@ -133,7 +139,9 @@ private: /// \brief Declarations with static linkage are mangled with the number of /// scopes seen as a component. - unsigned short MSLocalManglingNumber; + unsigned short MSLastManglingNumber; + + unsigned short MSCurManglingNumber; /// PrototypeDepth - This is the number of function prototype scopes /// enclosing this scope, including this scope. @@ -146,7 +154,7 @@ private: /// FnParent - If this scope has a parent scope that is a function body, this /// pointer is non-null and points to it. This is used for label processing. Scope *FnParent; - Scope *MSLocalManglingParent; + Scope *MSLastManglingParent; /// BreakParent/ContinueParent - This is a direct link to the innermost /// BreakScope/ContinueScope which contains the contents of this scope @@ -212,10 +220,10 @@ public: const Scope *getFnParent() const { return FnParent; } Scope *getFnParent() { return FnParent; } - const Scope *getMSLocalManglingParent() const { - return MSLocalManglingParent; + const Scope *getMSLastManglingParent() const { + return MSLastManglingParent; } - Scope *getMSLocalManglingParent() { return MSLocalManglingParent; } + Scope *getMSLastManglingParent() { return MSLastManglingParent; } /// getContinueParent - Return the closest scope that a continue statement /// would be affected by. @@ -269,22 +277,30 @@ public: DeclsInScope.erase(D); } - void incrementMSLocalManglingNumber() { - if (Scope *MSLMP = getMSLocalManglingParent()) - MSLMP->MSLocalManglingNumber += 1; + void incrementMSManglingNumber() { + if (Scope *MSLMP = getMSLastManglingParent()) { + MSLMP->MSLastManglingNumber += 1; + MSCurManglingNumber += 1; + } } - void decrementMSLocalManglingNumber() { - if (Scope *MSLMP = getMSLocalManglingParent()) - MSLMP->MSLocalManglingNumber -= 1; + void decrementMSManglingNumber() { + if (Scope *MSLMP = getMSLastManglingParent()) { + MSLMP->MSLastManglingNumber -= 1; + MSCurManglingNumber -= 1; + } } - unsigned getMSLocalManglingNumber() const { - if (const Scope *MSLMP = getMSLocalManglingParent()) - return MSLMP->MSLocalManglingNumber; + unsigned getMSLastManglingNumber() const { + if (const Scope *MSLMP = getMSLastManglingParent()) + return MSLMP->MSLastManglingNumber; return 1; } + unsigned getMSCurManglingNumber() const { + return MSCurManglingNumber; + } + /// isDeclScope - Return true if this is the scope that the specified decl is /// declared in. bool isDeclScope(Decl *D) { @@ -407,6 +423,15 @@ public: /// \brief Determine whether this scope is a SEH '__try' block. bool isSEHTryScope() const { return getFlags() & Scope::SEHTryScope; } + /// \brief Determine whether this scope is a SEH '__except' block. + bool isSEHExceptScope() const { return getFlags() & Scope::SEHExceptScope; } + + /// \brief Returns if rhs has a higher scope depth than this. + /// + /// The caller is responsible for calling this only if one of the two scopes + /// is an ancestor of the other. + bool Contains(const Scope& rhs) const { return Depth < rhs.Depth; } + /// containedInPrototypeScope - Return true if this or a parent scope /// is a FunctionPrototypeScope. bool containedInPrototypeScope() const; diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index d63b734..15ee8a4 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -124,6 +124,12 @@ public: /// false if there is an invocation of an initializer on 'self'. bool ObjCWarnForNoInitDelegation; + /// First C++ 'try' statement in the current function. + SourceLocation FirstCXXTryLoc; + + /// First SEH '__try' statement in the current function. + SourceLocation FirstSEHTryLoc; + /// \brief Used to determine if errors occurred in this function or block. DiagnosticErrorTrap ErrorTrap; @@ -321,6 +327,16 @@ public: HasDroppedStmt = true; } + void setHasCXXTry(SourceLocation TryLoc) { + setHasBranchProtectedScope(); + FirstCXXTryLoc = TryLoc; + } + + void setHasSEHTry(SourceLocation TryLoc) { + setHasBranchProtectedScope(); + FirstSEHTryLoc = TryLoc; + } + bool NeedsScopeChecking() const { return !HasDroppedStmt && (HasIndirectGoto || @@ -552,7 +568,7 @@ public: Kind = SK_Block; } - virtual ~BlockScopeInfo(); + ~BlockScopeInfo() override; static bool classof(const FunctionScopeInfo *FSI) { return FSI->Kind == SK_Block; @@ -583,7 +599,7 @@ public: Kind = SK_CapturedRegion; } - virtual ~CapturedRegionScopeInfo(); + ~CapturedRegionScopeInfo() override; /// \brief A descriptive name for the kind of captured region this is. StringRef getRegionName() const { @@ -632,13 +648,6 @@ public: /// \brief Whether the lambda contains an unexpanded parameter pack. bool ContainsUnexpandedParameterPack; - /// \brief Variables used to index into by-copy array captures. - SmallVector<VarDecl *, 4> ArrayIndexVars; - - /// \brief Offsets into the ArrayIndexVars array at which each capture starts - /// its list of array index variables. - SmallVector<unsigned, 4> ArrayIndexStarts; - /// \brief If this is a generic lambda, use this as the depth of /// each 'auto' parameter, during initial AST construction. unsigned AutoTemplateParameterDepth; @@ -682,13 +691,13 @@ public: LambdaScopeInfo(DiagnosticsEngine &Diag) : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr), CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false), - ExprNeedsCleanups(false), ContainsUnexpandedParameterPack(false), - AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr) - { + ExplicitParams(false), ExprNeedsCleanups(false), + ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0), + GLTemplateParameterList(nullptr) { Kind = SK_Lambda; } - virtual ~LambdaScopeInfo(); + ~LambdaScopeInfo() override; /// \brief Note when all explicit captures have been added. void finishedExplicitCaptures() { @@ -826,9 +835,6 @@ CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, Cpy)); CXXThisCaptureIndex = Captures.size(); - - if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(this)) - LSI->ArrayIndexStarts.push_back(LSI->ArrayIndexVars.size()); } } // end namespace sema diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index a364214..39ea3c6 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -78,6 +78,7 @@ namespace clang { typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath; class CXXConstructorDecl; class CXXConversionDecl; + class CXXDeleteExpr; class CXXDestructorDecl; class CXXFieldCollector; class CXXMemberCallExpr; @@ -199,6 +200,11 @@ namespace sema { class TemplateDeductionInfo; } +namespace threadSafety { + class BeforeSet; + void threadSafetyCleanup(BeforeSet* Cache); +} + // FIXME: No way to easily map from TemplateTypeParmTypes to // TemplateTypeParmDecls, so we have this horrible PointerUnion. typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, @@ -206,8 +212,8 @@ typedef std::pair<llvm::PointerUnion<const TemplateTypeParmType*, NamedDecl*>, /// Sema - This implements semantic analysis and AST building for C. class Sema { - Sema(const Sema &) LLVM_DELETED_FUNCTION; - void operator=(const Sema &) LLVM_DELETED_FUNCTION; + Sema(const Sema &) = delete; + void operator=(const Sema &) = delete; ///\brief Source of additional semantic information. ExternalSemaSource *ExternalSource; @@ -217,15 +223,17 @@ class Sema { static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD); - static bool - shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, const NamedDecl *New) { + bool isVisibleSlow(const NamedDecl *D); + + bool shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, + const NamedDecl *New) { // We are about to link these. It is now safe to compute the linkage of // the new decl. If the new decl has external linkage, we will // link it with the hidden decl (which also has external linkage) and // it will keep having external linkage. If it has internal linkage, we // will not link it. Since it has no previous decls, it will remain // with internal linkage. - return !Old->isHidden() || New->isExternallyVisible(); + return isVisible(Old) || New->isExternallyVisible(); } public: @@ -298,6 +306,9 @@ public: /// The stack always has at least one element in it. SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack; + /// Stack of active SEH __finally scopes. Can be empty. + SmallVector<Scope*, 2> CurrentSEHFinally; + /// \brief Source location for newly created implicit MSInheritanceAttrs SourceLocation ImplicitMSInheritanceAttrLoc; @@ -394,6 +405,15 @@ public: llvm::SmallSetVector<const TypedefNameDecl *, 4> UnusedLocalTypedefNameCandidates; + /// \brief Delete-expressions to be analyzed at the end of translation unit + /// + /// This list contains class members, and locations of delete-expressions + /// that could not be proven as to whether they mismatch with new-expression + /// used in initializer of the field. + typedef std::pair<SourceLocation, bool> DeleteExprLoc; + typedef llvm::SmallVector<DeleteExprLoc, 4> DeleteLocs; + llvm::MapVector<FieldDecl *, DeleteLocs> DeleteExprs; + typedef llvm::SmallPtrSet<const CXXRecordDecl*, 8> RecordDeclSetTy; /// PureVirtualClassDiagSet - a set of class declarations which we have @@ -405,33 +425,6 @@ public: /// we are currently parsing the initializer. llvm::SmallPtrSet<const Decl*, 4> ParsingInitForAutoVars; - /// \brief A mapping from external names to the most recent - /// locally-scoped extern "C" declaration with that name. - /// - /// This map contains external declarations introduced in local - /// scopes, e.g., - /// - /// \code - /// extern "C" void f() { - /// void foo(int, int); - /// } - /// \endcode - /// - /// Here, the name "foo" will be associated with the declaration of - /// "foo" within f. This name is not visible outside of - /// "f". However, we still find it in two cases: - /// - /// - If we are declaring another global or extern "C" entity with - /// the name "foo", we can find "foo" as a previous declaration, - /// so that the types of this external declaration can be checked - /// for compatibility. - /// - /// - If we would implicitly declare "foo" (e.g., due to a call to - /// "foo" in C when no prototype or definition is visible), then - /// we find this declaration of "foo" and complain that it is - /// not visible. - llvm::DenseMap<DeclarationName, NamedDecl *> LocallyScopedExternCDecls; - /// \brief Look for a locally scoped extern "C" declaration by the given name. NamedDecl *findLocallyScopedExternCDecl(DeclarationName Name); @@ -474,8 +467,8 @@ public: SmallVector<std::pair<CXXMethodDecl*, const FunctionProtoType*>, 2> DelayedDefaultedMemberExceptionSpecs; - typedef llvm::DenseMap<const FunctionDecl *, LateParsedTemplate *> - LateParsedTemplateMapT; + typedef llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> + LateParsedTemplateMapT; LateParsedTemplateMapT LateParsedTemplateMap; /// \brief Callback to the parser to parse templated functions when needed. @@ -611,7 +604,7 @@ public: /// WeakUndeclaredIdentifiers - Identifiers contained in /// \#pragma weak before declared. rare. may alias another /// identifier, declared or undeclared - llvm::DenseMap<IdentifierInfo*,WeakInfo> WeakUndeclaredIdentifiers; + llvm::MapVector<IdentifierInfo *, WeakInfo> WeakUndeclaredIdentifiers; /// ExtnameUndeclaredIdentifiers - Identifiers contained in /// \#pragma redefine_extname before declared. Used in Solaris system headers @@ -678,12 +671,27 @@ public: /// \brief The declaration of the Objective-C NSArray class. ObjCInterfaceDecl *NSArrayDecl; + /// \brief Pointer to NSMutableArray type (NSMutableArray *). + QualType NSMutableArrayPointer; + /// \brief The declaration of the arrayWithObjects:count: method. ObjCMethodDecl *ArrayWithObjectsMethod; /// \brief The declaration of the Objective-C NSDictionary class. ObjCInterfaceDecl *NSDictionaryDecl; + /// \brief Pointer to NSMutableDictionary type (NSMutableDictionary *). + QualType NSMutableDictionaryPointer; + + /// \brief Pointer to NSMutableSet type (NSMutableSet *). + QualType NSMutableSetPointer; + + /// \brief Pointer to NSCountedSet type (NSCountedSet *). + QualType NSCountedSetPointer; + + /// \brief Pointer to NSMutableOrderedSet type (NSMutableOrderedSet *). + QualType NSMutableOrderedSetPointer; + /// \brief The declaration of the dictionaryWithObjects:forKeys:count: method. ObjCMethodDecl *DictionaryWithObjectsMethod; @@ -890,6 +898,11 @@ public: void getUndefinedButUsed( SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined); + /// Retrieves list of suspicious delete-expressions that will be checked at + /// the end of translation unit. + const llvm::MapVector<FieldDecl *, DeleteLocs> & + getMismatchingDeleteExpressions() const; + typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods; typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool; @@ -903,7 +916,7 @@ public: /// Method selectors used in a \@selector expression. Used for implementation /// of -Wselector. - llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors; + llvm::MapVector<Selector, SourceLocation> ReferencedSelectors; /// Kinds of C++ special members. enum CXXSpecialMember { @@ -1254,117 +1267,82 @@ public: static SourceRange getPrintable(const Expr *E) { return E->getSourceRange(); } static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} - template<typename T1> - class BoundTypeDiagnoser1 : public TypeDiagnoser { + template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser { unsigned DiagID; - const T1 &Arg1; + std::tuple<const Ts &...> Args; + + template <std::size_t... Is> + void emit(const SemaDiagnosticBuilder &DB, + llvm::index_sequence<Is...>) const { + // Apply all tuple elements to the builder in order. + bool Dummy[] = {(DB << getPrintable(std::get<Is>(Args)))...}; + (void)Dummy; + } public: - BoundTypeDiagnoser1(unsigned DiagID, const T1 &Arg1) - : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1) { } + BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args) + : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Args(Args...) {} + void diagnose(Sema &S, SourceLocation Loc, QualType T) override { - if (Suppressed) return; - S.Diag(Loc, DiagID) << getPrintable(Arg1) << T; + if (Suppressed) + return; + const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID); + emit(DB, llvm::index_sequence_for<Ts...>()); + DB << T; } - - virtual ~BoundTypeDiagnoser1() { } }; - template<typename T1, typename T2> - class BoundTypeDiagnoser2 : public TypeDiagnoser { - unsigned DiagID; - const T1 &Arg1; - const T2 &Arg2; - - public: - BoundTypeDiagnoser2(unsigned DiagID, const T1 &Arg1, - const T2 &Arg2) - : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1), - Arg2(Arg2) { } +private: + bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, + TypeDiagnoser &Diagnoser); - void diagnose(Sema &S, SourceLocation Loc, QualType T) override { - if (Suppressed) return; - S.Diag(Loc, DiagID) << getPrintable(Arg1) << getPrintable(Arg2) << T; - } + VisibleModuleSet VisibleModules; + llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack; - virtual ~BoundTypeDiagnoser2() { } - }; + Module *CachedFakeTopLevelModule; - template<typename T1, typename T2, typename T3> - class BoundTypeDiagnoser3 : public TypeDiagnoser { - unsigned DiagID; - const T1 &Arg1; - const T2 &Arg2; - const T3 &Arg3; +public: + /// \brief Get the module owning an entity. + Module *getOwningModule(Decl *Entity); - public: - BoundTypeDiagnoser3(unsigned DiagID, const T1 &Arg1, - const T2 &Arg2, const T3 &Arg3) - : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Arg1(Arg1), - Arg2(Arg2), Arg3(Arg3) { } + /// \brief Make a merged definition of an existing hidden definition \p ND + /// visible at the specified location. + void makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc); - void diagnose(Sema &S, SourceLocation Loc, QualType T) override { - if (Suppressed) return; - S.Diag(Loc, DiagID) - << getPrintable(Arg1) << getPrintable(Arg2) << getPrintable(Arg3) << T; - } + bool isModuleVisible(Module *M) { return VisibleModules.isVisible(M); } - virtual ~BoundTypeDiagnoser3() { } - }; + /// Determine whether a declaration is visible to name lookup. + bool isVisible(const NamedDecl *D) { + return !D->isHidden() || isVisibleSlow(D); + } + bool hasVisibleMergedDefinition(NamedDecl *Def); + + /// 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(const NamedDecl *D) { + NamedDecl *Hidden; + return hasVisibleDefinition(const_cast<NamedDecl*>(D), &Hidden); + } -private: - bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, - TypeDiagnoser &Diagnoser); -public: bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser); bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID); - template<typename T1> - bool RequireCompleteType(SourceLocation Loc, QualType T, - unsigned DiagID, const T1 &Arg1) { - BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); - return RequireCompleteType(Loc, T, Diagnoser); - } - - template<typename T1, typename T2> - bool RequireCompleteType(SourceLocation Loc, QualType T, - unsigned DiagID, const T1 &Arg1, const T2 &Arg2) { - BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); - return RequireCompleteType(Loc, T, Diagnoser); - } - - template<typename T1, typename T2, typename T3> - bool RequireCompleteType(SourceLocation Loc, QualType T, - unsigned DiagID, const T1 &Arg1, const T2 &Arg2, - const T3 &Arg3) { - BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, - Arg3); + template <typename... Ts> + bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID, + const Ts &...Args) { + BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); return RequireCompleteType(Loc, T, Diagnoser); } bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser); bool RequireCompleteExprType(Expr *E, unsigned DiagID); - template<typename T1> - bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1) { - BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); - return RequireCompleteExprType(E, Diagnoser); - } - - template<typename T1, typename T2> - bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1, - const T2 &Arg2) { - BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); - return RequireCompleteExprType(E, Diagnoser); - } - - template<typename T1, typename T2, typename T3> - bool RequireCompleteExprType(Expr *E, unsigned DiagID, const T1 &Arg1, - const T2 &Arg2, const T3 &Arg3) { - BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, - Arg3); + template <typename... Ts> + bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) { + BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); return RequireCompleteExprType(E, Diagnoser); } @@ -1372,26 +1350,10 @@ public: TypeDiagnoser &Diagnoser); bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID); - template<typename T1> - bool RequireLiteralType(SourceLocation Loc, QualType T, - unsigned DiagID, const T1 &Arg1) { - BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); - return RequireLiteralType(Loc, T, Diagnoser); - } - - template<typename T1, typename T2> - bool RequireLiteralType(SourceLocation Loc, QualType T, - unsigned DiagID, const T1 &Arg1, const T2 &Arg2) { - BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); - return RequireLiteralType(Loc, T, Diagnoser); - } - - template<typename T1, typename T2, typename T3> - bool RequireLiteralType(SourceLocation Loc, QualType T, - unsigned DiagID, const T1 &Arg1, const T2 &Arg2, - const T3 &Arg3) { - BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, - Arg3); + template <typename... Ts> + bool RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID, + const Ts &...Args) { + BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); return RequireLiteralType(Loc, T, Diagnoser); } @@ -1592,6 +1554,9 @@ public: void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); void CheckShadow(Scope *S, VarDecl *D); void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); + void handleTagNumbering(const TagDecl *Tag, Scope *TagScope); + void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, + TypedefNameDecl *NewTD); void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D); NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, TypeSourceInfo *TInfo, @@ -1748,6 +1713,11 @@ public: /// #include or similar preprocessing directive. void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod); + /// \brief The parsed has entered a submodule. + void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod); + /// \brief The parser has left a submodule. + void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); + /// \brief Create an implicit import of the given module at the given /// source location, for error recovery, if possible. /// @@ -1797,6 +1767,12 @@ public: TUK_Friend // Friend declaration: 'friend struct foo;' }; + struct SkipBodyInfo { + SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {} + bool ShouldSkip; + NamedDecl *Previous; + }; + Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, @@ -1806,7 +1782,7 @@ public: bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, - bool IsTypeSpecifier); + bool IsTypeSpecifier, SkipBodyInfo *SkipBody = nullptr); Decl *ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, @@ -1871,6 +1847,11 @@ public: /// struct, or union). void ActOnTagStartDefinition(Scope *S, Decl *TagDecl); + /// \brief Invoked when we enter a tag definition that we're skipping. + void ActOnTagStartSkippedDefinition(Scope *S, Decl *TD) { + PushDeclContext(S, cast<DeclContext>(TD)); + } + Decl *ActOnObjCContainerStartDefinition(Decl *IDecl); /// ActOnStartCXXMemberDeclarations - Invoked when we have parsed a @@ -1886,6 +1867,10 @@ public: void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, SourceLocation RBraceLoc); + void ActOnTagFinishSkippedDefinition() { + PopDeclContext(); + } + void ActOnObjCContainerFinishDefinition(); /// \brief Invoked when we must temporarily exit the objective-c container @@ -1908,6 +1893,11 @@ public: bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, QualType EnumUnderlyingTy, const EnumDecl *Prev); + /// Determine whether the body of an anonymous enumeration should be skipped. + /// \param II The name of the first enumerator. + SkipBodyInfo shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, + SourceLocation IILoc); + Decl *ActOnEnumConstant(Scope *S, Decl *EnumDecl, Decl *LastEnumConstant, SourceLocation IdLoc, IdentifierInfo *Id, AttributeList *Attrs, @@ -2279,8 +2269,9 @@ public: void AddFunctionCandidates(const UnresolvedSetImpl &Functions, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, + TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr, bool SuppressUserConversions = false, - TemplateArgumentListInfo *ExplicitTemplateArgs = nullptr); + bool PartialOverloading = false); void AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, @@ -2293,7 +2284,8 @@ public: Expr::Classification ObjectClassification, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false); + bool SuppressUserConversions = false, + bool PartialOverloading = false); void AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -2302,13 +2294,15 @@ public: Expr::Classification ObjectClassification, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false); + bool SuppressUserConversions = false, + bool PartialOverloading = false); void AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, - bool SuppressUserConversions = false); + bool SuppressUserConversions = false, + bool PartialOverloading = false); void AddConversionCandidate(CXXConversionDecl *Conversion, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, @@ -2731,18 +2725,44 @@ public: bool EnteringContext = false, const ObjCObjectPointerType *OPT = nullptr); + /// \brief Process any TypoExprs in the given Expr and its children, + /// generating diagnostics as appropriate and returning a new Expr if there + /// were typos that were all successfully corrected and ExprError if one or + /// more typos could not be corrected. + /// + /// \param E The Expr to check for TypoExprs. + /// + /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its + /// initializer. + /// + /// \param Filter A function applied to a newly rebuilt Expr to determine if + /// it is an acceptable/usable result from a single combination of typo + /// corrections. As long as the filter returns ExprError, different + /// combinations of corrections will be tried until all are exhausted. ExprResult - CorrectDelayedTyposInExpr(Expr *E, + CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl = nullptr, llvm::function_ref<ExprResult(Expr *)> Filter = [](Expr *E) -> ExprResult { return E; }); ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, + CorrectDelayedTyposInExpr(Expr *E, + llvm::function_ref<ExprResult(Expr *)> Filter) { + return CorrectDelayedTyposInExpr(E, nullptr, Filter); + } + + ExprResult + CorrectDelayedTyposInExpr(ExprResult ER, VarDecl *InitDecl = nullptr, llvm::function_ref<ExprResult(Expr *)> Filter = [](Expr *E) -> ExprResult { return E; }) { return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter); } + ExprResult + CorrectDelayedTyposInExpr(ExprResult ER, + llvm::function_ref<ExprResult(Expr *)> Filter) { + return CorrectDelayedTyposInExpr(ER, nullptr, Filter); + } + void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery = true); @@ -2798,6 +2818,7 @@ public: bool checkStringLiteralArgumentAttr(const AttributeList &Attr, unsigned ArgNum, StringRef &Str, SourceLocation *ArgLocation = nullptr); + bool checkSectionName(SourceLocation LiteralLoc, StringRef Str); bool checkMSInheritanceAttrOnDefinition( CXXRecordDecl *RD, SourceRange Range, bool BestCase, MSInheritanceAttr::Spelling SemanticSpelling); @@ -2967,7 +2988,7 @@ private: /// optionally warns if there are multiple signatures. ObjCMethodDecl *LookupMethodInGlobalPool(Selector Sel, SourceRange R, bool receiverIdOrClass, - bool warn, bool instance); + bool instance); public: /// \brief - Returns instance or factory methods in global method pool for @@ -2977,8 +2998,13 @@ public: SmallVectorImpl<ObjCMethodDecl*>& Methods, bool instance); - bool AreMultipleMethodsInGlobalPool(Selector Sel, - bool instance); + bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, + SourceRange R, + bool receiverIdOrClass); + + void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, + Selector Sel, SourceRange R, + bool receiverIdOrClass); private: /// \brief - Returns a selector which best matches given argument list or @@ -3016,19 +3042,17 @@ public: /// LookupInstanceMethodInGlobalPool - Returns the method and warns if /// there are multiple signatures. ObjCMethodDecl *LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass=false, - bool warn=true) { + bool receiverIdOrClass=false) { return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, - warn, /*instance*/true); + /*instance*/true); } /// LookupFactoryMethodInGlobalPool - Returns the method and warns if /// there are multiple signatures. ObjCMethodDecl *LookupFactoryMethodInGlobalPool(Selector Sel, SourceRange R, - bool receiverIdOrClass=false, - bool warn=true) { + bool receiverIdOrClass=false) { return LookupMethodInGlobalPool(Sel, R, receiverIdOrClass, - warn, /*instance*/false); + /*instance*/false); } const ObjCMethodDecl *SelectorsForTypoCorrection(Selector Sel, @@ -3295,7 +3319,9 @@ public: StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block); - StmtResult ActOnSEHFinallyBlock(SourceLocation Loc, Stmt *Block); + void ActOnStartSEHFinallyBlock(); + void ActOnAbortSEHFinallyBlock(); + StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block); StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope); void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock); @@ -3346,7 +3372,7 @@ public: void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); - enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable }; + enum AvailabilityDiagnostic { AD_Deprecation, AD_Unavailable, AD_Partial }; void EmitAvailabilityWarning(AvailabilityDiagnostic AD, NamedDecl *D, StringRef Message, @@ -3656,7 +3682,6 @@ public: Scope *S; UnqualifiedId &Id; Decl *ObjCImpDecl; - bool HasTrailingLParen; }; ExprResult BuildMemberReferenceExpr( @@ -3695,8 +3720,7 @@ public: CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, - Decl *ObjCImpDecl, - bool HasTrailingLParen); + Decl *ObjCImpDecl); void ActOnDefaultCtorInitializers(Decl *CDtorDecl); bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, @@ -3989,7 +4013,8 @@ public: SourceLocation UsingLoc, UnqualifiedId &Name, AttributeList *AttrList, - TypeResult Type); + TypeResult Type, + Decl *DeclFromDeclSpec); /// BuildCXXConstructExpr - Creates a complete call to a constructor, /// including handling of its default argument expressions. @@ -4437,8 +4462,7 @@ public: ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr); ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, bool IsThrownVarInScope); - ExprResult CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, - bool IsThrownVarInScope); + bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E); /// ActOnCXXTypeConstructExpr - Parse construction of a specified type. /// Can be interpreted either as function-style casting ("int(x)") @@ -4489,7 +4513,7 @@ public: void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, QualType Param1, QualType Param2 = QualType(), - bool addMallocAttr = false); + bool addRestrictAttr = false); bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl* &Operator, @@ -4554,8 +4578,6 @@ public: ParsedType &ObjectType, bool &MayBePseudoDestructor); - ExprResult DiagnoseDtorReference(SourceLocation NameLoc, Expr *MemExpr); - ExprResult BuildPseudoDestructorExpr(Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, @@ -4563,8 +4585,7 @@ public: TypeSourceInfo *ScopeType, SourceLocation CCLoc, SourceLocation TildeLoc, - PseudoDestructorTypeStorage DestroyedType, - bool HasTrailingLParen); + PseudoDestructorTypeStorage DestroyedType); ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, @@ -4573,15 +4594,13 @@ public: UnqualifiedId &FirstTypeName, SourceLocation CCLoc, SourceLocation TildeLoc, - UnqualifiedId &SecondTypeName, - bool HasTrailingLParen); + UnqualifiedId &SecondTypeName); ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, SourceLocation TildeLoc, - const DeclSpec& DS, - bool HasTrailingLParen); + const DeclSpec& DS); /// MaybeCreateExprWithCleanups - If the current full-expression /// requires any cleanups, surround it with a ExprWithCleanups node. @@ -4632,7 +4651,8 @@ public: bool ActOnSuperScopeSpecifier(SourceLocation SuperLoc, SourceLocation ColonColonLoc, CXXScopeSpec &SS); - bool isAcceptableNestedNameSpecifier(const NamedDecl *SD); + bool isAcceptableNestedNameSpecifier(const NamedDecl *SD, + bool *CanCorrect = nullptr); NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS); bool isNonTypeNestedNameSpecifier(Scope *S, CXXScopeSpec &SS, @@ -4854,8 +4874,12 @@ public: /// ActOnLambdaExpr - This is called when the body of a lambda expression /// was successfully completed. ExprResult ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, - Scope *CurScope, - bool IsInstantiation = false); + Scope *CurScope); + + /// \brief Complete a lambda-expression having processed and attached the + /// lambda body. + ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, + sema::LambdaScopeInfo *LSI); /// \brief Define the "body" of the conversion from a lambda object to a /// function pointer. @@ -5056,14 +5080,6 @@ public: /// \brief Load any externally-stored vtable uses. void LoadExternalVTableUses(); - typedef LazyVector<CXXRecordDecl *, ExternalSemaSource, - &ExternalSemaSource::ReadDynamicClasses, 2, 2> - DynamicClassesType; - - /// \brief A list of all of the dynamic classes in this translation - /// unit. - DynamicClassesType DynamicClasses; - /// \brief Note that the vtable for the given class was used at the /// given location. void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, @@ -5093,6 +5109,7 @@ public: ArrayRef<CXXCtorInitializer*> MemInits, bool AnyErrors); + void checkClassLevelDLLAttribute(CXXRecordDecl *Class); void CheckCompletedCXXClass(CXXRecordDecl *Record); void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, Decl *TagDecl, @@ -5100,6 +5117,7 @@ public: SourceLocation RBrac, AttributeList *AttrList); void ActOnFinishCXXMemberDecls(); + void ActOnFinishCXXMemberDefaultArgs(Decl *D); void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template); @@ -5177,8 +5195,6 @@ public: // FIXME: I don't like this name. void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); - bool BasePathInvolvesVirtualBase(const CXXCastPath &BasePath); - bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, SourceLocation Loc, SourceRange Range, CXXCastPath *BasePath = nullptr, @@ -5305,27 +5321,10 @@ public: bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser); - template<typename T1> - bool RequireNonAbstractType(SourceLocation Loc, QualType T, - unsigned DiagID, - const T1 &Arg1) { - BoundTypeDiagnoser1<T1> Diagnoser(DiagID, Arg1); - return RequireNonAbstractType(Loc, T, Diagnoser); - } - - template<typename T1, typename T2> - bool RequireNonAbstractType(SourceLocation Loc, QualType T, - unsigned DiagID, - const T1 &Arg1, const T2 &Arg2) { - BoundTypeDiagnoser2<T1, T2> Diagnoser(DiagID, Arg1, Arg2); - return RequireNonAbstractType(Loc, T, Diagnoser); - } - - template<typename T1, typename T2, typename T3> - bool RequireNonAbstractType(SourceLocation Loc, QualType T, - unsigned DiagID, - const T1 &Arg1, const T2 &Arg2, const T3 &Arg3) { - BoundTypeDiagnoser3<T1, T2, T3> Diagnoser(DiagID, Arg1, Arg2, Arg3); + template <typename... Ts> + bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, + const Ts &...Args) { + BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); return RequireNonAbstractType(Loc, T, Diagnoser); } @@ -5437,7 +5436,8 @@ public: SourceLocation ModulePrivateLoc, SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists, - TemplateParameterList **OuterTemplateParamLists); + TemplateParameterList **OuterTemplateParamLists, + SkipBodyInfo *SkipBody = nullptr); void translateTemplateArguments(const ASTTemplateArgsPtr &In, TemplateArgumentListInfo &Out); @@ -5510,7 +5510,8 @@ public: SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId, AttributeList *Attr, - MultiTemplateParamsArg TemplateParameterLists); + MultiTemplateParamsArg TemplateParameterLists, + SkipBodyInfo *SkipBody = nullptr); Decl *ActOnTemplateDeclarator(Scope *S, MultiTemplateParamsArg TemplateParameterLists, @@ -6181,14 +6182,16 @@ public: unsigned NumExplicitlySpecified, FunctionDecl *&Specialization, sema::TemplateDeductionInfo &Info, - SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr); + SmallVectorImpl<OriginalCallArg> const *OriginalCallArgs = nullptr, + bool PartialOverloading = false); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef<Expr *> Args, FunctionDecl *&Specialization, - sema::TemplateDeductionInfo &Info); + sema::TemplateDeductionInfo &Info, + bool PartialOverloading = false); TemplateDeductionResult DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, @@ -6593,19 +6596,17 @@ public: bool CheckInstantiationDepth(SourceLocation PointOfInstantiation, SourceRange InstantiationRange); - // FIXME: Replace this with a constructor once we can use delegating - // constructors in llvm. - void Initialize( - ActiveTemplateInstantiation::InstantiationKind Kind, + InstantiatingTemplate( + Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind, SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template = nullptr, ArrayRef<TemplateArgument> TemplateArgs = ArrayRef<TemplateArgument>(), sema::TemplateDeductionInfo *DeductionInfo = nullptr); - InstantiatingTemplate(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION; + InstantiatingTemplate(const InstantiatingTemplate&) = delete; InstantiatingTemplate& - operator=(const InstantiatingTemplate&) LLVM_DELETED_FUNCTION; + operator=(const InstantiatingTemplate&) = delete; }; void PrintInstantiationStack(); @@ -6703,6 +6704,7 @@ public: /// \brief Worker object for performing CFG-based warnings. sema::AnalysisBasedWarnings AnalysisWarnings; + threadSafety::BeforeSet *ThreadSafetyDeclCache; /// \brief An entity for which implicit template instantiation is required. /// @@ -6720,12 +6722,17 @@ public: class SavePendingInstantiationsAndVTableUsesRAII { public: - SavePendingInstantiationsAndVTableUsesRAII(Sema &S): S(S) { + SavePendingInstantiationsAndVTableUsesRAII(Sema &S, bool Enabled) + : S(S), Enabled(Enabled) { + if (!Enabled) return; + SavedPendingInstantiations.swap(S.PendingInstantiations); SavedVTableUses.swap(S.VTableUses); } ~SavePendingInstantiationsAndVTableUsesRAII() { + if (!Enabled) return; + // Restore the set of pending vtables. assert(S.VTableUses.empty() && "VTableUses should be empty before it is discarded."); @@ -6741,6 +6748,7 @@ public: Sema &S; SmallVector<VTableUse, 16> SavedVTableUses; std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; + bool Enabled; }; /// \brief The queue of implicit template instantiations that are required @@ -7030,7 +7038,7 @@ public: unsigned NumElts, AttributeList *attrList); - void FindProtocolDeclaration(bool WarnOnDeclarations, + void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, const IdentifierLocPair *ProtocolId, unsigned NumProtocols, SmallVectorImpl<Decl *> &Protocols); @@ -7471,6 +7479,11 @@ public: void AddAlignValueAttr(SourceRange AttrRange, Decl *D, Expr *E, unsigned SpellingListIndex); + /// AddLaunchBoundsAttr - Adds a launch_bounds attribute to a particular + /// declaration. + void AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, + Expr *MinBlocks, unsigned SpellingListIndex); + // OpenMP directives and clauses. private: void *VarDataSharingAttributesStack; @@ -7490,9 +7503,19 @@ public: void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc); + /// \brief Start analysis of clauses. + void StartOpenMPClauses(); + /// \brief End analysis of clauses. + void EndOpenMPClauses(); /// \brief Called on end of data sharing attribute block. void EndOpenMPDSABlock(Stmt *CurDirective); + /// \brief Check if the current region is an OpenMP loop region and if it is, + /// mark loop control variable, used in \p Init for loop initialization, as + /// private by default. + /// \param Init First part of the for loop. + void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init); + // OpenMP directives and clauses. /// \brief Called on correct id-expression from the '#pragma omp /// threadprivate'. @@ -7510,6 +7533,13 @@ public: /// \brief Initialization of captured region for OpenMP region. void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); + /// \brief End of OpenMP region. + /// + /// \param S Statement associated with the current OpenMP region. + /// \param Clauses List of clauses for the current OpenMP region. + /// + /// \returns Statement for finished OpenMP region. + StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses); StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, @@ -7971,6 +8001,12 @@ public: Expr *SrcExpr, AssignmentAction Action, bool *Complained = nullptr); + /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag + /// enum. If AllowMask is true, then we also allow the complement of a valid + /// value, to be used as a mask. + bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, + bool AllowMask) const; + /// DiagnoseAssignmentEnum - Warn if assignment to enum is a constant /// integer not in the range of enum values. void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, @@ -8398,6 +8434,8 @@ public: void CodeCompleteTypeQualifiers(DeclSpec &DS); void CodeCompleteCase(Scope *S); void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args); + void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, + ArrayRef<Expr *> Args); void CodeCompleteInitializer(Scope *S, Decl *D); void CodeCompleteReturn(Scope *S); void CodeCompleteAfterIf(Scope *S); @@ -8531,8 +8569,10 @@ private: bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - + bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool SemaBuiltinVAStart(CallExpr *TheCall); bool SemaBuiltinVAStartARM(CallExpr *Call); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); @@ -8567,6 +8607,8 @@ public: FST_Strftime, FST_Strfmon, FST_Kprintf, + FST_FreeBSDKPrintf, + FST_OSTrace, FST_Unknown }; static FormatStringType GetFormatStringType(const FormatAttr *Format); @@ -8634,6 +8676,13 @@ private: /// statement that produces control flow different from GCC. void CheckBreakContinueBinding(Expr *E); + /// \brief Check whether receiver is mutable ObjC container which + /// attempts to add itself into the container + void CheckObjCCircularContainer(ObjCMessageExpr *Message); + + void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE); + void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc, + bool DeleteWasArrayForm); public: /// \brief Register a magic integral constant to be used as a type tag. void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, @@ -8682,6 +8731,7 @@ protected: friend class Parser; friend class InitializationSequence; friend class ASTReader; + friend class ASTDeclReader; friend class ASTWriter; public: @@ -8695,8 +8745,8 @@ public: /// template substitution or instantiation. Scope *getCurScope() const { return CurScope; } - void incrementMSLocalManglingNumber() const { - return CurScope->incrementMSLocalManglingNumber(); + void incrementMSManglingNumber() const { + return CurScope->incrementMSManglingNumber(); } IdentifierInfo *getSuperIdentifier() const; @@ -8717,6 +8767,16 @@ public: DC = CatD->getClassInterface(); return DC; } + + /// \brief To be used for checking whether the arguments being passed to + /// function exceeds the number of parameters expected for it. + static bool TooManyArguments(size_t NumParams, size_t NumArgs, + bool PartialOverloading = false) { + // We check whether we're just after a comma in code-completion. + if (NumArgs > 0 && PartialOverloading) + return NumArgs + 1 > NumParams; // If so, we view as an extra argument. + return NumArgs > NumParams; + } }; /// \brief RAII object that enters a new expression evaluation context. diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index 005d882..60c6598 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -48,6 +48,18 @@ inline bool IsVariableAConstantExpression(VarDecl *Var, ASTContext &Context) { Var->getAnyInitializer(DefVD) && DefVD->checkInitIsICE(); } +// Helper function to check whether D's attributes match current CUDA mode. +// Decls with mismatched attributes and related diagnostics may have to be +// ignored during this CUDA compilation pass. +inline bool DeclAttrsMatchCUDAMode(const LangOptions &LangOpts, Decl *D) { + if (!LangOpts.CUDA || !D) + return true; + bool isDeviceSideDecl = D->hasAttr<CUDADeviceAttr>() || + D->hasAttr<CUDASharedAttr>() || + D->hasAttr<CUDAGlobalAttr>(); + return isDeviceSideDecl == LangOpts.CUDAIsDevice; +} + // Directly mark a variable odr-used. Given a choice, prefer to use // MarkVariableReferenced since it does additional checks and then // calls MarkVarDeclODRUsed. @@ -221,18 +233,13 @@ private: std::string CurNameSpecifier; SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers; SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers; - bool isSorted; - SpecifierInfoList Specifiers; - llvm::SmallSetVector<unsigned, 4> Distances; - llvm::DenseMap<unsigned, SpecifierInfoList> DistanceMap; + std::map<unsigned, SpecifierInfoList> DistanceMap; /// \brief Helper for building the list of DeclContexts between the current /// context and the top of the translation unit static DeclContextList buildContextChain(DeclContext *Start); - void sortNamespaces(); - unsigned buildNestedNameSpecifier(DeclContextList &DeclChain, NestedNameSpecifier *&NNS); @@ -244,12 +251,40 @@ private: /// the corresponding NestedNameSpecifier and its distance in the process. void addNameSpecifier(DeclContext *Ctx); - typedef SpecifierInfoList::iterator iterator; - iterator begin() { - if (!isSorted) sortNamespaces(); - return Specifiers.begin(); - } - iterator end() { return Specifiers.end(); } + /// \brief Provides flat iteration over specifiers, sorted by distance. + class iterator + : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag, + SpecifierInfo> { + /// Always points to the last element in the distance map. + const std::map<unsigned, SpecifierInfoList>::iterator OuterBack; + /// Iterator on the distance map. + std::map<unsigned, SpecifierInfoList>::iterator Outer; + /// Iterator on an element in the distance map. + SpecifierInfoList::iterator Inner; + + public: + iterator(NamespaceSpecifierSet &Set, bool IsAtEnd) + : OuterBack(std::prev(Set.DistanceMap.end())), + Outer(Set.DistanceMap.begin()), + Inner(!IsAtEnd ? Outer->second.begin() : OuterBack->second.end()) { + assert(!Set.DistanceMap.empty()); + } + + iterator &operator++() { + ++Inner; + if (Inner == Outer->second.end() && Outer != OuterBack) { + ++Outer; + Inner = Outer->second.begin(); + } + return *this; + } + + SpecifierInfo &operator*() { return *Inner; } + bool operator==(const iterator &RHS) const { return Inner == RHS.Inner; } + }; + + iterator begin() { return iterator(*this, /*IsAtEnd=*/false); } + iterator end() { return iterator(*this, /*IsAtEnd=*/true); } }; void addName(StringRef Name, NamedDecl *ND, diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index 8f0d9da..b822b11 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -239,8 +239,8 @@ namespace clang { // This class is non-copyable LocalInstantiationScope( - const LocalInstantiationScope &) LLVM_DELETED_FUNCTION; - void operator=(const LocalInstantiationScope &) LLVM_DELETED_FUNCTION; + const LocalInstantiationScope &) = delete; + void operator=(const LocalInstantiationScope &) = delete; public: LocalInstantiationScope(Sema &SemaRef, bool CombineWithOuterScope = false) diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index 8338d97..229eb71 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -44,8 +44,8 @@ class TemplateDeductionInfo { /// SFINAE while performing template argument deduction. SmallVector<PartialDiagnosticAt, 4> SuppressedDiagnostics; - TemplateDeductionInfo(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; - void operator=(const TemplateDeductionInfo &) LLVM_DELETED_FUNCTION; + TemplateDeductionInfo(const TemplateDeductionInfo &) = delete; + void operator=(const TemplateDeductionInfo &) = delete; public: TemplateDeductionInfo(SourceLocation Loc) @@ -91,9 +91,7 @@ public: if (HasSFINAEDiagnostic) return; SuppressedDiagnostics.clear(); - SuppressedDiagnostics.push_back( - std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); - SuppressedDiagnostics.back().second.swap(PD); + SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); HasSFINAEDiagnostic = true; } @@ -102,9 +100,7 @@ public: PartialDiagnostic PD) { if (HasSFINAEDiagnostic) return; - SuppressedDiagnostics.push_back( - std::make_pair(Loc, PartialDiagnostic::NullDiagnostic())); - SuppressedDiagnostics.back().second.swap(PD); + SuppressedDiagnostics.emplace_back(Loc, std::move(PD)); } /// \brief Iterator over the set of suppressed diagnostics. @@ -252,8 +248,8 @@ class TemplateSpecCandidateSet { SourceLocation Loc; TemplateSpecCandidateSet( - const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; - void operator=(const TemplateSpecCandidateSet &) LLVM_DELETED_FUNCTION; + const TemplateSpecCandidateSet &) = delete; + void operator=(const TemplateSpecCandidateSet &) = delete; void destroyCandidates(); @@ -277,7 +273,7 @@ public: /// \brief Add a new candidate with NumConversions conversion sequence slots /// to the overload set. TemplateSpecCandidate &addCandidate() { - Candidates.push_back(TemplateSpecCandidate()); + Candidates.emplace_back(); return Candidates.back(); } diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index 922d0ff..958aab0 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -165,7 +165,7 @@ public: } /// \brief Returns whether this TypoCorrection has a non-empty DeclarationName - LLVM_EXPLICIT operator bool() const { return bool(CorrectionName); } + explicit operator bool() const { return bool(CorrectionName); } /// \brief Mark this TypoCorrection as being a keyword. /// Since addCorrectionDeclsand setCorrectionDecl don't allow NULL to be diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 3874f3a..e0f01c8 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -149,7 +149,11 @@ namespace clang { /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an /// AST file. typedef uint32_t CXXBaseSpecifiersID; - + + /// \brief An ID number that refers to a list of CXXCtorInitializers in an + /// AST file. + typedef uint32_t CXXCtorInitializersID; + /// \brief An ID number that refers to an entity in the detailed /// preprocessing record. typedef uint32_t PreprocessedEntityID; @@ -295,6 +299,10 @@ namespace clang { /// \brief Record code for the module build directory. MODULE_DIRECTORY = 16, + + /// \brief Record code for the list of other AST files made available by + /// this AST file but not actually used by it. + KNOWN_MODULE_FILES = 17, }; /// \brief Record types that occur within the input-files block @@ -385,9 +393,7 @@ namespace clang { /// \brief Record code for the array of tentative definitions. TENTATIVE_DEFINITIONS = 9, - /// \brief Record code for the array of locally-scoped extern "C" - /// declarations. - LOCALLY_SCOPED_EXTERN_C_DECLS = 10, + // ID 10 used to be for a list of extern "C" declarations. /// \brief Record code for the table of offsets into the /// Objective-C method pool. @@ -425,8 +431,7 @@ namespace clang { /// \brief Record code for the array of VTable uses. VTABLE_USES = 19, - /// \brief Record code for the array of dynamic classes. - DYNAMIC_CLASSES = 20, + // ID 20 used to be for a list of dynamic classes. /// \brief Record code for referenced selector pool. REFERENCED_SELECTOR_POOL = 21, @@ -516,8 +521,7 @@ namespace clang { /// imported by the AST file. IMPORTED_MODULES = 43, - /// \brief Record code for the set of merged declarations in an AST file. - MERGED_DECLARATIONS = 44, + // ID 40 used to be a table of merged canonical declarations. /// \brief Record code for the array of redeclaration chains. /// @@ -539,9 +543,7 @@ namespace clang { /// macro definition. MACRO_OFFSET = 47, - /// \brief Mapping table from the identifier ID to the offset of the - /// macro directive history for the identifier. - MACRO_TABLE = 48, + // ID 48 used to be a table of macros. /// \brief Record code for undefined but used functions and variables that /// need a definition in this TU. @@ -555,6 +557,13 @@ namespace clang { /// \brief Record code for potentially unused local typedef names. UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52, + + /// \brief Record code for the table of offsets to CXXCtorInitializers + /// lists. + CXX_CTOR_INITIALIZERS_OFFSETS = 53, + + /// \brief Delete expressions that will be analyzed later. + DELETE_EXPRS_TO_ANALYZE = 54 }; /// \brief Record types used within a source manager block. @@ -594,7 +603,11 @@ namespace clang { PP_TOKEN = 3, /// \brief The macro directives history for a particular identifier. - PP_MACRO_DIRECTIVE_HISTORY = 4 + PP_MACRO_DIRECTIVE_HISTORY = 4, + + /// \brief A macro directive exported by a module. + /// [PP_MODULE_MACRO, SubmoduleID, MacroID, (Overridden SubmoduleID)*] + PP_MODULE_MACRO = 5, }; /// \brief Record types used within a preprocessor detail block. @@ -927,14 +940,17 @@ namespace clang { PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, /// \brief The internal '__builtin_va_list' typedef. - PREDEF_DECL_BUILTIN_VA_LIST_ID = 9 + PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, + + /// \brief The extern "C" context. + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 10, }; /// \brief The number of declaration IDs that are predefined. /// /// For more information about predefined declarations, see the /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. - const unsigned int NUM_PREDEF_DECL_IDS = 10; + const unsigned int NUM_PREDEF_DECL_IDS = 11; /// \brief Record codes for each kind of declaration. /// @@ -1071,6 +1087,8 @@ namespace clang { DECL_STATIC_ASSERT, /// \brief A record containing CXXBaseSpecifiers. DECL_CXX_BASE_SPECIFIERS, + /// \brief A record containing CXXCtorInitializers. + DECL_CXX_CTOR_INITIALIZERS, /// \brief A IndirectFieldDecl record. DECL_INDIRECTFIELD, /// \brief A NonTypeTemplateParmDecl record that stores an expanded @@ -1094,13 +1112,13 @@ namespace clang { /// /// These constants describe the records that describe statements /// or expressions. These records occur within type and declarations - /// block, so they begin with record values of 100. Each constant + /// block, so they begin with record values of 128. Each constant /// describes a record for a specific statement or expression class in the /// AST. enum StmtCode { /// \brief A marker record that indicates that we are at the end /// of an expression. - STMT_STOP = 100, + STMT_STOP = 128, /// \brief A NULL expression. STMT_NULL_PTR, /// \brief A reference to a previously [de]serialized Stmt record. diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h index c24ccdc..4b10c39 100644 --- a/include/clang/Serialization/ASTDeserializationListener.h +++ b/include/clang/Serialization/ASTDeserializationListener.h @@ -23,10 +23,10 @@ namespace clang { class Decl; class ASTReader; class QualType; -class MacroDefinition; +class MacroDefinitionRecord; class MacroInfo; class Module; - + class ASTDeserializationListener { public: virtual ~ASTDeserializationListener(); @@ -46,14 +46,13 @@ public: /// \brief A decl was deserialized from the AST file. virtual void DeclRead(serialization::DeclID ID, const Decl *D) { } /// \brief A selector was read from the AST file. - virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) { } + virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} /// \brief A macro definition was read from the AST file. - virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, - MacroDefinition *MD) { } + virtual void MacroDefinitionRead(serialization::PreprocessedEntityID, + MacroDefinitionRecord *MD) {} /// \brief A module definition was read from the AST file. - virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) { } + virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {} }; - } #endif diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 91ad34b..c7cc1be 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -73,6 +73,7 @@ class GlobalModuleIndex; class GotoStmt; class MacroDefinition; class MacroDirective; +class ModuleMacro; class NamedDecl; class OpaqueValueExpr; class Preprocessor; @@ -124,8 +125,8 @@ public: /// /// \returns true to indicate the target options are invalid, or false /// otherwise. - virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) { + virtual bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) { return false; } @@ -153,6 +154,7 @@ public: /// \returns true to indicate the header search options are invalid, or false /// otherwise. virtual bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, bool Complain) { return false; } @@ -222,14 +224,15 @@ public: void ReadModuleMapFile(StringRef ModuleMapPath) override; bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, bool AllowCompatibleDifferences) override; - bool ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) override; + bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) override; bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) override; bool ReadFileSystemOptions(const FileSystemOptions &FSOpts, bool Complain) override; bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, bool Complain) override; bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, @@ -255,12 +258,15 @@ public: bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, bool AllowCompatibleDifferences) override; - bool ReadTargetOptions(const TargetOptions &TargetOpts, - bool Complain) override; + bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain, + bool AllowCompatibleDifferences) override; bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) override; bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts, bool Complain, std::string &SuggestedPredefines) override; + bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts, + StringRef SpecificModuleCachePath, + bool Complain) override; void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override; private: @@ -435,6 +441,18 @@ private: llvm::SmallVector<std::pair<serialization::GlobalDeclID, Decl*>, 16> PendingUpdateRecords; + enum class PendingFakeDefinitionKind { NotFake, Fake, FakeLoaded }; + + /// \brief The DefinitionData pointers that we faked up for class definitions + /// that we needed but hadn't loaded yet. + llvm::DenseMap<void *, PendingFakeDefinitionKind> PendingFakeDefinitionData; + + /// \brief Exception specification updates that have been loaded but not yet + /// propagated across the relevant redeclaration chain. The map key is the + /// canonical declaration (used only for deduplication) and the value is a + /// declaration that has an exception specification. + llvm::SmallMapVector<Decl *, FunctionDecl *, 4> PendingExceptionSpecUpdates; + struct ReplacedDeclInfo { ModuleFile *Mod; uint64_t Offset; @@ -498,6 +516,10 @@ private: /// \brief Functions or methods that have bodies that will be attached. PendingBodiesMap PendingBodies; + /// \brief Definitions for which we have added merged definitions but not yet + /// performed deduplication. + llvm::SetVector<NamedDecl*> PendingMergedDefinitionsToDeduplicate; + /// \brief Read the records that describe the contents of declcontexts. bool ReadDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, @@ -528,6 +550,14 @@ private: /// been loaded. std::vector<MacroInfo *> MacrosLoaded; + typedef std::pair<IdentifierInfo *, serialization::SubmoduleID> + LoadedMacroInfo; + + /// \brief A set of #undef directives that we have loaded; used to + /// deduplicate the same #undef information coming from multiple module + /// files. + llvm::DenseSet<LoadedMacroInfo> LoadedUndefs; + typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4> GlobalMacroMapType; @@ -550,54 +580,8 @@ private: /// global submodule ID to produce a local ID. GlobalSubmoduleMapType GlobalSubmoduleMap; - /// \brief Information on a macro definition or undefinition that is visible - /// at the end of a submodule. - struct ModuleMacroInfo; - - /// \brief An entity that has been hidden. - class HiddenName { - public: - enum NameKind { - Declaration, - Macro - } Kind; - - private: - union { - Decl *D; - ModuleMacroInfo *MMI; - }; - - IdentifierInfo *Id; - - public: - HiddenName(Decl *D) : Kind(Declaration), D(D), Id() { } - - HiddenName(IdentifierInfo *II, ModuleMacroInfo *MMI) - : Kind(Macro), MMI(MMI), Id(II) { } - - NameKind getKind() const { return Kind; } - - Decl *getDecl() const { - assert(getKind() == Declaration && "Hidden name is not a declaration"); - return D; - } - - std::pair<IdentifierInfo *, ModuleMacroInfo *> getMacro() const { - assert(getKind() == Macro && "Hidden name is not a macro!"); - return std::make_pair(Id, MMI); - } - }; - - typedef llvm::SmallDenseMap<IdentifierInfo*, - ModuleMacroInfo*> HiddenMacrosMap; - /// \brief A set of hidden declarations. - struct HiddenNames { - SmallVector<Decl*, 2> HiddenDecls; - HiddenMacrosMap HiddenMacros; - }; - + typedef SmallVector<Decl*, 2> HiddenNames; typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType; /// \brief A mapping from each of the hidden submodules to the deserialized @@ -651,30 +635,10 @@ private: struct PendingMacroInfo { ModuleFile *M; + uint64_t MacroDirectivesOffset; - struct ModuleMacroDataTy { - uint32_t MacID; - serialization::SubmoduleID *Overrides; - }; - struct PCHMacroDataTy { - uint64_t MacroDirectivesOffset; - }; - - union { - ModuleMacroDataTy ModuleMacroData; - PCHMacroDataTy PCHMacroData; - }; - - PendingMacroInfo(ModuleFile *M, - uint32_t MacID, - serialization::SubmoduleID *Overrides) : M(M) { - ModuleMacroData.MacID = MacID; - ModuleMacroData.Overrides = Overrides; - } - - PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) : M(M) { - PCHMacroData.MacroDirectivesOffset = MacroDirectivesOffset; - } + PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) + : M(M), MacroDirectivesOffset(MacroDirectivesOffset) {} }; typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> > @@ -759,18 +723,6 @@ private: /// \brief Fields containing data that is used for semantic analysis //@{ - /// \brief The IDs of all locally scoped extern "C" decls in the chain. - /// - /// Sema tracks these to validate that the types are consistent across all - /// local extern "C" declarations. - SmallVector<uint64_t, 16> LocallyScopedExternCDecls; - - /// \brief The IDs of all dynamic class declarations in the chain. - /// - /// Sema tracks these because it checks for the key functions being defined - /// at the end of the TU, in which case it directs CodeGen to emit the VTable. - SmallVector<uint64_t, 16> DynamicClasses; - /// \brief The IDs of all potentially unused typedef names in the chain. /// /// Sema tracks these to emit warnings. @@ -808,6 +760,9 @@ private: /// SourceLocation of a matching ODR-use. SmallVector<uint64_t, 8> UndefinedButUsed; + /// \brief Delete expressions to analyze at the end of translation unit. + SmallVector<uint64_t, 8> DelayedDeleteExprs; + // \brief A list of late parsed template function data. SmallVector<uint64_t, 1> LateParsedTemplates; @@ -930,9 +885,6 @@ private: /// passing decls to consumer. bool PassingDeclsToConsumer; - /// Number of CXX base specifiers currently loaded - unsigned NumCXXBaseSpecifiersLoaded; - /// \brief The set of identifiers that were read while the AST reader was /// (recursively) loading declarations. /// @@ -941,6 +893,11 @@ private: llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> > PendingIdentifierInfos; + /// \brief The set of lookup results that we have faked in order to support + /// merging of partially deserialized decls but that we have not yet removed. + llvm::SmallMapVector<IdentifierInfo *, SmallVector<NamedDecl*, 2>, 16> + PendingFakeLookupResults; + /// \brief The generation number of each identifier, which keeps track of /// the last time we loaded information about this identifier. llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration; @@ -960,13 +917,13 @@ private: /// \brief The list of redeclaration chains that still need to be /// reconstructed. /// - /// Each element is the global declaration ID of the first declaration in - /// the chain. Elements in this vector should be unique; use + /// Each element is the canonical declaration of the chain. + /// Elements in this vector should be unique; use /// PendingDeclChainsKnown to ensure uniqueness. - SmallVector<serialization::DeclID, 16> PendingDeclChains; + SmallVector<Decl *, 16> PendingDeclChains; /// \brief Keeps track of the elements added to PendingDeclChains. - llvm::SmallSet<serialization::DeclID, 16> PendingDeclChainsKnown; + llvm::SmallSet<Decl *, 16> PendingDeclChainsKnown; /// \brief The list of canonical declarations whose redeclaration chains /// need to be marked as incomplete once we're done deserializing things. @@ -1026,26 +983,6 @@ private: /// that canonical declaration. MergedDeclsMap MergedDecls; - typedef llvm::DenseMap<serialization::GlobalDeclID, - SmallVector<serialization::DeclID, 2> > - StoredMergedDeclsMap; - - /// \brief A mapping from canonical declaration IDs to the set of additional - /// declaration IDs that have been merged with that canonical declaration. - /// - /// This is the deserialized representation of the entries in MergedDecls. - /// When we query entries in MergedDecls, they will be augmented with entries - /// from StoredMergedDecls. - StoredMergedDeclsMap StoredMergedDecls; - - /// \brief Combine the stored merged declarations for the given canonical - /// declaration into the set of merged declarations. - /// - /// \returns An iterator into MergedDecls that corresponds to the position of - /// the given canonical declaration. - MergedDeclsMap::iterator - combineStoredMergedDecls(Decl *Canon, serialization::GlobalDeclID CanonID); - /// \brief A mapping from DeclContexts to the semantic DeclContext that we /// are treating as the definition of the entity. This is used, for instance, /// when merging implicit instantiations of class templates across modules. @@ -1071,8 +1008,8 @@ private: ASTReader &Reader; enum ReadingKind PrevKind; - ReadingKindTracker(const ReadingKindTracker &) LLVM_DELETED_FUNCTION; - void operator=(const ReadingKindTracker &) LLVM_DELETED_FUNCTION; + ReadingKindTracker(const ReadingKindTracker &) = delete; + void operator=(const ReadingKindTracker &) = delete; public: ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader) @@ -1153,7 +1090,8 @@ private: ASTReaderListener &Listener, bool AllowCompatibleDifferences); static bool ParseTargetOptions(const RecordData &Record, bool Complain, - ASTReaderListener &Listener); + ASTReaderListener &Listener, + bool AllowCompatibleDifferences); static bool ParseDiagnosticOptions(const RecordData &Record, bool Complain, ASTReaderListener &Listener); static bool ParseFileSystemOptions(const RecordData &Record, bool Complain, @@ -1180,10 +1118,28 @@ private: void LoadedDecl(unsigned Index, Decl *D); Decl *ReadDeclRecord(serialization::DeclID ID); void markIncompleteDeclChain(Decl *Canon); + + /// \brief Returns the most recent declaration of a declaration (which must be + /// of a redeclarable kind) that is either local or has already been loaded + /// merged into its redecl chain. + Decl *getMostRecentExistingDecl(Decl *D); + + template <typename Fn> + void forEachFormerlyCanonicalImportedDecl(const Decl *D, Fn Visit) { + D = D->getCanonicalDecl(); + if (D->isFromASTFile()) + Visit(D); + + auto It = MergedDecls.find(const_cast<Decl*>(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); - void loadPendingDeclChain(serialization::GlobalDeclID ID); + void loadPendingDeclChain(Decl *D); void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration = 0); @@ -1212,66 +1168,38 @@ private: /// \brief Returns (begin, end) pair for the preprocessed entities of a /// particular module. - std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> - getModulePreprocessedEntities(ModuleFile &Mod) const; - - class ModuleDeclIterator { + llvm::iterator_range<PreprocessingRecord::iterator> + getModulePreprocessedEntities(ModuleFile &Mod) const; + + class ModuleDeclIterator + : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const serialization::LocalDeclID *, + std::random_access_iterator_tag, const Decl *, ptrdiff_t, + const Decl *, const Decl *> { ASTReader *Reader; ModuleFile *Mod; - const serialization::LocalDeclID *Pos; public: - typedef const Decl *value_type; - typedef value_type& reference; - typedef value_type* pointer; - - ModuleDeclIterator() : Reader(nullptr), Mod(nullptr), Pos(nullptr) { } + ModuleDeclIterator() + : iterator_adaptor_base(nullptr), Reader(nullptr), Mod(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, const serialization::LocalDeclID *Pos) - : Reader(Reader), Mod(Mod), Pos(Pos) { } + : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} value_type operator*() const { - return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *Pos)); + return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I)); } + value_type operator->() const { return **this; } - ModuleDeclIterator &operator++() { - ++Pos; - return *this; - } - - ModuleDeclIterator operator++(int) { - ModuleDeclIterator Prev(*this); - ++Pos; - return Prev; - } - - ModuleDeclIterator &operator--() { - --Pos; - return *this; - } - - ModuleDeclIterator operator--(int) { - ModuleDeclIterator Prev(*this); - --Pos; - return Prev; - } - - friend bool operator==(const ModuleDeclIterator &LHS, - const ModuleDeclIterator &RHS) { - assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod); - return LHS.Pos == RHS.Pos; - } - - friend bool operator!=(const ModuleDeclIterator &LHS, - const ModuleDeclIterator &RHS) { - assert(LHS.Reader == RHS.Reader && LHS.Mod == RHS.Mod); - return LHS.Pos != RHS.Pos; + bool operator==(const ModuleDeclIterator &RHS) const { + assert(Reader == RHS.Reader && Mod == RHS.Mod); + return I == RHS.I; } }; - std::pair<ModuleDeclIterator, ModuleDeclIterator> - getModuleFileLevelDecls(ModuleFile &Mod); + llvm::iterator_range<ModuleDeclIterator> + getModuleFileLevelDecls(ModuleFile &Mod); void PassInterestingDeclsToConsumer(); void PassInterestingDeclToConsumer(Decl *D); @@ -1297,8 +1225,8 @@ private: void Error(unsigned DiagID, StringRef Arg1 = StringRef(), StringRef Arg2 = StringRef()); - ASTReader(const ASTReader &) LLVM_DELETED_FUNCTION; - void operator=(const ASTReader &) LLVM_DELETED_FUNCTION; + ASTReader(const ASTReader &) = delete; + void operator=(const ASTReader &) = delete; public: /// \brief Load the AST file and validate its contents against the given /// Preprocessor. @@ -1337,7 +1265,7 @@ public: bool ValidateSystemInputs = false, bool UseGlobalIndex = true); - ~ASTReader(); + ~ASTReader() override; SourceManager &getSourceManager() const { return SourceMgr; } FileManager &getFileManager() const { return FileMgr; } @@ -1391,16 +1319,12 @@ public: /// module. Visibility can only be increased over time. /// /// \param ImportLoc The location at which the import occurs. - /// - /// \param Complain Whether to complain about conflicting module imports. void makeModuleVisible(Module *Mod, Module::NameVisibilityKind NameVisibility, - SourceLocation ImportLoc, - bool Complain); + SourceLocation ImportLoc); /// \brief Make the names within this set of hidden names visible. - void makeNamesVisible(const HiddenNames &Names, Module *Owner, - bool FromFinalization); + void makeNamesVisible(const HiddenNames &Names, Module *Owner); /// \brief Take the AST callbacks listener. std::unique_ptr<ASTReaderListener> takeListener() { @@ -1518,7 +1442,8 @@ public: FileManager &FileMgr, const LangOptions &LangOpts, const TargetOptions &TargetOpts, - const PreprocessorOptions &PPOpts); + const PreprocessorOptions &PPOpts, + std::string ExistingModuleCachePath); /// \brief Returns the suggested contents of the predefines buffer, /// which contains a (typically-empty) subset of the predefines @@ -1593,11 +1518,6 @@ public: return Result; } - /// \brief Returns the number of C++ base specifiers found in the chain. - unsigned getTotalNumCXXBaseSpecifiers() const { - return NumCXXBaseSpecifiersLoaded; - } - /// \brief Reads a TemplateArgumentLocInfo appropriate for the /// given TemplateArgument kind. TemplateArgumentLocInfo @@ -1823,6 +1743,10 @@ public: void ReadUndefinedButUsed( llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override; + void ReadMismatchingDeleteExpressions(llvm::MapVector< + FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & + Exprs) override; + void ReadTentativeDefinitions( SmallVectorImpl<VarDecl *> &TentativeDefs) override; @@ -1834,14 +1758,9 @@ public: void ReadExtVectorDecls(SmallVectorImpl<TypedefNameDecl *> &Decls) override; - void ReadDynamicClasses(SmallVectorImpl<CXXRecordDecl *> &Decls) override; - void ReadUnusedLocalTypedefNameCandidates( llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; - void ReadLocallyScopedExternCDecls( - SmallVectorImpl<NamedDecl *> &Decls) override; - void ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override; @@ -1855,8 +1774,8 @@ public: SourceLocation> > &Pending) override; void ReadLateParsedTemplates( - llvm::DenseMap<const FunctionDecl *, - LateParsedTemplate *> &LPTMap) override; + llvm::MapVector<const FunctionDecl *, LateParsedTemplate *> &LPTMap) + override; /// \brief Load a selector from disk, registering its ID if it exists. void LoadSelector(Selector Sel); @@ -1891,28 +1810,8 @@ public: serialization::IdentifierID getGlobalIdentifierID(ModuleFile &M, unsigned LocalID); - ModuleMacroInfo *getModuleMacro(const PendingMacroInfo &PMInfo); - void resolvePendingMacro(IdentifierInfo *II, const PendingMacroInfo &PMInfo); - void installPCHMacroDirectives(IdentifierInfo *II, - ModuleFile &M, uint64_t Offset); - - void installImportedMacro(IdentifierInfo *II, ModuleMacroInfo *MMI, - Module *Owner); - - typedef llvm::TinyPtrVector<DefMacroDirective *> AmbiguousMacros; - llvm::DenseMap<IdentifierInfo*, AmbiguousMacros> AmbiguousMacroDefs; - - void - removeOverriddenMacros(IdentifierInfo *II, SourceLocation Loc, - AmbiguousMacros &Ambig, - ArrayRef<serialization::SubmoduleID> Overrides); - - AmbiguousMacros * - removeOverriddenMacros(IdentifierInfo *II, SourceLocation Loc, - ArrayRef<serialization::SubmoduleID> Overrides); - /// \brief Retrieve the macro with the given ID. MacroInfo *getMacro(serialization::MacroID ID); @@ -2007,10 +1906,18 @@ public: const RecordData &Record,unsigned &Idx); /// \brief Read a CXXCtorInitializer array. - std::pair<CXXCtorInitializer **, unsigned> + CXXCtorInitializer ** ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, unsigned &Idx); + /// \brief Read a CXXCtorInitializers ID from the given record and + /// return its global bit offset. + uint64_t ReadCXXCtorInitializersRef(ModuleFile &M, const RecordData &Record, + unsigned &Idx); + + /// \brief Read the contents of a CXXCtorInitializer array. + CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; + /// \brief Read a source location from raw form. SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, unsigned Raw) const { SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw); @@ -2087,24 +1994,14 @@ public: serialization::PreprocessedEntityID getGlobalPreprocessedEntityID(ModuleFile &M, unsigned LocalID) const; - /// \brief Add a macro to resolve imported from a module. - /// - /// \param II The name of the macro. - /// \param M The module file. - /// \param GMacID The global macro ID that is associated with this identifier. - void addPendingMacroFromModule(IdentifierInfo *II, - ModuleFile *M, - serialization::GlobalMacroID GMacID, - ArrayRef<serialization::SubmoduleID>); - - /// \brief Add a macro to deserialize its macro directive history from a PCH. + /// \brief Add a macro to deserialize its macro directive history. /// /// \param II The name of the macro. /// \param M The module file. /// \param MacroDirectivesOffset Offset of the serialized macro directive /// history. - void addPendingMacroFromPCH(IdentifierInfo *II, - ModuleFile *M, uint64_t MacroDirectivesOffset); + void addPendingMacro(IdentifierInfo *II, ModuleFile *M, + uint64_t MacroDirectivesOffset); /// \brief Read the set of macros defined by this external macro source. void ReadDefinedMacros() override; diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 9907fae..297ee22 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -49,7 +49,7 @@ class FPOptions; class HeaderSearch; class HeaderSearchOptions; class IdentifierResolver; -class MacroDefinition; +class MacroDefinitionRecord; class MacroDirective; class MacroInfo; class OpaqueValueExpr; @@ -61,6 +61,7 @@ class PreprocessingRecord; class Preprocessor; class Sema; class SourceManager; +struct StoredDeclsList; class SwitchCase; class TargetInfo; class Token; @@ -225,7 +226,7 @@ private: /// The ID numbers for identifiers are consecutive (in order of /// discovery), starting at 1. An ID of zero refers to a NULL /// IdentifierInfo. - llvm::DenseMap<const IdentifierInfo *, serialization::IdentID> IdentifierIDs; + llvm::MapVector<const IdentifierInfo *, serialization::IdentID> IdentifierIDs; /// \brief The first ID number we can use for our own macros. serialization::MacroID FirstMacroID; @@ -275,7 +276,7 @@ private: serialization::SelectorID NextSelectorID; /// \brief Map that provides the ID numbers of each Selector. - llvm::DenseMap<Selector, serialization::SelectorID> SelectorIDs; + llvm::MapVector<Selector, serialization::SelectorID> SelectorIDs; /// \brief Offset of each selector within the method pool/selector /// table, indexed by the Selector ID (-1). @@ -283,8 +284,8 @@ private: /// \brief Mapping from macro definitions (as they occur in the preprocessing /// record) to the macro IDs. - llvm::DenseMap<const MacroDefinition *, serialization::PreprocessedEntityID> - MacroDefinitions; + llvm::DenseMap<const MacroDefinitionRecord *, + serialization::PreprocessedEntityID> MacroDefinitions; /// \brief Cache of indices of anonymous declarations within their lexical /// contexts. @@ -299,6 +300,7 @@ private: void *Type; unsigned Loc; unsigned Val; + Module *Mod; }; public: @@ -310,6 +312,8 @@ private: : Kind(Kind), Loc(Loc.getRawEncoding()) {} DeclUpdate(unsigned Kind, unsigned Val) : Kind(Kind), Val(Val) {} + DeclUpdate(unsigned Kind, Module *M) + : Kind(Kind), Mod(M) {} unsigned getKind() const { return Kind; } const Decl *getDecl() const { return Dcl; } @@ -318,10 +322,11 @@ private: return SourceLocation::getFromRawEncoding(Loc); } unsigned getNumber() const { return Val; } + Module *getModule() const { return Mod; } }; typedef SmallVector<DeclUpdate, 1> UpdateRecord; - typedef llvm::DenseMap<const Decl *, UpdateRecord> DeclUpdateMap; + typedef llvm::MapVector<const Decl *, UpdateRecord> DeclUpdateMap; /// \brief Mapping from declarations that came from a chained PCH to the /// record containing modifications to them. DeclUpdateMap DeclUpdates; @@ -351,13 +356,13 @@ private: /// if its primary namespace comes from the chain. If it does, we add the /// primary to this set, so that we can write out lexical content updates for /// it. - llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts; + llvm::SmallSetVector<const DeclContext *, 16> UpdatedDeclContexts; /// \brief Keeps track of visible decls that were added in DeclContexts /// coming from another AST file. SmallVector<const Decl *, 16> UpdatingVisibleDecls; - typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy; + typedef llvm::SmallSetVector<const Decl *, 16> DeclsToRewriteTy; /// \brief Decls that will be replaced in the current dependent AST file. DeclsToRewriteTy DeclsToRewrite; @@ -386,8 +391,7 @@ private: /// \brief The set of declarations that may have redeclaration chains that /// need to be serialized. - llvm::SetVector<Decl *, SmallVector<Decl *, 4>, - llvm::SmallPtrSet<Decl *, 4> > Redeclarations; + llvm::SmallSetVector<Decl *, 4> Redeclarations; /// \brief Statements that we've encountered while serializing a /// declaration or type. @@ -415,7 +419,7 @@ private: unsigned NumVisibleDeclContexts; /// \brief The offset of each CXXBaseSpecifier set within the AST. - SmallVector<uint32_t, 4> CXXBaseSpecifiersOffsets; + SmallVector<uint32_t, 16> CXXBaseSpecifiersOffsets; /// \brief The first ID number we can use for our own base specifiers. serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID; @@ -443,6 +447,33 @@ private: /// in the order they should be written. SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite; + /// \brief The offset of each CXXCtorInitializer list within the AST. + SmallVector<uint32_t, 16> CXXCtorInitializersOffsets; + + /// \brief The first ID number we can use for our own ctor initializers. + serialization::CXXCtorInitializersID FirstCXXCtorInitializersID; + + /// \brief The ctor initializers ID that will be assigned to the next new + /// list of C++ ctor initializers. + serialization::CXXCtorInitializersID NextCXXCtorInitializersID; + + /// \brief A set of C++ ctor initializers that is queued to be written + /// into the AST file. + struct QueuedCXXCtorInitializers { + QueuedCXXCtorInitializers() : ID() {} + + QueuedCXXCtorInitializers(serialization::CXXCtorInitializersID ID, + ArrayRef<CXXCtorInitializer*> Inits) + : ID(ID), Inits(Inits) {} + + serialization::CXXCtorInitializersID ID; + ArrayRef<CXXCtorInitializer*> Inits; + }; + + /// \brief Queue of C++ ctor initializers to be written to the AST file, + /// in the order they should be written. + SmallVector<QueuedCXXCtorInitializers, 2> CXXCtorInitializersToWrite; + /// \brief A mapping from each known submodule to its ID number, which will /// be a positive integer. llvm::DenseMap<Module *, unsigned> SubmoduleIDs; @@ -471,12 +502,16 @@ private: void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, bool isModule); void WriteCXXBaseSpecifiersOffsets(); + void WriteCXXCtorInitializersOffsets(); unsigned TypeExtQualAbbrev; unsigned TypeFunctionProtoAbbrev; void WriteTypeAbbrevs(); void WriteType(QualType T); + bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC); + bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC); + uint32_t GenerateNameLookupTable(const DeclContext *DC, llvm::SmallVectorImpl<char> &LookupTable); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); @@ -496,7 +531,6 @@ private: void WriteOpenCLExtensions(Sema &SemaRef); void WriteObjCCategories(); void WriteRedeclarations(); - void WriteMergedDecls(); void WriteLateParsedTemplates(Sema &SemaRef); void WriteOptimizePragmaOptions(Sema &SemaRef); @@ -529,7 +563,9 @@ public: /// \brief Create a new precompiled header writer that outputs to /// the given bitstream. ASTWriter(llvm::BitstreamWriter &Stream); - ~ASTWriter(); + ~ASTWriter() override; + + const LangOptions &getLangOpts() const; /// \brief Write a precompiled header for the given semantic analysis. /// @@ -602,12 +638,6 @@ public: /// \brief Determine the type ID of an already-emitted type. serialization::TypeID getTypeID(QualType T) const; - /// \brief Force a type to be emitted and get its index. - serialization::TypeIdx GetOrCreateTypeIdx( QualType T); - - /// \brief Determine the type index of an already-emitted type. - serialization::TypeIdx getTypeIdx(QualType T) const; - /// \brief Emits a reference to a declarator info. void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record); @@ -677,6 +707,11 @@ public: void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, RecordDataImpl &Record); + /// \brief Emit the ID for a CXXCtorInitializer array and register the array + /// for later serialization. + void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits, + RecordDataImpl &Record); + /// \brief Emit a CXXCtorInitializer array. void AddCXXCtorInitializers( const CXXCtorInitializer * const *CtorInitializers, @@ -702,9 +737,6 @@ public: /// \brief Add a version tuple to the given record void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record); - /// \brief Mark a declaration context as needing an update. - void AddUpdatedDeclContext(const DeclContext *DC); - void RewriteDecl(const Decl *D) { DeclsToRewrite.insert(D); } @@ -749,6 +781,18 @@ public: /// via \c AddCXXBaseSpecifiersRef(). void FlushCXXBaseSpecifiers(); + /// \brief Flush all of the C++ constructor initializer lists that have been + /// added via \c AddCXXCtorInitializersRef(). + void FlushCXXCtorInitializers(); + + /// \brief Flush all pending records that are tacked onto the end of + /// decl and decl update records. + void FlushPendingAfterDecl() { + FlushStmts(); + FlushCXXBaseSpecifiers(); + FlushCXXCtorInitializers(); + } + /// \brief Record an ID for the given switch-case statement. unsigned RecordSwitchCaseID(SwitchCase *S); @@ -787,7 +831,7 @@ public: void TypeRead(serialization::TypeIdx Idx, QualType T) override; void SelectorRead(serialization::SelectorID ID, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID ID, - MacroDefinition *MD) override; + MacroDefinitionRecord *MD) override; void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override; // ASTMutationListener implementation. @@ -802,6 +846,8 @@ public: const FunctionDecl *D) override; void ResolvedExceptionSpec(const FunctionDecl *FD) override; void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; + void ResolvedOperatorDelete(const CXXDestructorDecl *DD, + const FunctionDecl *Delete) override; void CompletedImplicitDefinition(const FunctionDecl *D) override; void StaticDataMemberInstantiated(const VarDecl *D) override; void FunctionDefinitionInstantiated(const FunctionDecl *D) override; @@ -812,6 +858,7 @@ public: const ObjCCategoryDecl *ClassExt) override; void DeclarationMarkedUsed(const Decl *D) override; void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; + void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; }; /// \brief AST and semantic-analysis consumer that generates a @@ -838,7 +885,7 @@ public: clang::Module *Module, StringRef isysroot, raw_ostream *Out, bool AllowASTWithErrors = false); - ~PCHGenerator(); + ~PCHGenerator() override; void InitializeSema(Sema &S) override { SemaPtr = &S; } void HandleTranslationUnit(ASTContext &Ctx) override; ASTMutationListener *GetASTMutationListener() override; diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h index 5f8ae1f..244b01b 100644 --- a/include/clang/Serialization/ContinuousRangeMap.h +++ b/include/clang/Serialization/ContinuousRangeMap.h @@ -109,8 +109,8 @@ public: class Builder { ContinuousRangeMap &Self; - Builder(const Builder&) LLVM_DELETED_FUNCTION; - Builder &operator=(const Builder&) LLVM_DELETED_FUNCTION; + Builder(const Builder&) = delete; + Builder &operator=(const Builder&) = delete; public: explicit Builder(ContinuousRangeMap &Self) : Self(Self) { } diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h index d8a57be..640c7bb 100644 --- a/include/clang/Serialization/GlobalModuleIndex.h +++ b/include/clang/Serialization/GlobalModuleIndex.h @@ -118,8 +118,8 @@ class GlobalModuleIndex { explicit GlobalModuleIndex(std::unique_ptr<llvm::MemoryBuffer> Buffer, llvm::BitstreamCursor Cursor); - GlobalModuleIndex(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION; - GlobalModuleIndex &operator=(const GlobalModuleIndex &) LLVM_DELETED_FUNCTION; + GlobalModuleIndex(const GlobalModuleIndex &) = delete; + GlobalModuleIndex &operator=(const GlobalModuleIndex &) = delete; public: ~GlobalModuleIndex(); diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index 426cec5..5571d91 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -206,7 +206,7 @@ public: llvm::BitstreamCursor InputFilesCursor; /// \brief Offsets for all of the input file entries in the AST file. - const uint32_t *InputFileOffsets; + const uint64_t *InputFileOffsets; /// \brief The input files that have been loaded from this AST file. std::vector<InputFile> InputFilesLoaded; @@ -404,6 +404,13 @@ public: /// indexed by the C++ base specifier set ID (-1). const uint32_t *CXXBaseSpecifiersOffsets; + /// \brief The number of C++ ctor initializer lists in this AST file. + unsigned LocalNumCXXCtorInitializers; + + /// \brief Offset of each C++ ctor initializer list within the bitstream, + /// indexed by the C++ ctor initializer list ID minus 1. + const uint32_t *CXXCtorInitializersOffsets; + typedef llvm::DenseMap<const DeclContext *, DeclContextInfo> DeclContextInfosMap; diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h index 3d10fad..3de86fe 100644 --- a/include/clang/Serialization/ModuleManager.h +++ b/include/clang/Serialization/ModuleManager.h @@ -32,10 +32,20 @@ class ModuleManager { /// \brief The chain of AST files. The first entry is the one named by the /// user, the last one is the one that doesn't depend on anything further. SmallVector<ModuleFile *, 2> Chain; + + // \brief The roots of the dependency DAG of AST files. This is used + // to implement short-circuiting logic when running DFS over the dependencies. + SmallVector<ModuleFile *, 2> Roots; /// \brief All loaded modules, indexed by name. llvm::DenseMap<const FileEntry *, ModuleFile *> Modules; - + + typedef llvm::SetVector<const FileEntry *> AdditionalKnownModuleFileSet; + + /// \brief Additional module files that are known but not loaded. Tracked + /// here so that we can re-export them if necessary. + AdditionalKnownModuleFileSet AdditionalKnownModuleFiles; + /// \brief FileManager that handles translating between filenames and /// FileEntry *. FileManager &FileMgr; @@ -159,6 +169,8 @@ public: OutOfDate }; + typedef ASTFileSignature(*ASTFileSignatureReader)(llvm::BitstreamReader &); + /// \brief Attempts to create a new module and add it to the list of known /// modules. /// @@ -198,8 +210,7 @@ public: ModuleFile *ImportedBy, unsigned Generation, off_t ExpectedSize, time_t ExpectedModTime, ASTFileSignature ExpectedSignature, - std::function<ASTFileSignature(llvm::BitstreamReader &)> - ReadSignature, + ASTFileSignatureReader ReadSignature, ModuleFile *&Module, std::string &ErrorStr); @@ -219,6 +230,19 @@ public: /// has been "accepted", and will not (can not) be unloaded. void moduleFileAccepted(ModuleFile *MF); + /// \brief Notification from the frontend that the given module file is + /// part of this compilation (even if not imported) and, if this compilation + /// is exported, should be made available to importers of it. + bool addKnownModuleFile(StringRef FileName); + + /// \brief Get a list of additional module files that are not currently + /// loaded but are considered to be part of the current compilation. + llvm::iterator_range<AdditionalKnownModuleFileSet::const_iterator> + getAdditionalKnownModuleFiles() { + return llvm::make_range(AdditionalKnownModuleFiles.begin(), + AdditionalKnownModuleFiles.end()); + } + /// \brief Visit each of the modules. /// /// This routine visits each of the modules, starting with the @@ -244,25 +268,35 @@ public: /// manager that is *not* in this set can be skipped. void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData, llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr); - + + /// \brief Control DFS behavior during preorder visitation. + enum DFSPreorderControl { + Continue, /// Continue visiting all nodes. + Abort, /// Stop the visitation immediately. + SkipImports, /// Do not visit imports of the current node. + }; + /// \brief Visit each of the modules with a depth-first traversal. /// /// This routine visits each of the modules known to the module /// manager using a depth-first search, starting with the first - /// loaded module. The traversal invokes the callback both before - /// traversing the children (preorder traversal) and after - /// traversing the children (postorder traversal). + /// loaded module. The traversal invokes one callback before + /// traversing the imports (preorder traversal) and one after + /// traversing the imports (postorder traversal). /// - /// \param Visitor A visitor function that will be invoked with each - /// module and given a \c Preorder flag that indicates whether we're - /// visiting the module before or after visiting its children. The - /// visitor may return true at any time to abort the depth-first - /// visitation. + /// \param PreorderVisitor A visitor function that will be invoked with each + /// module before visiting its imports. The visitor can control how to + /// continue the visitation through its return value. + /// + /// \param PostorderVisitor A visitor function taht will be invoked with each + /// module after visiting its imports. The visitor may return true at any time + /// to abort the depth-first visitation. /// /// \param UserData User data ssociated with the visitor object, /// which will be passed along to the user. - void visitDepthFirst(bool (*Visitor)(ModuleFile &M, bool Preorder, - void *UserData), + void visitDepthFirst(DFSPreorderControl (*PreorderVisitor)(ModuleFile &M, + void *UserData), + bool (*PostorderVisitor)(ModuleFile &M, void *UserData), void *UserData); /// \brief Attempt to resolve the given module file name to a file entry. diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index fc9fc5e..f02e48a4 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -28,6 +28,10 @@ class DiagnosticsEngine; class Preprocessor; class LangOptions; +namespace ento { +class CheckerBase; +} + /// Analysis - Set of available source code analyses. enum Analyses { #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME, @@ -252,18 +256,102 @@ private: /// \sa getMaxNodesPerTopLevelFunction Optional<unsigned> MaxNodesPerTopLevelFunction; + /// A helper function that retrieves option for a given full-qualified + /// checker name. + /// Options for checkers can be specified via 'analyzer-config' command-line + /// option. + /// Example: + /// @code-analyzer-config unix.Malloc:OptionName=CheckerOptionValue @endcode + /// or @code-analyzer-config unix:OptionName=GroupOptionValue @endcode + /// for groups of checkers. + /// @param [in] CheckerName Full-qualified checker name, like + /// alpha.unix.StreamChecker. + /// @param [in] OptionName Name of the option to get. + /// @param [in] Default Default value if no option is specified. + /// @param [in] SearchInParents If set to true and the searched option was not + /// specified for the given checker the options for the parent packages will + /// be searched as well. The inner packages take precedence over the outer + /// ones. + /// @retval CheckerOptionValue An option for a checker if it was specified. + /// @retval GroupOptionValue An option for group if it was specified and no + /// checker-specific options were found. The closer group to checker, + /// the more priority it has. For example, @c coregroup.subgroup has more + /// priority than @c coregroup for @c coregroup.subgroup.CheckerName checker. + /// @retval Default If nor checker option, nor group option was found. + StringRef getCheckerOption(StringRef CheckerName, StringRef OptionName, + StringRef Default, + bool SearchInParents = false); + public: - /// Interprets an option's string value as a boolean. + /// Interprets an option's string value as a boolean. The "true" string is + /// interpreted as true and the "false" string is interpreted as false. /// - /// Accepts the strings "true" and "false". /// If an option value is not provided, returns the given \p DefaultVal. - bool getBooleanOption(StringRef Name, bool DefaultVal); + /// @param [in] Name Name for option to retrieve. + /// @param [in] DefaultVal Default value returned if no such option was + /// specified. + /// @param [in] C The optional checker parameter that can be used to restrict + /// the search to the options of this particular checker (and its parents + /// dependening on search mode). + /// @param [in] SearchInParents If set to true and the searched option was not + /// specified for the given checker the options for the parent packages will + /// be searched as well. The inner packages take precedence over the outer + /// ones. + bool getBooleanOption(StringRef Name, bool DefaultVal, + const ento::CheckerBase *C = nullptr, + bool SearchInParents = false); /// Variant that accepts a Optional value to cache the result. - bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal); + /// + /// @param [in,out] V Return value storage, returned if parameter contains + /// an existing valid option, else it is used to store a return value + /// @param [in] Name Name for option to retrieve. + /// @param [in] DefaultVal Default value returned if no such option was + /// specified. + /// @param [in] C The optional checker parameter that can be used to restrict + /// the search to the options of this particular checker (and its parents + /// dependening on search mode). + /// @param [in] SearchInParents If set to true and the searched option was not + /// specified for the given checker the options for the parent packages will + /// be searched as well. The inner packages take precedence over the outer + /// ones. + bool getBooleanOption(Optional<bool> &V, StringRef Name, bool DefaultVal, + const ento::CheckerBase *C = nullptr, + bool SearchInParents = false); /// Interprets an option's string value as an integer value. - int getOptionAsInteger(StringRef Name, int DefaultVal); + /// + /// If an option value is not provided, returns the given \p DefaultVal. + /// @param [in] Name Name for option to retrieve. + /// @param [in] DefaultVal Default value returned if no such option was + /// specified. + /// @param [in] C The optional checker parameter that can be used to restrict + /// the search to the options of this particular checker (and its parents + /// dependening on search mode). + /// @param [in] SearchInParents If set to true and the searched option was not + /// specified for the given checker the options for the parent packages will + /// be searched as well. The inner packages take precedence over the outer + /// ones. + int getOptionAsInteger(StringRef Name, int DefaultVal, + const ento::CheckerBase *C = nullptr, + bool SearchInParents = false); + + /// Query an option's string value. + /// + /// If an option value is not provided, returns the given \p DefaultVal. + /// @param [in] Name Name for option to retrieve. + /// @param [in] DefaultVal Default value returned if no such option was + /// specified. + /// @param [in] C The optional checker parameter that can be used to restrict + /// the search to the options of this particular checker (and its parents + /// dependening on search mode). + /// @param [in] SearchInParents If set to true and the searched option was not + /// specified for the given checker the options for the parent packages will + /// be searched as well. The inner packages take precedence over the outer + /// ones. + StringRef getOptionAsString(StringRef Name, StringRef DefaultVal, + const ento::CheckerBase *C = nullptr, + bool SearchInParents = false); /// \brief Retrieves and sets the UserMode. This is a high-level option, /// which is used to set other low-level options. It is not accessible diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index b03371c..308ac83 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -290,7 +290,7 @@ public: } /// \brief Get the SourceRanges associated with the report. - virtual std::pair<ranges_iterator, ranges_iterator> getRanges(); + virtual llvm::iterator_range<ranges_iterator> getRanges(); /// \brief Add custom or predefined bug report visitors to this report. /// @@ -492,7 +492,7 @@ public: GRBugReporter(BugReporterData& d, ExprEngine& eng) : BugReporter(d, GRBugReporterKind), Eng(eng) {} - virtual ~GRBugReporter(); + ~GRBugReporter() override; /// getEngine - Return the analysis engine used to analyze a given /// function or method. diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index b4ab1ea..941d5240 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -70,11 +70,15 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; } }; - struct FilesMade : public llvm::FoldingSet<PDFileEntry> { + class FilesMade { llvm::BumpPtrAllocator Alloc; + llvm::FoldingSet<PDFileEntry> Set; + public: ~FilesMade(); + bool empty() const { return Set.empty(); } + void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName); @@ -352,9 +356,9 @@ private: std::vector<SourceRange> ranges; - PathDiagnosticPiece() LLVM_DELETED_FUNCTION; - PathDiagnosticPiece(const PathDiagnosticPiece &P) LLVM_DELETED_FUNCTION; - void operator=(const PathDiagnosticPiece &P) LLVM_DELETED_FUNCTION; + PathDiagnosticPiece() = delete; + PathDiagnosticPiece(const PathDiagnosticPiece &P) = delete; + void operator=(const PathDiagnosticPiece &P) = delete; protected: PathDiagnosticPiece(StringRef s, Kind k, DisplayHint hint = Below); @@ -362,7 +366,7 @@ protected: PathDiagnosticPiece(Kind k, DisplayHint hint = Below); public: - virtual ~PathDiagnosticPiece(); + ~PathDiagnosticPiece() override; StringRef getString() const { return str; } @@ -478,7 +482,7 @@ private: public: StackHintGeneratorForSymbol(SymbolRef S, StringRef M) : Sym(S), Msg(M) {} - virtual ~StackHintGeneratorForSymbol() {} + ~StackHintGeneratorForSymbol() override {} /// \brief Search the call expression for the symbol Sym and dispatch the /// 'getMessageForX()' methods to construct a specific message. @@ -511,7 +515,7 @@ public: : PathDiagnosticSpotPiece(pos, s, Event, addPosRange), CallStackHint(stackHint) {} - ~PathDiagnosticEventPiece(); + ~PathDiagnosticEventPiece() override; /// Mark the diagnostic piece as being potentially prunable. This /// flag may have been previously set, at which point it will not @@ -570,9 +574,9 @@ public: PathDiagnosticLocation callEnterWithin; PathDiagnosticLocation callReturn; PathPieces path; - - virtual ~PathDiagnosticCallPiece(); - + + ~PathDiagnosticCallPiece() override; + const Decl *getCaller() const { return Caller; } const Decl *getCallee() const { return Callee; } @@ -631,7 +635,7 @@ public: LPairs.push_back(PathDiagnosticLocationPair(startPos, endPos)); } - ~PathDiagnosticControlFlowPiece(); + ~PathDiagnosticControlFlowPiece() override; PathDiagnosticLocation getStartLocation() const { assert(!LPairs.empty() && @@ -686,7 +690,7 @@ public: PathDiagnosticMacroPiece(const PathDiagnosticLocation &pos) : PathDiagnosticSpotPiece(pos, "", Macro) {} - ~PathDiagnosticMacroPiece(); + ~PathDiagnosticMacroPiece() override; PathPieces subPieces; @@ -730,7 +734,7 @@ class PathDiagnostic : public llvm::FoldingSetNode { PathDiagnosticLocation UniqueingLoc; const Decl *UniqueingDecl; - PathDiagnostic() LLVM_DELETED_FUNCTION; + PathDiagnostic() = delete; public: PathDiagnostic(StringRef CheckName, const Decl *DeclWithIssue, StringRef bugtype, StringRef verboseDesc, StringRef shortDesc, diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 8cc3514..099d763 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -25,10 +25,6 @@ namespace ento { namespace check { -struct _VoidCheck { - static void _register(void *checker, CheckerManager &mgr) { } -}; - template <typename DECL> class ASTDecl { template <typename CHECKER> @@ -476,49 +472,22 @@ public: CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg); }; -template <typename CHECK1, typename CHECK2=check::_VoidCheck, - typename CHECK3=check::_VoidCheck, typename CHECK4=check::_VoidCheck, - typename CHECK5=check::_VoidCheck, typename CHECK6=check::_VoidCheck, - typename CHECK7=check::_VoidCheck, typename CHECK8=check::_VoidCheck, - typename CHECK9=check::_VoidCheck, typename CHECK10=check::_VoidCheck, - typename CHECK11=check::_VoidCheck,typename CHECK12=check::_VoidCheck, - typename CHECK13=check::_VoidCheck,typename CHECK14=check::_VoidCheck, - typename CHECK15=check::_VoidCheck,typename CHECK16=check::_VoidCheck, - typename CHECK17=check::_VoidCheck,typename CHECK18=check::_VoidCheck, - typename CHECK19=check::_VoidCheck,typename CHECK20=check::_VoidCheck, - typename CHECK21=check::_VoidCheck,typename CHECK22=check::_VoidCheck, - typename CHECK23=check::_VoidCheck,typename CHECK24=check::_VoidCheck> -class Checker; - -template <> -class Checker<check::_VoidCheck> - : public CheckerBase -{ - virtual void anchor(); +template <typename CHECK1, typename... CHECKs> +class Checker : public CHECK1, public CHECKs..., public CheckerBase { public: - static void _register(void *checker, CheckerManager &mgr) { } + template <typename CHECKER> + static void _register(CHECKER *checker, CheckerManager &mgr) { + CHECK1::_register(checker, mgr); + Checker<CHECKs...>::_register(checker, mgr); + } }; -template <typename CHECK1, typename CHECK2, typename CHECK3, typename CHECK4, - typename CHECK5, typename CHECK6, typename CHECK7, typename CHECK8, - typename CHECK9, typename CHECK10,typename CHECK11,typename CHECK12, - typename CHECK13,typename CHECK14,typename CHECK15,typename CHECK16, - typename CHECK17,typename CHECK18,typename CHECK19,typename CHECK20, - typename CHECK21,typename CHECK22,typename CHECK23,typename CHECK24> -class Checker - : public CHECK1, - public Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, - CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13, - CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19, - CHECK20,CHECK21,CHECK22,CHECK23,CHECK24> { +template <typename CHECK1> +class Checker<CHECK1> : public CHECK1, public CheckerBase { public: template <typename CHECKER> static void _register(CHECKER *checker, CheckerManager &mgr) { CHECK1::_register(checker, mgr); - Checker<CHECK2, CHECK3, CHECK4, CHECK5, CHECK6, CHECK7, - CHECK8, CHECK9, CHECK10,CHECK11,CHECK12,CHECK13, - CHECK14,CHECK15,CHECK16,CHECK17,CHECK18,CHECK19, - CHECK20,CHECK21,CHECK22,CHECK23,CHECK24>::_register(checker, mgr); } }; diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 30b0480..8a1a82b 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -47,71 +47,18 @@ namespace ento { template <typename T> class CheckerFn; -template <typename RET, typename P1, typename P2, typename P3, typename P4, - typename P5> -class CheckerFn<RET(P1, P2, P3, P4, P5)> { - typedef RET (*Func)(void *, P1, P2, P3, P4, P5); +template <typename RET, typename... Ps> +class CheckerFn<RET(Ps...)> { + typedef RET (*Func)(void *, Ps...); Func Fn; public: CheckerBase *Checker; CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } - RET operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { - return Fn(Checker, p1, p2, p3, p4, p5); + RET operator()(Ps... ps) const { + return Fn(Checker, ps...); } }; -template <typename RET, typename P1, typename P2, typename P3, typename P4> -class CheckerFn<RET(P1, P2, P3, P4)> { - typedef RET (*Func)(void *, P1, P2, P3, P4); - Func Fn; -public: - CheckerBase *Checker; - CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } - RET operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { - return Fn(Checker, p1, p2, p3, p4); - } -}; - -template <typename RET, typename P1, typename P2, typename P3> -class CheckerFn<RET(P1, P2, P3)> { - typedef RET (*Func)(void *, P1, P2, P3); - Func Fn; -public: - CheckerBase *Checker; - CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } - RET operator()(P1 p1, P2 p2, P3 p3) const { return Fn(Checker, p1, p2, p3); } -}; - -template <typename RET, typename P1, typename P2> -class CheckerFn<RET(P1, P2)> { - typedef RET (*Func)(void *, P1, P2); - Func Fn; -public: - CheckerBase *Checker; - CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } - RET operator()(P1 p1, P2 p2) const { return Fn(Checker, p1, p2); } -}; - -template <typename RET, typename P1> -class CheckerFn<RET(P1)> { - typedef RET (*Func)(void *, P1); - Func Fn; -public: - CheckerBase *Checker; - CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } - RET operator()(P1 p1) const { return Fn(Checker, p1); } -}; - -template <typename RET> -class CheckerFn<RET()> { - typedef RET (*Func)(void *); - Func Fn; -public: - CheckerBase *Checker; - CheckerFn(CheckerBase *checker, Func fn) : Fn(fn), Checker(checker) { } - RET operator()() const { return Fn(Checker); } -}; - /// \brief Describes the different reasons a pointer escapes /// during analysis. enum PointerEscapeKind { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index dbc59cf..3e0913e 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -55,8 +55,8 @@ public: AnalyzerOptions &Options, CodeInjector* injector = nullptr); - ~AnalysisManager(); - + ~AnalysisManager() override; + void ClearContexts() { AnaCtxMgr.clear(); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index 00deaa6..63b8631 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -119,7 +119,7 @@ private: const LocationContext *LCtx; llvm::PointerUnion<const Expr *, const Decl *> Origin; - void operator=(const CallEvent &) LLVM_DELETED_FUNCTION; + void operator=(const CallEvent &) = delete; protected: // This is user data for subclasses. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 0dafd5f..d5822e2 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -103,8 +103,8 @@ private: ExplodedNode *Pred); private: - CoreEngine(const CoreEngine &) LLVM_DELETED_FUNCTION; - void operator=(const CoreEngine &) LLVM_DELETED_FUNCTION; + CoreEngine(const CoreEngine &) = delete; + void operator=(const CoreEngine &) = delete; ExplodedNode *generateCallExitBeginNode(ExplodedNode *N); @@ -367,7 +367,7 @@ public: EnclosingBldr->takeNodes(*I); } - virtual ~StmtNodeBuilder(); + ~StmtNodeBuilder() override; using NodeBuilder::generateNode; using NodeBuilder::generateSink; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index ba9715b..cc3779d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -106,7 +106,6 @@ private: public: EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} - ~EnvironmentManager() {} Environment getInitialEnvironment() { return Environment(F.getEmptyMap()); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index c4eabb8..cfb1b92 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -127,8 +127,6 @@ public: : Location(loc), State(state), Succs(IsSink) { assert(isSink() == IsSink); } - - ~ExplodedNode() {} /// getLocation - Returns the edge associated with the given node. ProgramPoint getLocation() const { return Location; } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 247bf0c..d8f1c34 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -102,7 +102,7 @@ public: FunctionSummariesTy *FS, InliningModes HowToInlineIn); - ~ExprEngine(); + ~ExprEngine() override; /// Returns true if there is still simulation state on the worklist. bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 1be7a26..4f07129 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -609,7 +609,7 @@ public: AnalysisDeclContext *getAnalysisDeclContext() const { return AC; } - virtual void dumpToStream(raw_ostream &os) const override; + void dumpToStream(raw_ostream &os) const override; void Profile(llvm::FoldingSetNodeID& ID) const override; @@ -704,7 +704,7 @@ private: }; /// SymbolicRegion - A special, "non-concrete" region. Unlike other region -/// clases, SymbolicRegion represents a region that serves as an alias for +/// classes, SymbolicRegion represents a region that serves as an alias for /// either a real region, a NULL pointer, etc. It essentially is used to /// map the concept of symbolic values into the domain of regions. Symbolic /// regions do not need to be typed. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index e819b88..ac4e452 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -76,7 +76,7 @@ public: typedef llvm::ImmutableMap<void*, void*> GenericDataMap; private: - void operator=(const ProgramState& R) LLVM_DELETED_FUNCTION; + void operator=(const ProgramState& R) = delete; friend class ProgramStateManager; friend class ExplodedGraph; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index ef43fe0..642e11a 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -203,8 +203,8 @@ class DefinedOrUnknownSVal : public SVal { private: // We want calling these methods to be a compiler error since they are // tautologically false. - bool isUndef() const LLVM_DELETED_FUNCTION; - bool isValid() const LLVM_DELETED_FUNCTION; + bool isUndef() const = delete; + bool isValid() const = delete; protected: DefinedOrUnknownSVal() {} @@ -236,9 +236,9 @@ class DefinedSVal : public DefinedOrUnknownSVal { private: // We want calling these methods to be a compiler error since they are // tautologically true/false. - bool isUnknown() const LLVM_DELETED_FUNCTION; - bool isUnknownOrUndef() const LLVM_DELETED_FUNCTION; - bool isValid() const LLVM_DELETED_FUNCTION; + bool isUnknown() const = delete; + bool isUnknownOrUndef() const = delete; + bool isValid() const = delete; protected: DefinedSVal() {} explicit DefinedSVal(const void *d, bool isLoc, unsigned ValKind) diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index 5500c3c..a03b630 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -225,7 +225,7 @@ public: bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R, SVal val) override; - LLVM_EXPLICIT operator bool() { return First && Binding; } + explicit operator bool() { return First && Binding; } const MemRegion *getRegion() { return Binding; } }; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index fbeaae4..1ca96a2 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -109,7 +109,7 @@ protected: SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} public: - virtual ~SymbolData() {} + ~SymbolData() override {} SymbolID getSymbolID() const { return Sym; } @@ -589,8 +589,6 @@ public: : LCtx(Ctx), Loc(s), SymMgr(symmgr), reapedStore(nullptr, storeMgr) {} - ~SymbolReaper() {} - const LocationContext *getLocationContext() const { return LCtx; } bool isLive(SymbolRef sym); diff --git a/include/clang/Tooling/CompilationDatabase.h b/include/clang/Tooling/CompilationDatabase.h index 27c1652..e5b95af 100644 --- a/include/clang/Tooling/CompilationDatabase.h +++ b/include/clang/Tooling/CompilationDatabase.h @@ -178,7 +178,7 @@ public: /// \param Argv Points to the command line arguments. /// \param Directory The base directory used in the FixedCompilationDatabase. static FixedCompilationDatabase *loadFromCommandLine(int &Argc, - const char **Argv, + const char *const *Argv, Twine Directory = "."); /// \brief Constructs a compilation data base from a specified directory diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h index 393cc1d..ca187b1 100644 --- a/include/clang/Tooling/Tooling.h +++ b/include/clang/Tooling/Tooling.h @@ -40,6 +40,7 @@ #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" +#include "llvm/Option/Option.h" #include <memory> #include <string> #include <vector> @@ -78,7 +79,7 @@ public: /// process each translation unit. class FrontendActionFactory : public ToolAction { public: - virtual ~FrontendActionFactory(); + ~FrontendActionFactory() override; /// \brief Invokes the compiler with a FrontendAction created by create(). bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files, @@ -383,6 +384,11 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory( /// \param File Either an absolute or relative path. std::string getAbsolutePath(StringRef File); +/// \brief Creates a \c CompilerInvocation. +clang::CompilerInvocation *newInvocation( + clang::DiagnosticsEngine *Diagnostics, + const llvm::opt::ArgStringList &CC1Args); + } // end namespace tooling } // end namespace clang diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap index 5058d15..6b77adb 100644 --- a/include/clang/module.modulemap +++ b/include/clang/module.modulemap @@ -2,8 +2,7 @@ module Clang_Analysis { requires cplusplus umbrella "Analysis" - // This file is intended for repeated textual inclusion. - exclude header "Analysis/Analyses/ThreadSafetyOps.def" + textual header "Analysis/Analyses/ThreadSafetyOps.def" module * { export * } } @@ -12,10 +11,9 @@ module Clang_AST { requires cplusplus umbrella "AST" - // These files are intended for repeated textual inclusion. - exclude header "AST/BuiltinTypes.def" - exclude header "AST/TypeLocNodes.def" - exclude header "AST/TypeNodes.def" + textual header "AST/BuiltinTypes.def" + textual header "AST/TypeLocNodes.def" + textual header "AST/TypeNodes.def" module * { export * } } @@ -26,33 +24,26 @@ module Clang_Basic { requires cplusplus umbrella "Basic" - // These files are intended for repeated textual inclusion. - exclude header "Basic/BuiltinsAArch64.def" - exclude header "Basic/BuiltinsARM64.def" - exclude header "Basic/BuiltinsARM.def" - exclude header "Basic/Builtins.def" - exclude header "Basic/BuiltinsHexagon.def" - exclude header "Basic/BuiltinsMips.def" - exclude header "Basic/BuiltinsNEON.def" - exclude header "Basic/BuiltinsNVPTX.def" - exclude header "Basic/BuiltinsPPC.def" - exclude header "Basic/BuiltinsR600.def" - exclude header "Basic/BuiltinsX86.def" - exclude header "Basic/BuiltinsXCore.def" - exclude header "Basic/BuiltinsLe64.def" - exclude header "Basic/DiagnosticOptions.def" - exclude header "Basic/LangOptions.def" - exclude header "Basic/OpenCLExtensions.def" - exclude header "Basic/OpenMPKinds.def" - exclude header "Basic/OperatorKinds.def" - exclude header "Basic/Sanitizers.def" - exclude header "Basic/TokenKinds.def" - - // This file includes a header from Lex. - exclude header "Basic/PlistSupport.h" - - // FIXME: This is logically a part of Basic, but has been put in the wrong place. - header "StaticAnalyzer/Core/AnalyzerOptions.h" + textual header "Basic/BuiltinsAArch64.def" + textual header "Basic/BuiltinsARM.def" + textual header "Basic/Builtins.def" + textual header "Basic/BuiltinsHexagon.def" + textual header "Basic/BuiltinsLe64.def" + textual header "Basic/BuiltinsMips.def" + textual header "Basic/BuiltinsNEON.def" + textual header "Basic/BuiltinsNVPTX.def" + textual header "Basic/BuiltinsPPC.def" + textual header "Basic/BuiltinsR600.def" + textual header "Basic/BuiltinsSystemZ.def" + textual header "Basic/BuiltinsX86.def" + textual header "Basic/BuiltinsXCore.def" + textual header "Basic/DiagnosticOptions.def" + textual header "Basic/LangOptions.def" + textual header "Basic/OpenCLExtensions.def" + textual header "Basic/OpenMPKinds.def" + textual header "Basic/OperatorKinds.def" + textual header "Basic/Sanitizers.def" + textual header "Basic/TokenKinds.def" module * { export * } } @@ -82,8 +73,7 @@ module Clang_Driver { requires cplusplus umbrella "Driver" - // This file is intended for repeated textual inclusion. - exclude header "Driver/Types.def" + textual header "Driver/Types.def" module * { export * } } @@ -95,9 +85,8 @@ module Clang_Frontend { requires cplusplus umbrella "Frontend" - // These files are intended for repeated textual inclusion. - exclude header "Frontend/CodeGenOptions.def" - exclude header "Frontend/LangStandards.def" + textual header "Frontend/CodeGenOptions.def" + textual header "Frontend/LangStandards.def" module * { export * } } @@ -110,14 +99,32 @@ module Clang_Rewrite { requires cplusplus umbrella "Rewrite" module * { export * module Clang_Sema { requires cplusplus umbrella "Sema" module * { export * } } module Clang_Serialization { requires cplusplus umbrella "Serialization" module * { export * } } -module Clang_StaticAnalyzer { +module Clang_StaticAnalyzer_Core { requires cplusplus - umbrella "StaticAnalyzer" + umbrella "StaticAnalyzer/Core" - // This file is intended for repeated textual inclusion. - exclude header "StaticAnalyzer/Core/Analyses.def" + textual header "StaticAnalyzer/Core/Analyses.def" module * { export * } } -module Clang_Tooling { requires cplusplus umbrella "Tooling" module * { export * } } +module Clang_StaticAnalyzer_Checkers { + requires cplusplus + umbrella "StaticAnalyzer/Checkers" + module * { export * } +} + +module Clang_StaticAnalyzer_Frontend { + requires cplusplus + umbrella "StaticAnalyzer/Frontend" + module * { export * } +} + +module Clang_Tooling { + requires cplusplus umbrella "Tooling" module * { export * } + // FIXME: Exclude this header to avoid pulling all of the AST matchers + // library into clang-format. Due to inline key functions in the headers, + // importing the AST matchers library gives a link dependency on the AST + // matchers (and thus the AST), which clang-format should not have. + exclude header "Tooling/RefactoringCallbacks.h" +} |