diff options
Diffstat (limited to 'include/clang/AST')
43 files changed, 1521 insertions, 709 deletions
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index 736a10bec9b4..b2730e462228 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 195d748b5be8..049221ad9144 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 a335f980e6c5..ee48955ca636 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 48eb6292772c..4f3acc3a75c1 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 84b0842492ad..9078a0e80299 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 787843e64f56..4e282d68b748 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 39ee81f1201c..a0c803096af8 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 37f6748ace90..f7612f21f216 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 aa3c84682983..b25800bfedb9 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 ec6d83c03021..289f2fd345af 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 d995df921282..f190b932c0a0 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 2c444f0dc3a6..42bf4c989a23 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 4ae6fe0c613d..9b05d397baf8 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 c0526e1cfd45..971841e8fb5d 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 a39888f9e1f0..451f9da1b60a 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 984ab13df426..5c382b0d5780 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 027b41e27da3..f7cb4624cb55 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 9068c00a799c..ff37758c2551 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 55d4b0f16953..4a5b4f3d0756 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 9283d2dc4350..90cfb2049173 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 49e51e09b830..ec0fb0b9715e 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 c410f2358bc7..a3be7d06c4b1 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 176817823ea9..1dbf5743c124 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 ff1d180ee8c6..9a7608076214 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 a7468a0fd53f..ddefa88a6b69 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 cbe08a1a765e..c5a7ea16a7ec 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 33fcce2109aa..fc994c1fbd9f 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 518f1232fe8f..4da17b0c0779 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 0c3002c103e2..c8ecef8ce50c 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 7b7799884a3d..667f23520eb7 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 a1d36180d737..95e0df3066b0 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 7aa11d403437..92046d582bf3 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 eb6836f88699..ce9449dc46f6 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 837dc45d1224..567a77288430 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 6ffe74f2d7fb..ec7329a4a013 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 d0527e2d8b61..68fe3ef697bc 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 aed7691cf73a..5161eff0993b 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 80b68bc0569b..1d01753c10fe 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 1bda01fee8ad..8cd29b7b917e 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 4f3c811ce275..e29fa4903282 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 3b2665bb88e0..2549f0bf50c5 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 a11f22d201b7..26ee1cf71c81 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 4e24bdd73041..ebfbb8ad04ab 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); |