diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-12-18 20:11:37 +0000 |
commit | 461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch) | |
tree | 6942083d7d56bba40ec790a453ca58ad3baf6832 /include | |
parent | 75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff) | |
download | src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.tar.gz src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.zip |
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes:
svn path=/vendor/clang/dist/; revision=326941
svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'include')
252 files changed, 15281 insertions, 7202 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 3b5ea9fa539b..587008a7210b 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 43 +#define CINDEX_VERSION_MINOR 45 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -334,6 +334,16 @@ CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options); CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex); /** + * \brief Sets the invocation emission path option in a CXIndex. + * + * The invocation emission path specifies a path which will contain log + * files for certain libclang invocations. A null value (default) implies that + * libclang invocations are not logged.. + */ +CINDEX_LINKAGE void +clang_CXIndex_setInvocationEmissionPathOption(CXIndex, const char *Path); + +/** * \defgroup CINDEX_FILES File manipulation routines * * @{ @@ -394,6 +404,21 @@ CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu, const char *file_name); /** + * \brief Retrieve the buffer associated with the given file. + * + * \param tu the translation unit + * + * \param file the file for which to retrieve the buffer. + * + * \param size [out] if non-NULL, will be set to the size of the buffer. + * + * \returns a pointer to the buffer in memory that holds the contents of + * \p file, or a NULL pointer when the file is not loaded. + */ +CINDEX_LINKAGE const char *clang_getFileContents(CXTranslationUnit tu, + CXFile file, size_t *size); + +/** * \brief Returns non-zero if the \c file1 and \c file2 point to the same file, * or they are both NULL. */ @@ -2837,6 +2862,22 @@ enum CXLanguageKind { CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); /** + * \brief Describe the "thread-local storage (TLS) kind" of the declaration + * referred to by a cursor. + */ +enum CXTLSKind { + CXTLS_None = 0, + CXTLS_Dynamic, + CXTLS_Static +}; + +/** + * \brief Determine the "thread-local storage (TLS) kind" of the declaration + * referred to by a cursor. + */ +CINDEX_LINKAGE enum CXTLSKind clang_getCursorTLSKind(CXCursor cursor); + +/** * \brief Returns the translation unit that a cursor originated from. */ CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor); @@ -3115,8 +3156,9 @@ enum CXTypeKind { CXType_ObjCSel = 29, CXType_Float128 = 30, CXType_Half = 31, + CXType_Float16 = 32, CXType_FirstBuiltin = CXType_Void, - CXType_LastBuiltin = CXType_Half, + CXType_LastBuiltin = CXType_Float16, CXType_Complex = 100, CXType_Pointer = 101, @@ -4276,6 +4318,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor); CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor); /** + * \brief Retrieve the CXStrings representing the mangled symbols of the ObjC + * class interface or implementation at the cursor. + */ +CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor); + +/** * @} */ @@ -4419,6 +4467,12 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C); CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C); /** + * \brief Determine if a C++ record is abstract, i.e. whether a class or struct + * has a pure virtual member function. + */ +CINDEX_LINKAGE unsigned clang_CXXRecord_isAbstract(CXCursor C); + +/** * \brief Determine if an enum declaration refers to a scoped enum. */ CINDEX_LINKAGE unsigned clang_EnumDecl_isScoped(CXCursor C); diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 703f588c5663..a5d080035df0 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1,4 +1,4 @@ -//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===// +//===- ASTContext.h - Context to hold long-lived AST nodes ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,10 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the clang::ASTContext interface. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_ASTCONTEXT_H @@ -19,8 +19,8 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/Decl.h" -#include "clang/AST/DeclarationName.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" @@ -30,32 +30,32 @@ #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/Linkage.h" -#include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SanitizerBlacklist.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/XRayLists.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" -#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/TinyPtrVector.h" +#include "llvm/ADT/Triple.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" @@ -65,7 +65,6 @@ #include <cstdint> #include <iterator> #include <memory> -#include <new> #include <string> #include <type_traits> #include <utility> @@ -75,50 +74,72 @@ namespace llvm { struct fltSemantics; -} // end namespace llvm +} // namespace llvm namespace clang { +class APValue; class ASTMutationListener; class ASTRecordLayout; class AtomicExpr; class BlockExpr; +class BuiltinTemplateDecl; class CharUnits; class CXXABI; +class CXXConstructorDecl; +class CXXMethodDecl; +class CXXRecordDecl; class DiagnosticsEngine; class Expr; +class MangleContext; class MangleNumberingContext; class MaterializeTemporaryExpr; -class TargetInfo; -// Decls -class MangleContext; +class MemberSpecializationInfo; +class Module; +class ObjCCategoryDecl; +class ObjCCategoryImplDecl; +class ObjCContainerDecl; +class ObjCImplDecl; +class ObjCImplementationDecl; +class ObjCInterfaceDecl; class ObjCIvarDecl; +class ObjCMethodDecl; class ObjCPropertyDecl; +class ObjCPropertyImplDecl; +class ObjCProtocolDecl; +class ObjCTypeParamDecl; +class Preprocessor; +class Stmt; +class StoredDeclsMap; +class TemplateDecl; +class TemplateParameterList; +class TemplateTemplateParmDecl; +class TemplateTypeParmDecl; class UnresolvedSetIterator; -class UsingDecl; class UsingShadowDecl; +class VarTemplateDecl; class VTableContextBase; namespace Builtin { - class Context; +class Context; -} // end namespace Builtin +} // namespace Builtin enum BuiltinTemplateKind : int; namespace comments { - class FullComment; +class FullComment; -} // end namespace comments +} // namespace comments struct TypeInfo { - uint64_t Width; - unsigned Align; + uint64_t Width = 0; + unsigned Align = 0; bool AlignIsRequired : 1; - TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {} + TypeInfo() : AlignIsRequired(false) {} TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired) : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {} }; @@ -126,7 +147,7 @@ struct TypeInfo { /// \brief Holds long-lived AST nodes (such as types and decls) that can be /// referred to throughout the semantic analysis of a file. class ASTContext : public RefCountedBase<ASTContext> { - ASTContext &this_() { return *this; } + friend class NestedNameSpecifier; mutable SmallVector<Type *, 0> Types; mutable llvm::FoldingSet<ExtQuals> ExtQualNodes; @@ -143,6 +164,8 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable llvm::FoldingSet<DependentSizedArrayType> DependentSizedArrayTypes; mutable llvm::FoldingSet<DependentSizedExtVectorType> DependentSizedExtVectorTypes; + mutable llvm::FoldingSet<DependentAddressSpaceType> + DependentAddressSpaceTypes; mutable llvm::FoldingSet<VectorType> VectorTypes; mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes; mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&> @@ -187,8 +210,7 @@ class ASTContext : public RefCountedBase<ASTContext> { /// /// This set is managed by the NestedNameSpecifier class. mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers; - mutable NestedNameSpecifier *GlobalNestedNameSpecifier; - friend class NestedNameSpecifier; + mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr; /// \brief A cache mapping from RecordDecls to ASTRecordLayouts. /// @@ -199,7 +221,7 @@ class ASTContext : public RefCountedBase<ASTContext> { ObjCLayouts; /// \brief A cache from types to size and alignment information. - typedef llvm::DenseMap<const Type *, struct TypeInfo> TypeInfoMap; + using TypeInfoMap = llvm::DenseMap<const Type *, struct TypeInfo>; mutable TypeInfoMap MemoizedTypeInfo; /// \brief A cache mapping from CXXRecordDecls to key functions. @@ -233,7 +255,7 @@ class ASTContext : public RefCountedBase<ASTContext> { public: CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm) - : Parm(Parm) { } + : Parm(Parm) {} TemplateTemplateParmDecl *getParam() const { return Parm; } @@ -249,32 +271,32 @@ class ASTContext : public RefCountedBase<ASTContext> { getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; /// \brief The typedef for the __int128_t type. - mutable TypedefDecl *Int128Decl; + mutable TypedefDecl *Int128Decl = nullptr; /// \brief The typedef for the __uint128_t type. - mutable TypedefDecl *UInt128Decl; + mutable TypedefDecl *UInt128Decl = nullptr; /// \brief The typedef for the target specific predefined /// __builtin_va_list type. - mutable TypedefDecl *BuiltinVaListDecl; + mutable TypedefDecl *BuiltinVaListDecl = nullptr; /// The typedef for the predefined \c __builtin_ms_va_list type. - mutable TypedefDecl *BuiltinMSVaListDecl; + mutable TypedefDecl *BuiltinMSVaListDecl = nullptr; /// \brief The typedef for the predefined \c id type. - mutable TypedefDecl *ObjCIdDecl; + mutable TypedefDecl *ObjCIdDecl = nullptr; /// \brief The typedef for the predefined \c SEL type. - mutable TypedefDecl *ObjCSelDecl; + mutable TypedefDecl *ObjCSelDecl = nullptr; /// \brief The typedef for the predefined \c Class type. - mutable TypedefDecl *ObjCClassDecl; + mutable TypedefDecl *ObjCClassDecl = nullptr; /// \brief The typedef for the predefined \c Protocol class in Objective-C. - mutable ObjCInterfaceDecl *ObjCProtocolClassDecl; + mutable ObjCInterfaceDecl *ObjCProtocolClassDecl = nullptr; /// \brief The typedef for the predefined 'BOOL' type. - mutable TypedefDecl *BOOLDecl; + mutable TypedefDecl *BOOLDecl = nullptr; // Typedefs which may be provided defining the structure of Objective-C // pseudo-builtins @@ -298,42 +320,42 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable IdentifierInfo *TypePackElementName = nullptr; QualType ObjCConstantStringType; - mutable RecordDecl *CFConstantStringTagDecl; - mutable TypedefDecl *CFConstantStringTypeDecl; + mutable RecordDecl *CFConstantStringTagDecl = nullptr; + mutable TypedefDecl *CFConstantStringTypeDecl = nullptr; mutable QualType ObjCSuperType; QualType ObjCNSStringType; /// \brief The typedef declaration for the Objective-C "instancetype" type. - TypedefDecl *ObjCInstanceTypeDecl; + TypedefDecl *ObjCInstanceTypeDecl = nullptr; /// \brief The type for the C FILE type. - TypeDecl *FILEDecl; + TypeDecl *FILEDecl = nullptr; /// \brief The type for the C jmp_buf type. - TypeDecl *jmp_bufDecl; + TypeDecl *jmp_bufDecl = nullptr; /// \brief The type for the C sigjmp_buf type. - TypeDecl *sigjmp_bufDecl; + TypeDecl *sigjmp_bufDecl = nullptr; /// \brief The type for the C ucontext_t type. - TypeDecl *ucontext_tDecl; + TypeDecl *ucontext_tDecl = nullptr; /// \brief Type for the Block descriptor for Blocks CodeGen. /// /// Since this is only used for generation of debug info, it is not /// serialized. - mutable RecordDecl *BlockDescriptorType; + mutable RecordDecl *BlockDescriptorType = nullptr; /// \brief Type for the Block descriptor for Blocks CodeGen. /// /// Since this is only used for generation of debug info, it is not /// serialized. - mutable RecordDecl *BlockDescriptorExtendedType; + mutable RecordDecl *BlockDescriptorExtendedType = nullptr; /// \brief Declaration for the CUDA cudaConfigureCall function. - FunctionDecl *cudaConfigureCallDecl; + FunctionDecl *cudaConfigureCallDecl = nullptr; /// \brief Keeps track of all declaration attributes. /// @@ -363,12 +385,19 @@ class ASTContext : public RefCountedBase<ASTContext> { }; llvm::DenseMap<Module*, PerModuleInitializers*> ModuleInitializers; + ASTContext &this_() { return *this; } + public: /// \brief A type synonym for the TemplateOrInstantiation mapping. - typedef llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *> - TemplateOrSpecializationInfo; + using TemplateOrSpecializationInfo = + llvm::PointerUnion<VarTemplateDecl *, MemberSpecializationInfo *>; private: + friend class ASTDeclReader; + friend class ASTReader; + friend class ASTWriter; + friend class CXXRecordDecl; + /// \brief A mapping to contain the template or declaration that /// a variable declaration describes or was instantiated from, /// respectively. @@ -438,7 +467,7 @@ private: /// Since most C++ member functions aren't virtual and therefore /// don't override anything, we store the overridden functions in /// this map on the side rather than within the CXXMethodDecl structure. - typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector; + using CXXMethodVector = llvm::TinyPtrVector<const CXXMethodDecl *>; llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods; /// \brief Mapping from each declaration context to its corresponding @@ -454,18 +483,18 @@ private: /// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. - typedef llvm::DenseMap<const VarDecl *, unsigned> ParameterIndexTable; + using ParameterIndexTable = llvm::DenseMap<const VarDecl *, unsigned>; ParameterIndexTable ParamIndices; - ImportDecl *FirstLocalImport; - ImportDecl *LastLocalImport; + ImportDecl *FirstLocalImport = nullptr; + ImportDecl *LastLocalImport = nullptr; TranslationUnitDecl *TUDecl; - mutable ExternCContextDecl *ExternCContext; - mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; - mutable BuiltinTemplateDecl *TypePackElementDecl; + mutable ExternCContextDecl *ExternCContext = nullptr; + mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr; + mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr; - /// \brief The associated SourceManager object.a + /// \brief The associated SourceManager object. SourceManager &SourceMgr; /// \brief The language options used to create the AST associated with @@ -494,19 +523,14 @@ private: CXXABI *createCXXABI(const TargetInfo &T); /// \brief The logical -> physical address space map. - const LangAS::Map *AddrSpaceMap; + const LangASMap *AddrSpaceMap = nullptr; /// \brief Address space map mangling must be used with language specific /// address spaces (e.g. OpenCL/CUDA) bool AddrSpaceMapMangling; - friend class ASTDeclReader; - friend class ASTReader; - friend class ASTWriter; - friend class CXXRecordDecl; - - const TargetInfo *Target; - const TargetInfo *AuxTarget; + const TargetInfo *Target = nullptr; + const TargetInfo *AuxTarget = nullptr; clang::PrintingPolicy PrintingPolicy; public: @@ -515,31 +539,33 @@ public: Builtin::Context &BuiltinInfo; mutable DeclarationNameTable DeclarationNames; IntrusiveRefCntPtr<ExternalASTSource> ExternalSource; - ASTMutationListener *Listener; + ASTMutationListener *Listener = nullptr; /// \brief Contains parents of a node. - typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector; + using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>; /// \brief Maps from a node to its parents. This is used for nodes that have /// pointer identity only, which are more common and we can save space by /// only storing a unique pointer to them. - typedef llvm::DenseMap<const void *, - llvm::PointerUnion4<const Decl *, const Stmt *, - ast_type_traits::DynTypedNode *, - ParentVector *>> ParentMapPointers; + using ParentMapPointers = + llvm::DenseMap<const void *, + llvm::PointerUnion4<const Decl *, const Stmt *, + ast_type_traits::DynTypedNode *, + ParentVector *>>; /// Parent map for nodes without pointer identity. We store a full /// DynTypedNode for all keys. - typedef llvm::DenseMap< - ast_type_traits::DynTypedNode, - llvm::PointerUnion4<const Decl *, const Stmt *, - ast_type_traits::DynTypedNode *, ParentVector *>> - ParentMapOtherNodes; + using ParentMapOtherNodes = + llvm::DenseMap<ast_type_traits::DynTypedNode, + llvm::PointerUnion4<const Decl *, const Stmt *, + ast_type_traits::DynTypedNode *, + ParentVector *>>; /// Container for either a single DynTypedNode or for an ArrayRef to /// DynTypedNode. For use with ParentMap. class DynTypedNodeList { - typedef ast_type_traits::DynTypedNode DynTypedNode; + using DynTypedNode = ast_type_traits::DynTypedNode; + llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode, ArrayRef<DynTypedNode>> Storage; bool IsSingleNode; @@ -548,6 +574,7 @@ public: DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) { new (Storage.buffer) DynTypedNode(N); } + DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) { new (Storage.buffer) ArrayRef<DynTypedNode>(A); } @@ -626,13 +653,14 @@ public: template <typename T> T *Allocate(size_t Num = 1) const { return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T))); } - void Deallocate(void *Ptr) const { } + void Deallocate(void *Ptr) const {} /// Return the total amount of physical memory allocated for representing /// AST nodes and type information. size_t getASTAllocatedMemory() const { return BumpAlloc.getTotalMemory(); } + /// Return the total memory used for various side tables. size_t getSideTableAllocatedMemory() const; @@ -649,6 +677,7 @@ public: /// Returns empty type if there is no appropriate target types. QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const; + /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. @@ -676,7 +705,7 @@ public: RawCommentList Comments; /// \brief True if comments are already loaded from ExternalASTSource. - mutable bool CommentsLoaded; + mutable bool CommentsLoaded = false; class RawCommentAndCacheFlags { public: @@ -759,24 +788,24 @@ public: } /// \brief Return the documentation comment attached to a given declaration. - /// Returns NULL if no comment is attached. + /// Returns nullptr if no comment is attached. /// - /// \param OriginalDecl if not NULL, is set to declaration AST node that had - /// the comment, if the comment we found comes from a redeclaration. + /// \param OriginalDecl if not nullptr, is set to declaration AST node that + /// had the comment, if the comment we found comes from a redeclaration. const RawComment * getRawCommentForAnyRedecl(const Decl *D, const Decl **OriginalDecl = nullptr) const; /// Return parsed documentation comment attached to a given declaration. - /// Returns NULL if no comment is attached. + /// Returns nullptr if no comment is attached. /// - /// \param PP the Preprocessor used with this TU. Could be NULL if + /// \param PP the Preprocessor used with this TU. Could be nullptr if /// preprocessor is not available. comments::FullComment *getCommentForDecl(const Decl *D, const Preprocessor *PP) const; /// Return parsed documentation comment attached to a given declaration. - /// Returns NULL if no comment is attached. Does not look at any + /// Returns nullptr if no comment is attached. Does not look at any /// redeclarations of the declaration. comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const; @@ -788,16 +817,16 @@ private: /// \brief Iterator that visits import declarations. class import_iterator { - ImportDecl *Import; + ImportDecl *Import = nullptr; public: - typedef ImportDecl *value_type; - typedef ImportDecl *reference; - typedef ImportDecl *pointer; - typedef int difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = ImportDecl *; + using reference = ImportDecl *; + using pointer = ImportDecl *; + using difference_type = int; + using iterator_category = std::forward_iterator_tag; - import_iterator() : Import() {} + import_iterator() = default; explicit import_iterator(ImportDecl *Import) : Import(Import) {} reference operator*() const { return Import; } @@ -876,7 +905,7 @@ public: void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl); // Access to the set of methods overridden by the given C++ method. - typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator; + using overridden_cxx_method_iterator = CXXMethodVector::const_iterator; overridden_cxx_method_iterator overridden_methods_begin(const CXXMethodDecl *Method) const; @@ -884,8 +913,10 @@ public: overridden_methods_end(const CXXMethodDecl *Method) const; unsigned overridden_methods_size(const CXXMethodDecl *Method) const; - typedef llvm::iterator_range<overridden_cxx_method_iterator> - overridden_method_range; + + using overridden_method_range = + llvm::iterator_range<overridden_cxx_method_iterator>; + overridden_method_range overridden_methods(const CXXMethodDecl *Method) const; /// \brief Note that the given C++ \p Method overrides the given \p @@ -912,7 +943,8 @@ public: return Import->NextLocalImport; } - typedef llvm::iterator_range<import_iterator> import_range; + using import_range = llvm::iterator_range<import_iterator>; + import_range local_imports() const { return import_range(import_iterator(FirstLocalImport), import_iterator()); } @@ -929,6 +961,7 @@ public: /// 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); @@ -973,6 +1006,7 @@ public: CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON + CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType Float128ComplexTy; CanQualType VoidPtrTy, NullPtrTy; @@ -1067,7 +1101,14 @@ public: /// The resulting type has a union of the qualifiers from T and the address /// space. If T already has an address space specifier, it is silently /// replaced. - QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const; + QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const; + + /// \brief Remove any existing address space on the type and returns the type + /// with qualifiers intact (or that's the idea anyway) + /// + /// The return type should be T with all prior qualifiers minus the address + /// space. + QualType removeAddrSpaceQualType(QualType T) const; /// \brief Apply Objective-C protocol qualifiers to the given type. /// \param allowOnPointerType specifies if we can apply protocol @@ -1175,6 +1216,7 @@ public: /// \brief Return a read_only pipe type for the specified type. QualType getReadPipeType(QualType T) const; + /// \brief Return a write_only pipe type for the specified type. QualType getWritePipeType(QualType T) const; @@ -1182,9 +1224,16 @@ public: /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; + /// Map an AST Type to an OpenCLTypeKind enum value. + TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const; + + /// Get address space for OpenCL type. + LangAS getOpenCLTypeAddrSpace(const Type *T) const; + void setcudaConfigureCallDecl(FunctionDecl *FD) { cudaConfigureCallDecl = FD; } + FunctionDecl *getcudaConfigureCallDecl() { return cudaConfigureCallDecl; } @@ -1192,7 +1241,6 @@ public: /// Returns true iff we need copy/dispose helpers for the given type. bool BlockRequiresCopying(QualType Ty, const VarDecl *D); - /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set /// to false in this case. If HasByrefExtendedLayout returns true, byref variable /// has extended lifetime. @@ -1269,6 +1317,10 @@ public: Expr *SizeExpr, SourceLocation AttrLoc) const; + QualType getDependentAddressSpaceType(QualType PointeeType, + Expr *AddrSpaceExpr, + SourceLocation AttrLoc) const; + /// \brief Return a K&R style C function type like 'int()'. QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const; @@ -1396,6 +1448,7 @@ public: QualType Canonical = QualType()) const; bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); + /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in /// QT's qualified-id protocol list adopt all protocols in IDecl's list /// of protocols. @@ -1426,7 +1479,7 @@ public: /// \brief C++11 deduction pattern for 'auto &&' type. QualType getAutoRRefDeductType() const; - /// \brief C++1z deduced class template specialization type. + /// \brief C++17 deduced class template specialization type. QualType getDeducedTemplateSpecializationType(TemplateName Template, QualType DeducedType, bool IsDependent) const; @@ -1488,6 +1541,11 @@ public: /// <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9). QualType getPointerDiffType() const; + /// \brief Return the unique unsigned counterpart of "ptrdiff_t" + /// integer type. The standard (C11 7.21.6.1p7) refers to this type + /// in the definition of %tu format specifier. + QualType getUnsignedPointerDiffType() const; + /// \brief Return the unique type for "pid_t" defined in /// <sys/types.h>. We need this to compute the correct type for vfork(). QualType getProcessIDType() const; @@ -1581,6 +1639,24 @@ public: return NSCopyingName; } + CanQualType getNSUIntegerType() const { + assert(Target && "Expected target to be initialized"); + const llvm::Triple &T = Target->getTriple(); + // Windows is LLP64 rather than LP64 + if (T.isOSWindows() && T.isArch64Bit()) + return UnsignedLongLongTy; + return UnsignedLongTy; + } + + CanQualType getNSIntegerType() const { + assert(Target && "Expected target to be initialized"); + const llvm::Triple &T = Target->getTriple(); + // Windows is LLP64 rather than LP64 + if (T.isOSWindows() && T.isArch64Bit()) + return LongLongTy; + return LongTy; + } + /// Retrieve the identifier 'bool'. IdentifierInfo *getBoolName() const { if (!BoolName) @@ -1865,10 +1941,17 @@ public: const TemplateArgument &ArgPack) const; enum GetBuiltinTypeError { - GE_None, ///< No error - GE_Missing_stdio, ///< Missing a type from <stdio.h> - GE_Missing_setjmp, ///< Missing a type from <setjmp.h> - GE_Missing_ucontext ///< Missing a type from <ucontext.h> + /// No error + GE_None, + + /// Missing a type from <stdio.h> + GE_Missing_stdio, + + /// Missing a type from <setjmp.h> + GE_Missing_setjmp, + + /// Missing a type from <ucontext.h> + GE_Missing_ucontext }; /// \brief Return the type for the specified builtin. @@ -2019,7 +2102,7 @@ public: getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const; /// \brief Get our current best idea for the key function of the - /// given record decl, or NULL if there isn't one. + /// given record decl, or nullptr if there isn't one. /// /// The key function is, according to the Itanium C++ ABI section 5.2.3: /// ...the first non-pure virtual function that is not inline at the @@ -2072,6 +2155,10 @@ public: void CollectInheritedProtocols(const Decl *CDecl, llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols); + /// \brief Return true if the specified type has unique object representations + /// according to (C++17 [meta.unary.prop]p9) + bool hasUniqueObjectRepresentations(QualType Ty) const; + //===--------------------------------------------------------------------===// // Type Operators //===--------------------------------------------------------------------===// @@ -2103,7 +2190,6 @@ public: bool hasSameType(QualType T1, QualType T2) const { return getCanonicalType(T1) == getCanonicalType(T2); } - bool hasSameType(const Type *T1, const Type *T2) const { return getCanonicalType(T1) == getCanonicalType(T2); } @@ -2192,7 +2278,7 @@ public: getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const; /// \brief Retrieves the default calling convention for the current target. - CallingConv getDefaultCallingConvention(bool isVariadic, + CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod) const; /// \brief Retrieves the "canonical" template name that refers to a @@ -2326,14 +2412,14 @@ public: return getTargetAddressSpace(Q.getAddressSpace()); } - unsigned getTargetAddressSpace(unsigned AS) const; + unsigned getTargetAddressSpace(LangAS AS) const; /// Get target-dependent integer value for null pointer which is used for /// constant folding. uint64_t getTargetNullPointerValue(QualType QT) const; - bool addressSpaceMapManglingFor(unsigned AS) const { - return AddrSpaceMapMangling || AS >= LangAS::FirstTargetAddressSpace; + bool addressSpaceMapManglingFor(LangAS AS) const { + return AddrSpaceMapMangling || isTargetAddressSpace(AS); } private: @@ -2355,12 +2441,15 @@ public: bool isObjCIdType(QualType T) const { return T == getObjCIdType(); } + bool isObjCClassType(QualType T) const { return T == getObjCClassType(); } + bool isObjCSelType(QualType T) const { return T == getObjCSelType(); } + bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS, bool ForCompare); @@ -2394,9 +2483,30 @@ public: QualType mergeObjCGCQualifiers(QualType, QualType); - bool doFunctionTypesMatchOnExtParameterInfos( - const FunctionProtoType *FromFunctionType, - const FunctionProtoType *ToFunctionType); + /// This function merges the ExtParameterInfo lists of two functions. It + /// returns true if the lists are compatible. The merged list is returned in + /// NewParamInfos. + /// + /// \param FirstFnType The type of the first function. + /// + /// \param SecondFnType The type of the second function. + /// + /// \param CanUseFirst This flag is set to true if the first function's + /// ExtParameterInfo list can be used as the composite list of + /// ExtParameterInfo. + /// + /// \param CanUseSecond This flag is set to true if the second function's + /// ExtParameterInfo list can be used as the composite list of + /// ExtParameterInfo. + /// + /// \param NewParamInfos The composite list of ExtParameterInfo. The list is + /// empty if none of the flags are set. + /// + bool mergeExtParameterInfo( + const FunctionProtoType *FirstFnType, + const FunctionProtoType *SecondFnType, + bool &CanUseFirst, bool &CanUseSecond, + SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos); void ResetObjCLayout(const ObjCContainerDecl *CD); @@ -2432,12 +2542,13 @@ public: bool isSentinelNullExpr(const Expr *E); - /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if + /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if /// none exists. ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D); - /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if + + /// \brief Get the implementation of the ObjCCategoryDecl \p D, or nullptr if /// none exists. - ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); + ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D); /// \brief Return true if there is at least one \@implementation in the TU. bool AnyObjCImplementation() { @@ -2447,6 +2558,7 @@ public: /// \brief Set the implementation of ObjCInterfaceDecl. void setObjCImplementation(ObjCInterfaceDecl *IFaceD, ObjCImplementationDecl *ImplD); + /// \brief Set the implementation of ObjCCategoryDecl. void setObjCImplementation(ObjCCategoryDecl *CatD, ObjCCategoryImplDecl *ImplD); @@ -2466,8 +2578,9 @@ public: /// \brief Set the copy inialization expression of a block var decl. void setBlockVarCopyInits(VarDecl*VD, Expr* Init); + /// \brief Get the copy initialization expression of the VarDecl \p VD, or - /// NULL if none exists. + /// nullptr if none exists. Expr *getBlockVarCopyInits(const VarDecl* VD); /// \brief Allocate an uninitialized TypeSourceInfo. @@ -2636,6 +2749,7 @@ private: const FieldDecl *Field, bool includeVBases = true, QualType *NotEncodedT=nullptr) const; + public: // Adds the encoding of a method parameter or return type. void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, @@ -2647,11 +2761,19 @@ public: bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const; enum class InlineVariableDefinitionKind { - None, ///< Not an inline variable. - Weak, ///< Weak definition of inline variable. - WeakUnknown, ///< Weak for now, might become strong later in this TU. - Strong ///< Strong definition. + /// Not an inline variable. + None, + + /// Weak definition of inline variable. + Weak, + + /// Weak for now, might become strong later in this TU. + WeakUnknown, + + /// Strong definition. + Strong }; + /// \brief Determine whether a definition of this inline variable should /// be treated as a weak or strong definition. For compatibility with /// C++14 and before, for a constexpr static data member, if there is an @@ -2661,6 +2783,9 @@ public: getInlineVariableDefinitionKind(const VarDecl *VD) const; private: + friend class DeclarationNameTable; + friend class DeclContext; + const ASTRecordLayout & getObjCLayout(const ObjCInterfaceDecl *D, const ObjCImplementationDecl *Impl) const; @@ -2673,26 +2798,23 @@ private: // into the datastructures which avoids this mess during deallocation but is // wasteful of memory, and here we require a lot of error prone book keeping // in order to track and run destructors while we're tearing things down. - typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16> - DeallocationFunctionsAndArguments; + using DeallocationFunctionsAndArguments = + llvm::SmallVector<std::pair<void (*)(void *), void *>, 16>; DeallocationFunctionsAndArguments Deallocations; // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, // but we include it here so that ASTContext can quickly deallocate them. - llvm::PointerIntPair<StoredDeclsMap*,1> LastSDM; - - friend class DeclContext; - friend class DeclarationNameTable; - - void ReleaseDeclContextMaps(); - void ReleaseParentMapEntries(); + llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM; std::unique_ptr<ParentMapPointers> PointerParents; std::unique_ptr<ParentMapOtherNodes> OtherParents; std::unique_ptr<VTableContextBase> VTContext; + void ReleaseDeclContextMaps(); + void ReleaseParentMapEntries(); + public: enum PragmaSectionFlag : unsigned { PSF_None = 0, @@ -2712,27 +2834,26 @@ public: SectionInfo(DeclaratorDecl *Decl, SourceLocation PragmaSectionLocation, int SectionFlags) - : Decl(Decl), - PragmaSectionLocation(PragmaSectionLocation), - SectionFlags(SectionFlags) {} + : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation), + SectionFlags(SectionFlags) {} }; llvm::StringMap<SectionInfo> SectionInfos; }; /// \brief Utility function for constructing a nullary selector. -static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) { +inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(0, &II); } /// \brief Utility function for constructing an unary selector. -static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { +inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); return Ctx.Selectors.getSelector(1, &II); } -} // end namespace clang +} // namespace clang // operator new and delete aren't allowed inside namespaces. @@ -2763,11 +2884,12 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) { /// @param C The ASTContext that provides the allocator. /// @param Alignment The alignment of the allocated memory (if the underlying /// allocator supports it). -/// @return The allocated memory. Could be NULL. +/// @return The allocated memory. Could be nullptr. inline void *operator new(size_t Bytes, const clang::ASTContext &C, size_t Alignment) { return C.Allocate(Bytes, Alignment); } + /// @brief Placement delete companion to the new above. /// /// This operator is just a companion to the new above. There is no way of @@ -2800,7 +2922,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) { /// @param C The ASTContext that provides the allocator. /// @param Alignment The alignment of the allocated memory (if the underlying /// allocator supports it). -/// @return The allocated memory. Could be NULL. +/// @return The allocated memory. Could be nullptr. inline void *operator new[](size_t Bytes, const clang::ASTContext& C, size_t Alignment = 8) { return C.Allocate(Bytes, Alignment); diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index a8eff1a2fcbb..9395d36d87e5 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -22,6 +22,7 @@ namespace clang { class CXXRecordDecl; class Decl; class DeclContext; + class Expr; class FieldDecl; class FunctionDecl; class FunctionTemplateDecl; @@ -35,6 +36,7 @@ namespace clang { class QualType; class RecordDecl; class TagDecl; + class ValueDecl; class VarDecl; class VarTemplateDecl; class VarTemplateSpecializationDecl; @@ -80,13 +82,19 @@ public: /// \brief A virtual destructor's operator delete has been resolved. virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD, - const FunctionDecl *Delete) {} + const FunctionDecl *Delete, + Expr *ThisArg) {} /// \brief An implicit member got a definition. virtual void CompletedImplicitDefinition(const FunctionDecl *D) {} - /// \brief A static data member was implicitly instantiated. - virtual void StaticDataMemberInstantiated(const VarDecl *D) {} + /// \brief The instantiation of a templated function or variable was + /// requested. In particular, the point of instantiation and template + /// specialization kind of \p D may have changed. + virtual void InstantiationRequested(const ValueDecl *D) {} + + /// \brief A templated variable's definition was implicitly instantiated. + virtual void VariableDefinitionInstantiated(const VarDecl *D) {} /// \brief A function template's definition was instantiated. virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {} diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h index 9078a0e80299..3693aeccfe14 100644 --- a/include/clang/AST/ASTUnresolvedSet.h +++ b/include/clang/AST/ASTUnresolvedSet.h @@ -1,4 +1,4 @@ -//===-- ASTUnresolvedSet.h - Unresolved sets of declarations ---*- C++ -*-===// +//===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,14 +16,22 @@ #define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H #include "clang/AST/ASTVector.h" +#include "clang/AST/DeclAccessPair.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/Specifiers.h" +#include <cassert> +#include <cstdint> namespace clang { +class NamedDecl; + /// \brief An UnresolvedSet-like class which uses the ASTContext's allocator. class ASTUnresolvedSet { + friend class LazyASTUnresolvedSet; + struct DeclsTy : ASTVector<DeclAccessPair> { - DeclsTy() {} + DeclsTy() = default; DeclsTy(ASTContext &C, unsigned N) : ASTVector<DeclAccessPair>(C, N) {} bool isLazy() const { return getTag(); } @@ -32,14 +40,12 @@ class ASTUnresolvedSet { DeclsTy Decls; - friend class LazyASTUnresolvedSet; - public: - ASTUnresolvedSet() {} + ASTUnresolvedSet() = default; ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {} - typedef UnresolvedSetIterator iterator; - typedef UnresolvedSetIterator const_iterator; + using iterator = UnresolvedSetIterator; + using const_iterator = UnresolvedSetIterator; iterator begin() { return iterator(Decls.begin()); } iterator end() { return iterator(Decls.end()); } @@ -98,13 +104,14 @@ public: } void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); } + void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) { assert(Impl.empty() || Impl.Decls.isLazy()); Impl.Decls.setLazy(true); - Impl.addDecl(C, reinterpret_cast<NamedDecl*>(ID << 2), AS); + Impl.addDecl(C, reinterpret_cast<NamedDecl *>(ID << 2), AS); } }; } // namespace clang -#endif +#endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h index 717a9e9dff34..80cd6b7007a6 100644 --- a/include/clang/AST/ASTVector.h +++ b/include/clang/AST/ASTVector.h @@ -1,4 +1,4 @@ -//===- ASTVector.h - Vector that uses ASTContext for allocation --*- C++ -*-=// +//===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=// // // The LLVM Compiler Infrastructure // @@ -18,22 +18,26 @@ #ifndef LLVM_CLANG_AST_ASTVECTOR_H #define LLVM_CLANG_AST_ASTVECTOR_H -#include "clang/AST/AttrIterator.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/Support/type_traits.h" #include <algorithm> +#include <cassert> #include <cstddef> #include <cstring> +#include <iterator> #include <memory> +#include <type_traits> +#include <utility> namespace clang { - class ASTContext; + +class ASTContext; template<typename T> class ASTVector { private: - T *Begin, *End; - llvm::PointerIntPair<T*, 1, bool> Capacity; + T *Begin = nullptr; + T *End = nullptr; + llvm::PointerIntPair<T *, 1, bool> Capacity; void setEnd(T *P) { this->End = P; } @@ -45,7 +49,7 @@ protected: public: // Default ctor - Initialize to empty. - ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {} + ASTVector() : Capacity(nullptr, false) {} ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) { O.Begin = O.End = nullptr; @@ -53,14 +57,15 @@ public: O.Capacity.setInt(false); } - ASTVector(const ASTContext &C, unsigned N) - : Begin(nullptr), End(nullptr), Capacity(nullptr, false) { + ASTVector(const ASTContext &C, unsigned N) : Capacity(nullptr, false) { reserve(C, N); } ASTVector &operator=(ASTVector &&RHS) { ASTVector O(std::move(RHS)); + using std::swap; + swap(Begin, O.Begin); swap(End, O.End); swap(Capacity, O.Capacity); @@ -74,19 +79,19 @@ public: } } - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T value_type; - typedef T* iterator; - typedef const T* const_iterator; + using size_type = size_t; + using difference_type = ptrdiff_t; + using value_type = T; + using iterator = T *; + using const_iterator = const T *; - typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; + using const_reverse_iterator = std::reverse_iterator<const_iterator>; + using reverse_iterator = std::reverse_iterator<iterator>; - typedef T& reference; - typedef const T& const_reference; - typedef T* pointer; - typedef const T* const_pointer; + using reference = T &; + using const_reference = const T &; + using pointer = T *; + using const_pointer = const T *; // forward iterator creation methods. iterator begin() { return Begin; } @@ -175,7 +180,6 @@ public: size_t capacity() const { return this->capacity_ptr() - Begin; } /// append - Add the specified range to the end of the SmallVector. - /// template<typename in_iter> void append(const ASTContext &C, in_iter in_start, in_iter in_end) { size_type NumInputs = std::distance(in_start, in_end); @@ -195,7 +199,6 @@ public: } /// append - Add the specified range to the end of the SmallVector. - /// void append(const ASTContext &C, size_type NumInputs, const T &Elt) { // Grow allocated space if needed. if (NumInputs > size_type(this->capacity_ptr()-this->end())) @@ -368,6 +371,7 @@ protected: const_iterator capacity_ptr() const { return (iterator) Capacity.getPointer(); } + iterator capacity_ptr() { return (iterator)Capacity.getPointer(); } }; @@ -401,5 +405,6 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) { Capacity.setPointer(Begin+NewCapacity); } -} // end: clang namespace -#endif +} // namespace clang + +#endif // LLVM_CLANG_AST_ASTVECTOR_H diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h index fb9b049e5d6b..56807b4590d3 100644 --- a/include/clang/AST/AttrIterator.h +++ b/include/clang/AST/AttrIterator.h @@ -1,4 +1,4 @@ -//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===// +//===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,16 +15,23 @@ #define LLVM_CLANG_AST_ATTRITERATOR_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Casting.h" +#include <cassert> +#include <cstddef> #include <iterator> namespace clang { - class ASTContext; - class Attr; -} + +class ASTContext; +class Attr; + +} // namespace clang // Defined in ASTContext.h void *operator new(size_t Bytes, const clang::ASTContext &C, 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, @@ -39,13 +46,13 @@ void operator delete[](void *Ptr, const clang::ASTContext &C, size_t); namespace clang { /// AttrVec - A vector of Attr, which is how they are stored on the AST. -typedef SmallVector<Attr *, 4> AttrVec; +using AttrVec = SmallVector<Attr *, 4>; /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only /// providing attributes that are of a specific type. template <typename SpecificAttr, typename Container = AttrVec> class specific_attr_iterator { - typedef typename Container::const_iterator Iterator; + using Iterator = typename Container::const_iterator; /// Current - The current, underlying iterator. /// In order to ensure we don't dereference an invalid iterator unless @@ -67,14 +74,14 @@ class specific_attr_iterator { } public: - typedef SpecificAttr* value_type; - typedef SpecificAttr* reference; - typedef SpecificAttr* pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = SpecificAttr *; + using reference = SpecificAttr *; + using pointer = SpecificAttr *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - specific_attr_iterator() : Current() { } - explicit specific_attr_iterator(Iterator i) : Current(i) { } + specific_attr_iterator() = default; + explicit specific_attr_iterator(Iterator i) : Current(i) {} reference operator*() const { AdvanceToNext(); @@ -136,6 +143,6 @@ inline SpecificAttr *getSpecificAttr(const Container& container) { return nullptr; } -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_ATTRITERATOR_H diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h index 66af023c828e..fdb7e718fe9e 100644 --- a/include/clang/AST/BaseSubobject.h +++ b/include/clang/AST/BaseSubobject.h @@ -1,4 +1,4 @@ -//===--- BaseSubobject.h - BaseSubobject class ----------------------------===// +//===- BaseSubobject.h - BaseSubobject class --------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,12 +15,15 @@ #define LLVM_CLANG_AST_BASESUBOBJECT_H #include "clang/AST/CharUnits.h" -#include "clang/AST/DeclCXX.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/type_traits.h" +#include <cstdint> +#include <utility> namespace clang { + +class CXXRecordDecl; + // BaseSubobject - Uniquely identifies a direct or indirect base class. // Stores both the base class decl and the offset from the most derived class to // the base class. Used for vtable and VTT generation. @@ -32,9 +35,9 @@ class BaseSubobject { CharUnits BaseOffset; public: - BaseSubobject() { } + BaseSubobject() = default; BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset) - : Base(Base), BaseOffset(BaseOffset) { } + : Base(Base), BaseOffset(BaseOffset) {} /// getBase - Returns the base class declaration. const CXXRecordDecl *getBase() const { return Base; } @@ -47,7 +50,7 @@ public: } }; -} // end namespace clang +} // namespace clang namespace llvm { @@ -65,7 +68,8 @@ template<> struct DenseMapInfo<clang::BaseSubobject> { } static unsigned getHashValue(const clang::BaseSubobject &Base) { - typedef std::pair<const clang::CXXRecordDecl *, clang::CharUnits> PairTy; + using PairTy = std::pair<const clang::CXXRecordDecl *, clang::CharUnits>; + return DenseMapInfo<PairTy>::getHashValue(PairTy(Base.getBase(), Base.getBaseOffset())); } @@ -81,6 +85,6 @@ template <> struct isPodLike<clang::BaseSubobject> { static const bool value = true; }; -} +} // namespace llvm -#endif +#endif // LLVM_CLANG_AST_BASESUBOBJECT_H diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index 181131aba07f..e4f5f7db2f73 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy) // 'long double' FLOATING_TYPE(LongDouble, LongDoubleTy) +// '_Float16' +FLOATING_TYPE(Float16, HalfTy) + // '__float128' FLOATING_TYPE(Float128, Float128Ty) diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt index 260734f2200a..942d08d585fe 100644 --- a/include/clang/AST/CMakeLists.txt +++ b/include/clang/AST/CMakeLists.txt @@ -50,3 +50,6 @@ clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list SOURCE CommentCommands.td TARGET ClangCommentCommandList) +clang_tablegen(StmtDataCollectors.inc -gen-clang-data-collectors + SOURCE StmtDataCollectors.td + TARGET StmtDataCollectors) diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 980608570fd6..11fb229f0c09 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -1,4 +1,4 @@ -//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===// +//===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,19 +16,23 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" -#include <cassert> +#include "llvm/ADT/iterator_range.h" #include <list> +#include <memory> +#include <utility> namespace clang { - -class CXXBaseSpecifier; -class CXXMethodDecl; -class CXXRecordDecl; + +class ASTContext; class NamedDecl; /// \brief Represents an element in a path from a derived class to a @@ -66,12 +70,12 @@ struct CXXBasePathElement { /// subobject is being used. class CXXBasePath : public SmallVector<CXXBasePathElement, 4> { public: - CXXBasePath() : Access(AS_public) {} - /// \brief The access along this inheritance path. This is only /// calculated when recording paths. AS_none is a special value /// used to indicate a path which permits no legal access. - AccessSpecifier Access; + AccessSpecifier Access = AS_public; + + CXXBasePath() = default; /// \brief The set of declarations found inside this base class /// subobject. @@ -113,8 +117,10 @@ public: /// refer to the same base class subobject of type A (the virtual /// one), there is no ambiguity. class CXXBasePaths { + friend class CXXRecordDecl; + /// \brief The type from which this search originated. - CXXRecordDecl *Origin; + CXXRecordDecl *Origin = nullptr; /// Paths - The actual set of paths that can be taken from the /// derived class to the same base class. @@ -152,15 +158,13 @@ class CXXBasePaths { CXXBasePath ScratchPath; /// DetectedVirtual - The base class that is virtual. - const RecordType *DetectedVirtual; + const RecordType *DetectedVirtual = nullptr; /// \brief Array of the declarations that have been found. This /// array is constructed only if needed, e.g., to iterate over the /// results within LookupResult. std::unique_ptr<NamedDecl *[]> DeclsFound; - unsigned NumDeclsFound; - - friend class CXXRecordDecl; + unsigned NumDeclsFound = 0; void ComputeDeclsFound(); @@ -169,17 +173,16 @@ class CXXBasePaths { bool LookupInDependent = false); public: - typedef std::list<CXXBasePath>::iterator paths_iterator; - typedef std::list<CXXBasePath>::const_iterator const_paths_iterator; - typedef NamedDecl **decl_iterator; + using paths_iterator = std::list<CXXBasePath>::iterator; + using const_paths_iterator = std::list<CXXBasePath>::const_iterator; + using decl_iterator = NamedDecl **; /// BasePaths - Construct a new BasePaths structure to record the /// paths for a derived-to-base search. explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true, bool DetectVirtual = true) - : Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), - DetectVirtual(DetectVirtual), DetectedVirtual(nullptr), - NumDeclsFound(0) {} + : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), + DetectVirtual(DetectVirtual) {} paths_iterator begin() { return Paths.begin(); } paths_iterator end() { return Paths.end(); } @@ -189,7 +192,8 @@ public: CXXBasePath& front() { return Paths.front(); } const CXXBasePath& front() const { return Paths.front(); } - typedef llvm::iterator_range<decl_iterator> decl_range; + using decl_range = llvm::iterator_range<decl_iterator>; + decl_range found_decls(); /// \brief Determine whether the path from the most-derived type to the @@ -231,25 +235,24 @@ public: /// \brief Uniquely identifies a virtual method within a class /// hierarchy by the method itself and a class subobject number. struct UniqueVirtualMethod { - UniqueVirtualMethod() - : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { } - - UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject, - const CXXRecordDecl *InVirtualSubobject) - : Method(Method), Subobject(Subobject), - InVirtualSubobject(InVirtualSubobject) { } - /// \brief The overriding virtual method. - CXXMethodDecl *Method; + CXXMethodDecl *Method = nullptr; /// \brief The subobject in which the overriding virtual method /// resides. - unsigned Subobject; + unsigned Subobject = 0; /// \brief The virtual base class subobject of which this overridden /// virtual method is a part. Note that this records the closest /// derived virtual base class subobject. - const CXXRecordDecl *InVirtualSubobject; + const CXXRecordDecl *InVirtualSubobject = nullptr; + + UniqueVirtualMethod() = default; + + UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject, + const CXXRecordDecl *InVirtualSubobject) + : Method(Method), Subobject(Subobject), + InVirtualSubobject(InVirtualSubobject) {} friend bool operator==(const UniqueVirtualMethod &X, const UniqueVirtualMethod &Y) { @@ -271,14 +274,16 @@ struct UniqueVirtualMethod { /// pair is the virtual method that overrides it (including the /// subobject in which that virtual function occurs). class OverridingMethods { - typedef SmallVector<UniqueVirtualMethod, 4> ValuesT; - typedef llvm::MapVector<unsigned, ValuesT> MapType; + using ValuesT = SmallVector<UniqueVirtualMethod, 4>; + using MapType = llvm::MapVector<unsigned, ValuesT>; + MapType Overrides; public: // Iterate over the set of subobjects that have overriding methods. - typedef MapType::iterator iterator; - typedef MapType::const_iterator const_iterator; + using iterator = MapType::iterator; + using const_iterator = MapType::const_iterator; + iterator begin() { return Overrides.begin(); } const_iterator begin() const { return Overrides.begin(); } iterator end() { return Overrides.end(); } @@ -287,10 +292,10 @@ public: // Iterate over the set of overriding virtual methods in a given // subobject. - typedef SmallVectorImpl<UniqueVirtualMethod>::iterator - overriding_iterator; - typedef SmallVectorImpl<UniqueVirtualMethod>::const_iterator - overriding_const_iterator; + using overriding_iterator = + SmallVectorImpl<UniqueVirtualMethod>::iterator; + using overriding_const_iterator = + SmallVectorImpl<UniqueVirtualMethod>::const_iterator; // Add a new overriding method for a particular subobject. void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding); @@ -357,12 +362,12 @@ public: /// subobject numbers greater than 0 refer to non-virtual base class /// subobjects of that type. class CXXFinalOverriderMap - : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> { }; + : public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {}; /// \brief A set of all the primary bases for a class. class CXXIndirectPrimaryBaseSet - : public llvm::SmallSet<const CXXRecordDecl*, 32> { }; + : public llvm::SmallSet<const CXXRecordDecl*, 32> {}; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_CXXINHERITANCE_H diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 25f6172be9b1..6487613200de 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -1,4 +1,4 @@ -//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===// +//===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,13 +16,29 @@ #define LLVM_CLANG_AST_CANONICALTYPE_H #include "clang/AST/Type.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/iterator.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <iterator> +#include <type_traits> namespace clang { template<typename T> class CanProxy; template<typename T> struct CanProxyAdaptor; +class CXXRecordDecl; +class EnumDecl; +class Expr; +class IdentifierInfo; +class ObjCInterfaceDecl; +class RecordDecl; +class TagDecl; +class TemplateTypeParmDecl; //----------------------------------------------------------------------------// // Canonical, qualified type template @@ -46,8 +62,6 @@ template<typename T> struct CanProxyAdaptor; /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can /// be implicitly converted to a QualType, but the reverse operation requires /// a call to ASTContext::getCanonicalType(). -/// -/// template<typename T = Type> class CanQual { /// \brief The actual, canonical type. @@ -55,7 +69,7 @@ class CanQual { public: /// \brief Constructs a NULL canonical type. - CanQual() : Stored() { } + CanQual() = default; /// \brief Converting constructor that permits implicit upcasting of /// canonical type pointers. @@ -66,12 +80,11 @@ public: /// \brief Retrieve the underlying type pointer, which refers to a /// canonical type. /// - /// The underlying pointer must not be NULL. + /// The underlying pointer must not be nullptr. const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); } /// \brief Retrieve the underlying type pointer, which refers to a - /// canonical type, or NULL. - /// + /// canonical type, or nullptr. const T *getTypePtrOrNull() const { return cast_or_null<T>(Stored.getTypePtrOrNull()); } @@ -125,9 +138,11 @@ public: bool isConstQualified() const { return Stored.isLocalConstQualified(); } + bool isVolatileQualified() const { return Stored.isLocalVolatileQualified(); } + bool isRestrictQualified() const { return Stored.isLocalRestrictQualified(); } @@ -195,7 +210,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) { } /// \brief Represents a canonical, potentially-qualified type. -typedef CanQual<Type> CanQualType; +using CanQualType = CanQual<Type>; inline CanQualType Type::getCanonicalTypeUnqualified() const { return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); @@ -320,7 +335,7 @@ public: /// than the more typical @c QualType, to propagate the notion of "canonical" /// through the system. template<typename T> -struct CanProxyAdaptor : CanProxyBase<T> { }; +struct CanProxyAdaptor : CanProxyBase<T> {}; /// \brief Canonical proxy type returned when retrieving the members of a /// canonical type or as the result of the @c CanQual<T>::getAs member @@ -333,7 +348,7 @@ template<typename T> class CanProxy : public CanProxyAdaptor<T> { public: /// \brief Build a NULL proxy. - CanProxy() { } + CanProxy() = default; /// \brief Build a proxy to the given canonical type. CanProxy(CanQual<T> Stored) { this->Stored = Stored; } @@ -342,7 +357,7 @@ public: operator CanQual<T>() const { return this->Stored; } }; -} // end namespace clang +} // namespace clang namespace llvm { @@ -350,8 +365,9 @@ namespace llvm { /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. /// to return smart pointer (proxies?). template<typename T> -struct simplify_type< ::clang::CanQual<T> > { - typedef const T *SimpleType; +struct simplify_type< ::clang::CanQual<T>> { + using SimpleType = const T *; + static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) { return Val.getTypePtr(); } @@ -359,19 +375,20 @@ struct simplify_type< ::clang::CanQual<T> > { // Teach SmallPtrSet that CanQual<T> is "basically a pointer". template<typename T> -class PointerLikeTypeTraits<clang::CanQual<T> > { -public: - static inline void *getAsVoidPointer(clang::CanQual<T> P) { +struct PointerLikeTypeTraits<clang::CanQual<T>> { + static void *getAsVoidPointer(clang::CanQual<T> P) { return P.getAsOpaquePtr(); } - static inline clang::CanQual<T> getFromVoidPointer(void *P) { + + static clang::CanQual<T> getFromVoidPointer(void *P) { return clang::CanQual<T>::getFromOpaquePtr(P); } + // qualifier information is encoded in the low bits. enum { NumLowBitsAvailable = 0 }; }; -} // end namespace llvm +} // namespace llvm namespace clang { @@ -389,7 +406,7 @@ struct CanTypeIterator CanQualType, typename std::iterator_traits<InputIterator>::difference_type, CanProxy<Type>, CanQualType> { - CanTypeIterator() {} + CanTypeIterator() = default; explicit CanTypeIterator(InputIterator Iter) : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {} @@ -487,6 +504,7 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR( ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos) + CanQualType getParamType(unsigned i) const { return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i)); } @@ -494,8 +512,8 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals) - typedef CanTypeIterator<FunctionProtoType::param_type_iterator> - param_type_iterator; + using param_type_iterator = + CanTypeIterator<FunctionProtoType::param_type_iterator>; param_type_iterator param_type_begin() const { return param_type_iterator(this->getTypePtr()->param_type_begin()); @@ -567,7 +585,8 @@ struct CanProxyAdaptor<ObjCObjectType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) - typedef ObjCObjectPointerType::qual_iterator qual_iterator; + using qual_iterator = ObjCObjectPointerType::qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) @@ -585,7 +604,8 @@ struct CanProxyAdaptor<ObjCObjectPointerType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) - typedef ObjCObjectPointerType::qual_iterator qual_iterator; + using qual_iterator = ObjCObjectPointerType::qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) @@ -662,7 +682,6 @@ CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const { return CanProxy<Type>(*this); } -} - +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_CANONICALTYPE_H diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 564c8ec9b9ea..ddead6046a14 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -40,14 +40,14 @@ namespace clang { typedef int64_t QuantityType; private: - QuantityType Quantity; + QuantityType Quantity = 0; explicit CharUnits(QuantityType C) : Quantity(C) {} public: /// CharUnits - A default constructor. - CharUnits() : Quantity(0) {} + CharUnits() = default; /// Zero - Construct a CharUnits quantity of zero. static CharUnits Zero() { diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h index 21641bfeb89f..d1cc2d0a4e5e 100644 --- a/include/clang/AST/CommentVisitor.h +++ b/include/clang/AST/CommentVisitor.h @@ -1,4 +1,4 @@ -//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===// +//===- CommentVisitor.h - Visitor for Comment subclasses --------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,8 +16,8 @@ namespace clang { namespace comments { -template <typename T> struct make_ptr { typedef T *type; }; -template <typename T> struct make_const_ptr { typedef const T *type; }; +template <typename T> struct make_ptr { using type = T *; }; +template <typename T> struct make_const_ptr { using type = const T *; }; template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> class CommentVisitorBase { @@ -64,7 +64,7 @@ template<typename ImplClass, typename RetTy=void> class ConstCommentVisitor : public CommentVisitorBase<make_const_ptr, ImplClass, RetTy> {}; -} // end namespace comments -} // end namespace clang +} // namespace comments +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_COMMENTVISITOR_H diff --git a/include/clang/AST/DataCollection.h b/include/clang/AST/DataCollection.h new file mode 100644 index 000000000000..229ac2bd0f22 --- /dev/null +++ b/include/clang/AST/DataCollection.h @@ -0,0 +1,65 @@ +//===--- DatatCollection.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// \brief This file declares helper methods for collecting data from AST nodes. +/// +/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include +/// StmtDataCollectors.inc after defining the macros that you need. This +/// provides data collection implementations for most Stmt kinds. Note +/// that that code requires some conditions to be met: +/// +/// - There must be a method addData(const T &Data) that accepts strings, +/// integral types as well as QualType. All data is forwarded using +/// to this method. +/// - The ASTContext of the Stmt must be accessible by the name Context. +/// +/// It is also possible to override individual visit methods. Have a look at +/// the DataCollector in lib/Analysis/CloneDetection.cpp for a usage example. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DATACOLLECTION_H +#define LLVM_CLANG_AST_DATACOLLECTION_H + +#include "clang/AST/ASTContext.h" + +namespace clang { +namespace data_collection { + +/// Returns a string that represents all macro expansions that expanded into the +/// given SourceLocation. +/// +/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations +/// A and B are expanded from the same macros in the same order. +std::string getMacroStack(SourceLocation Loc, ASTContext &Context); + +/// Utility functions for implementing addData() for a consumer that has a +/// method update(StringRef) +template <class T> +void addDataToConsumer(T &DataConsumer, llvm::StringRef Str) { + DataConsumer.update(Str); +} + +template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) { + addDataToConsumer(DataConsumer, QT.getAsString()); +} + +template <class T, class Type> +typename std::enable_if< + std::is_integral<Type>::value || std::is_enum<Type>::value || + std::is_convertible<Type, size_t>::value // for llvm::hash_code + >::type +addDataToConsumer(T &DataConsumer, Type Data) { + DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data))); +} + +} // end namespace data_collection +} // end namespace clang + +#endif // LLVM_CLANG_AST_DATACOLLECTION_H diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 54e6ebcd8af2..4db0b1ef949b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1,4 +1,4 @@ -//===--- Decl.h - Classes for representing declarations ---------*- C++ -*-===// +//===- Decl.h - Classes for representing declarations -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,33 +18,58 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/Type.h" +#include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Linkage.h" -#include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/PragmaKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Basic/Visibility.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <string> +#include <utility> namespace clang { + +class ASTContext; struct ASTTemplateArgumentListInfo; -class CXXTemporary; +class Attr; class CompoundStmt; class DependentFunctionTemplateSpecializationInfo; +class EnumDecl; class Expr; class FunctionTemplateDecl; class FunctionTemplateSpecializationInfo; class LabelStmt; class MemberSpecializationInfo; -class NestedNameSpecifier; +class Module; +class NamespaceDecl; class ParmVarDecl; +class RecordDecl; class Stmt; class StringLiteral; +class TagDecl; class TemplateArgumentList; +class TemplateArgumentListInfo; class TemplateParameterList; class TypeAliasTemplateDecl; class TypeLoc; @@ -58,13 +83,15 @@ class VarTemplateDecl; /// TypeLoc TL = TypeSourceInfo->getTypeLoc(); /// TL.getStartLoc().print(OS, SrcMgr); /// @endcode -/// class TypeSourceInfo { - QualType Ty; // Contains a memory block after the class, used for type source information, // allocated by ASTContext. friend class ASTContext; - TypeSourceInfo(QualType ty) : Ty(ty) { } + + QualType Ty; + + TypeSourceInfo(QualType ty) : Ty(ty) {} + public: /// \brief Return the type wrapped by this type source info. QualType getType() const { return Ty; } @@ -78,14 +105,16 @@ public: /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { - virtual void anchor(); ASTContext &Ctx; /// The (most recently entered) anonymous namespace for this /// translation unit, if one has been created. - NamespaceDecl *AnonymousNamespace; + NamespaceDecl *AnonymousNamespace = nullptr; explicit TranslationUnitDecl(ASTContext &ctx); + + virtual void anchor(); + public: ASTContext &getASTContext() const { return Ctx; } @@ -93,6 +122,7 @@ public: void setAnonymousNamespace(NamespaceDecl *D) { AnonymousNamespace = D; } static TranslationUnitDecl *Create(ASTContext &C); + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == TranslationUnit; } @@ -109,18 +139,18 @@ public: class PragmaCommentDecl final : public Decl, private llvm::TrailingObjects<PragmaCommentDecl, char> { - virtual void anchor(); - - PragmaMSCommentKind CommentKind; - - friend TrailingObjects; friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; + + PragmaMSCommentKind CommentKind; PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc, PragmaMSCommentKind CommentKind) : Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {} + virtual void anchor(); + public: static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC, SourceLocation CommentLoc, @@ -143,18 +173,18 @@ public: class PragmaDetectMismatchDecl final : public Decl, private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> { - virtual void anchor(); - - size_t ValueStart; - - friend TrailingObjects; friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; + + size_t ValueStart; PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc, size_t ValueStart) : Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {} + virtual void anchor(); + public: static PragmaDetectMismatchDecl *Create(const ASTContext &C, TranslationUnitDecl *DC, @@ -189,14 +219,16 @@ public: /// 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) {} + + virtual void anchor(); + 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; } @@ -211,18 +243,19 @@ public: /// NamedDecl - This represents a decl with a name. Many decls have names such /// as ObjCMethodDecl, but not \@class, etc. class NamedDecl : public Decl { - virtual void anchor(); /// Name - The name of this declaration, which is typically a normal /// identifier but may also be a special kind of name (C++ /// constructor, Objective-C selector, etc.) DeclarationName Name; + virtual void anchor(); + private: NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY; protected: NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N) - : Decl(DK, DC, L), Name(N) { } + : Decl(DK, DC, L), Name(N) {} public: /// getIdentifier - Get the identifier that names this declaration, @@ -272,8 +305,7 @@ public: // FIXME: Remove string version. std::string getQualifiedNameAsString() const; - /// getNameForDiagnostic - Appends a human-readable name for this - /// declaration into the given stream. + /// Appends a human-readable name for this declaration into the given stream. /// /// This is the method invoked by Sema when displaying a NamedDecl /// in a diagnostic. It does not necessarily produce the same @@ -339,6 +371,12 @@ public: return clang::isExternallyVisible(getLinkageInternal()); } + /// Determine whether this declaration can be redeclared in a + /// different translation unit. + bool isExternallyDeclarable() const { + return isExternallyVisible() && !getOwningModuleForLinkage(); + } + /// \brief Determines the visibility of this entity. Visibility getVisibility() const { return getLinkageAndVisibility().getVisibility(); @@ -349,7 +387,14 @@ public: /// Kinds of explicit visibility. enum ExplicitVisibilityKind { + /// Do an LV computation for, ultimately, a type. + /// Visibility may be restricted by type visibility settings and + /// the visibility of template arguments. VisibilityForType, + + /// Do an LV computation for, ultimately, a non-type declaration. + /// Visibility may be restricted by value visibility settings and + /// the visibility of template arguments. VisibilityForValue }; @@ -412,10 +457,10 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) { /// location of the statement. For GNU local labels (__label__), the decl /// location is where the __label__ is. class LabelDecl : public NamedDecl { - void anchor() override; LabelStmt *TheStmt; StringRef MSAsmName; - bool MSAsmNameResolved; + bool MSAsmNameResolved = false; + /// LocStart - For normal labels, this is the same as the main declaration /// label, i.e., the location of the identifier; for GNU local labels, /// this is the location of the __label__ keyword. @@ -423,10 +468,9 @@ class LabelDecl : public NamedDecl { LabelDecl(DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, LabelStmt *S, SourceLocation StartL) - : NamedDecl(Label, DC, IdentL, II), - TheStmt(S), - MSAsmNameResolved(false), - LocStart(StartL) {} + : NamedDecl(Label, DC, IdentL, II), TheStmt(S), LocStart(StartL) {} + + void anchor() override; public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, @@ -446,7 +490,7 @@ public: return SourceRange(LocStart, getLocation()); } - bool isMSAsmLabel() const { return MSAsmName.size() != 0; } + bool isMSAsmLabel() const { return !MSAsmName.empty(); } bool isResolvedMSAsmLabel() const { return isMSAsmLabel() && MSAsmNameResolved; } void setMSAsmLabel(StringRef Name); StringRef getMSAsmLabel() const { return MSAsmName; } @@ -464,6 +508,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext, /// LocStart - The starting location of the source range, pointing /// to either the namespace or the inline keyword. SourceLocation LocStart; + /// RBraceLoc - The ending location of the source range. SourceLocation RBraceLoc; @@ -477,12 +522,16 @@ class NamespaceDecl : public NamedDecl, public DeclContext, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, NamespaceDecl *PrevDecl); - typedef Redeclarable<NamespaceDecl> redeclarable_base; + using redeclarable_base = Redeclarable<NamespaceDecl>; + NamespaceDecl *getNextRedeclarationImpl() override; NamespaceDecl *getPreviousDeclImpl() override; NamespaceDecl *getMostRecentDeclImpl() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static NamespaceDecl *Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, @@ -490,8 +539,9 @@ public: static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID); - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -569,22 +619,21 @@ public: static NamespaceDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<NamespaceDecl *>(const_cast<DeclContext*>(DC)); } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// ValueDecl - Represent the declaration of a variable (in which case it is /// an lvalue) a function (in which case it is a function designator) or /// an enum constant. class ValueDecl : public NamedDecl { - void anchor() override; QualType DeclType; + void anchor() override; + protected: ValueDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T) : NamedDecl(DK, DC, L, N), DeclType(T) {} + public: QualType getType() const { return DeclType; } void setType(QualType newType) { DeclType = newType; } @@ -607,28 +656,23 @@ struct QualifierInfo { /// The count includes all of the template parameter lists that were matched /// against the template-ids occurring into the NNS and possibly (in the /// case of an explicit specialization) a final "template <>". - unsigned NumTemplParamLists; + unsigned NumTemplParamLists = 0; /// TemplParamLists - A new-allocated array of size NumTemplParamLists, /// containing pointers to the "outer" template parameter lists. /// It includes all of the template parameter lists that were matched /// against the template-ids occurring into the NNS and possibly (in the /// case of an explicit specialization) a final "template <>". - TemplateParameterList** TemplParamLists; + TemplateParameterList** TemplParamLists = nullptr; - /// Default constructor. - QualifierInfo() - : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {} + QualifierInfo() = default; + QualifierInfo(const QualifierInfo &) = delete; + QualifierInfo& operator=(const QualifierInfo &) = delete; /// setTemplateParameterListsInfo - Sets info about "outer" template /// parameter lists. void setTemplateParameterListsInfo(ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists); - -private: - // Copy constructor and copy assignment are disabled. - QualifierInfo(const QualifierInfo&) = delete; - QualifierInfo& operator=(const QualifierInfo&) = delete; }; /// \brief Represents a ValueDecl that came out of a declarator. @@ -640,7 +684,7 @@ class DeclaratorDecl : public ValueDecl { TypeSourceInfo *TInfo; }; - llvm::PointerUnion<TypeSourceInfo*, ExtInfo*> DeclInfo; + llvm::PointerUnion<TypeSourceInfo *, ExtInfo *> DeclInfo; /// InnerLocStart - The start of the source range for this declaration, /// ignoring outer template declarations. @@ -654,15 +698,18 @@ protected: DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL) - : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) { - } + : ValueDecl(DK, DC, L, N, T), DeclInfo(TInfo), InnerLocStart(StartL) {} public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + TypeSourceInfo *getTypeSourceInfo() const { return hasExtInfo() ? getExtInfo()->TInfo : DeclInfo.get<TypeSourceInfo*>(); } + void setTypeSourceInfo(TypeSourceInfo *TI) { if (hasExtInfo()) getExtInfo()->TInfo = TI; @@ -680,6 +727,7 @@ public: SourceLocation getOuterLocStart() const; SourceRange getSourceRange() const override LLVM_READONLY; + SourceLocation getLocStart() const LLVM_READONLY { return getOuterLocStart(); } @@ -704,10 +752,12 @@ public: unsigned getNumTemplateParameterLists() const { return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0; } + TemplateParameterList *getTemplateParameterList(unsigned index) const { assert(index < getNumTemplateParameterLists()); return getExtInfo()->TemplParamLists[index]; } + void setTemplateParameterListsInfo(ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists); @@ -718,18 +768,12 @@ public: static bool classofKind(Kind K) { return K >= firstDeclarator && K <= lastDeclarator; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Structure used to store a statement, the constant value to /// which it was evaluated (if any), and whether or not the statement /// is an integral constant expression (if known). struct EvaluatedStmt { - EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false), - CheckingICE(false), IsICE(false) { } - /// \brief Whether this statement was already evaluated. bool WasEvaluated : 1; @@ -751,32 +795,46 @@ struct EvaluatedStmt { Stmt *Value; APValue Evaluated; + + EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false), + CheckingICE(false), IsICE(false) {} + }; /// VarDecl - An instance of this class is created to represent a variable /// declaration or definition. class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> { public: - /// getStorageClassSpecifierString - Return the string used to - /// specify the storage class \p SC. - /// - /// It is illegal to call this function with SC == None. - static const char *getStorageClassSpecifierString(StorageClass SC); - /// \brief Initialization styles. enum InitializationStyle { - CInit, ///< C-style initialization with assignment - CallInit, ///< Call-style initialization (C++98) - ListInit ///< Direct list-initialization (C++11) + /// C-style initialization with assignment + CInit, + + /// Call-style initialization (C++98) + CallInit, + + /// Direct list-initialization (C++11) + ListInit }; /// \brief Kinds of thread-local storage. enum TLSKind { - TLS_None, ///< Not a TLS variable. - TLS_Static, ///< TLS with a known-constant initializer. - TLS_Dynamic ///< TLS with a dynamic initializer. + /// Not a TLS variable. + TLS_None, + + /// TLS with a known-constant initializer. + TLS_Static, + + /// TLS with a dynamic initializer. + TLS_Dynamic }; + /// getStorageClassSpecifierString - Return the string used to + /// specify the storage class \p SC. + /// + /// It is illegal to call this function with SC == None. + static const char *getStorageClassSpecifierString(StorageClass SC); + protected: // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we // have allocated the auxiliary struct of information there. @@ -785,16 +843,20 @@ protected: // this as *many* VarDecls are ParmVarDecls that don't have default // arguments. We could save some space by moving this pointer union to be // allocated in trailing space when necessary. - typedef llvm::PointerUnion<Stmt *, EvaluatedStmt *> InitType; + using InitType = llvm::PointerUnion<Stmt *, EvaluatedStmt *>; /// \brief The initializer for this variable or, for a ParmVarDecl, the /// C++ default argument. mutable InitType Init; private: + friend class ASTDeclReader; + friend class ASTNodeImporter; + friend class StmtIteratorBase; + class VarDeclBitfields { - friend class VarDecl; friend class ASTDeclReader; + friend class VarDecl; unsigned SClass : 3; unsigned TSCSpec : 2; @@ -802,10 +864,6 @@ private: }; enum { NumVarDeclBits = 7 }; - friend class ASTDeclReader; - friend class StmtIteratorBase; - friend class ASTNodeImporter; - protected: enum { NumParameterIndexBits = 8 }; @@ -817,8 +875,8 @@ protected: }; class ParmVarDeclBitfields { - friend class ParmVarDecl; friend class ASTDeclReader; + friend class ParmVarDecl; unsigned : NumVarDeclBits; @@ -850,9 +908,9 @@ protected: }; class NonParmVarDeclBitfields { - friend class VarDecl; - friend class ImplicitParamDecl; friend class ASTDeclReader; + friend class ImplicitParamDecl; + friend class VarDecl; unsigned : NumVarDeclBits; @@ -912,20 +970,24 @@ protected: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass SC); - typedef Redeclarable<VarDecl> redeclarable_base; + using redeclarable_base = Redeclarable<VarDecl>; + VarDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + VarDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + VarDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -1030,7 +1092,6 @@ public: /// inside of functions. It also includes variables inside blocks. /// /// void foo() { int x; static int y; extern int z; } - /// bool isLocalVarDecl() const { if (getKind() != Decl::Var && getKind() != Decl::Decomposition) return false; @@ -1073,9 +1134,14 @@ public: } enum DefinitionKind { - DeclarationOnly, ///< This declaration is only a declaration. - TentativeDefinition, ///< This declaration is a tentative definition. - Definition ///< This declaration is definitely a definition. + /// This declaration is only a declaration. + DeclarationOnly, + + /// This declaration is a tentative definition. + TentativeDefinition, + + /// This declaration is definitely a definition. + Definition }; /// \brief Check whether this declaration is a definition. If this could be @@ -1205,6 +1271,7 @@ public: InitializationStyle getInitStyle() const { return static_cast<InitializationStyle>(VarDeclBits.InitStyle); } + /// \brief Whether the initializer is a direct-initializer (list or call). bool isDirectInit() const { return getInitStyle() != CInit; @@ -1222,8 +1289,8 @@ public: /// definitions one of which needs to be demoted to a declaration to keep /// the AST invariants. void demoteThisDefinitionToDeclaration() { - assert (isThisDeclarationADefinition() && "Not a definition!"); - assert (!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!"); + assert(isThisDeclarationADefinition() && "Not a definition!"); + assert(!isa<ParmVarDecl>(this) && "Cannot demote ParmVarDecls!"); NonParmVarDeclBits.IsThisDeclarationADemotedDefinition = 1; } @@ -1387,12 +1454,23 @@ public: /// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured /// context or something else. enum ImplicitParamKind : unsigned { - ObjCSelf, /// Parameter for Objective-C 'self' argument - ObjCCmd, /// Parameter for Objective-C '_cmd' argument - CXXThis, /// Parameter for C++ 'this' argument - CXXVTT, /// Parameter for C++ virtual table pointers - CapturedContext, /// Parameter for captured context - Other, /// Other implicit parameter + /// Parameter for Objective-C 'self' argument + ObjCSelf, + + /// Parameter for Objective-C '_cmd' argument + ObjCCmd, + + /// Parameter for C++ 'this' argument + CXXThis, + + /// Parameter for C++ virtual table pointers + CXXVTT, + + /// Parameter for captured context + CapturedContext, + + /// Other implicit parameter + Other, }; /// Create implicit parameter. @@ -1425,6 +1503,7 @@ public: ImplicitParamKind getParameterKind() const { return static_cast<ImplicitParamKind>(NonParmVarDeclBits.ImplicitParamKind); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ImplicitParam; } @@ -1604,8 +1683,8 @@ private: unsigned getParameterIndexLarge() const; }; -/// FunctionDecl - An instance of this class is created to represent a -/// function declaration or definition. +/// An instance of this class is created to represent a function declaration or +/// definition. /// /// Since a given function can be declared several times in a program, /// there may be several FunctionDecls that correspond to that @@ -1631,7 +1710,7 @@ private: /// ParamInfo - new[]'d array of pointers to VarDecls for the formal /// parameters of this function. This is null if a prototype or if there are /// no formals. - ParmVarDecl **ParamInfo; + ParmVarDecl **ParamInfo = nullptr; LazyDeclStmtPtr Body; @@ -1640,10 +1719,12 @@ private: unsigned SClass : 3; unsigned IsInline : 1; unsigned IsInlineSpecified : 1; + protected: // This is shared by CXXConstructorDecl, CXXConversionDecl, and // CXXDeductionGuideDecl. unsigned IsExplicitSpecified : 1; + private: unsigned IsVirtualAsWritten : 1; unsigned IsPure : 1; @@ -1656,7 +1737,7 @@ private: unsigned HasImplicitReturnZero : 1; unsigned IsLateTemplateParsed : 1; unsigned IsConstexpr : 1; - unsigned InstantiationIsPending:1; + unsigned InstantiationIsPending : 1; /// \brief Indicates if the function uses __try. unsigned UsesSEHTry : 1; @@ -1669,6 +1750,15 @@ private: /// parsing it. unsigned WillHaveBody : 1; +protected: + /// [C++17] Only used by CXXDeductionGuideDecl. Declared here to avoid + /// increasing the size of CXXDeductionGuideDecl by the size of an unsigned + /// int as opposed to adding a single bit to FunctionDecl. + /// Indicates that the Deduction Guide is the implicitly generated 'copy + /// deduction candidate' (is used during overload resolution). + unsigned IsCopyDeductionCandidate : 1; + +private: /// \brief End part of this FunctionDecl's source range. /// /// We could compute the full range in getSourceRange(). However, when we're @@ -1696,8 +1786,8 @@ private: DependentFunctionTemplateSpecializationInfo *> TemplateOrSpecialization; - /// DNLoc - Provides source/type location info for the - /// declaration name embedded in the DeclaratorDecl base class. + /// Provides source/type location info for the declaration name embedded in + /// the DeclaratorDecl base class. DeclarationNameLoc DNLoc; /// \brief Specify that this function declaration is actually a function @@ -1743,33 +1833,38 @@ protected: bool isConstexprSpecified) : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, StartLoc), - DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(), - SClass(S), IsInline(isInlineSpecified), - IsInlineSpecified(isInlineSpecified), IsExplicitSpecified(false), - IsVirtualAsWritten(false), IsPure(false), + DeclContext(DK), redeclarable_base(C), SClass(S), + IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), + IsExplicitSpecified(false), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified), - InstantiationIsPending(false), - UsesSEHTry(false), HasSkippedBody(false), WillHaveBody(false), - EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), - DNLoc(NameInfo.getInfo()) {} + InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false), + WillHaveBody(false), IsCopyDeductionCandidate(false), + EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {} + + using redeclarable_base = Redeclarable<FunctionDecl>; - typedef Redeclarable<FunctionDecl> redeclarable_base; FunctionDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + FunctionDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + FunctionDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -1826,13 +1921,13 @@ public: return hasBody(Definition); } - /// hasTrivialBody - Returns whether the function has a trivial body that does - /// not require any specific codegen. + /// Returns whether the function has a trivial body that does not require any + /// specific codegen. bool hasTrivialBody() const; - /// isDefined - Returns true if the function is defined at all, including - /// a deleted definition. Except for the behavior when the function is - /// deleted, behaves like hasBody. + /// Returns true if the function is defined at all, including a deleted + /// definition. Except for the behavior when the function is deleted, behaves + /// like hasBody. bool isDefined(const FunctionDecl *&Definition) const; virtual bool isDefined() const { @@ -1851,11 +1946,10 @@ public: return const_cast<FunctionDecl *>(this)->getDefinition(); } - /// getBody - Retrieve the body (definition) of the function. The - /// function body might be in any of the (re-)declarations of this - /// function. The variant that accepts a FunctionDecl pointer will - /// set that function declaration to the actual declaration - /// containing the body (if there is one). + /// Retrieve the body (definition) of the function. The function body might be + /// in any of the (re-)declarations of this function. The variant that accepts + /// a FunctionDecl pointer will set that function declaration to the actual + /// declaration containing the body (if there is one). /// NOTE: For checking if there is a body, use hasBody() instead, to avoid /// unnecessary AST de-serialization of the body. Stmt *getBody(const FunctionDecl *&Definition) const; @@ -1870,15 +1964,13 @@ public: /// /// This does not determine whether the function has been defined (e.g., in a /// previous definition); for that information, use isDefined. - /// bool isThisDeclarationADefinition() const { - return IsDeleted || IsDefaulted || Body || IsLateTemplateParsed || - WillHaveBody || hasDefiningAttr(); + return IsDeleted || IsDefaulted || Body || HasSkippedBody || + IsLateTemplateParsed || WillHaveBody || hasDefiningAttr(); } - /// doesThisDeclarationHaveABody - Returns whether this specific - /// declaration of the function has a body - that is, if it is a non- - /// deleted definition. + /// Returns whether this specific declaration of the function has a body - + /// that is, if it is a non-deleted definition. bool doesThisDeclarationHaveABody() const { return Body || IsLateTemplateParsed; } @@ -2023,6 +2115,9 @@ public: /// true through IsAligned. bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const; + /// \brief Determine whether this is a destroying operator delete. + bool isDestroyingOperatorDelete() const; + /// Compute the language linkage. LanguageLinkage getLanguageLinkage() const; @@ -2071,8 +2166,9 @@ public: } // Iterator access to formal parameters. - typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator; - typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator; + using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator; + using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator; + bool param_empty() const { return parameters().empty(); } param_iterator param_begin() { return parameters().begin(); } param_iterator param_end() { return parameters().end(); } @@ -2080,9 +2176,9 @@ public: param_const_iterator param_end() const { return parameters().end(); } size_t param_size() const { return parameters().size(); } - /// getNumParams - Return the number of parameters this function must have - /// based on its FunctionType. This is the length of the ParamInfo array - /// after it has been created. + /// Return the number of parameters this function must have based on its + /// FunctionType. This is the length of the ParamInfo array after it has been + /// created. unsigned getNumParams() const; const ParmVarDecl *getParamDecl(unsigned i) const { @@ -2097,10 +2193,9 @@ public: setParams(getASTContext(), NewParamInfo); } - /// getMinRequiredArguments - Returns the minimum number of arguments - /// needed to call this function. This may be fewer than the number of - /// function parameters, if some of the parameters have default - /// arguments (in C++). + /// Returns the minimum number of arguments needed to call this function. This + /// may be fewer than the number of function parameters, if some of the + /// parameters have default arguments (in C++). unsigned getMinRequiredArguments() const; QualType getReturnType() const { @@ -2355,18 +2450,14 @@ public: static FunctionDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<FunctionDecl *>(const_cast<DeclContext*>(DC)); } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; - /// FieldDecl - An instance of this class is created by Sema::ActOnField to /// represent a member of a struct/union/class. class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { - // FIXME: This can be packed into the bitfields in Decl. + unsigned BitField : 1; unsigned Mutable : 1; - mutable unsigned CachedFieldIndex : 31; + mutable unsigned CachedFieldIndex : 30; /// The kinds of value we can store in InitializerOrBitWidth. /// @@ -2376,7 +2467,7 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { /// If the pointer is null, there's nothing special. Otherwise, /// this is a bitfield and the pointer is the Expr* storing the /// bit-width. - ISK_BitWidthOrNothing = (unsigned) ICIS_NoInit, + ISK_NoInit = (unsigned) ICIS_NoInit, /// The pointer is an (optional due to delayed parsing) Expr* /// holding the copy-initializer. @@ -2391,30 +2482,40 @@ class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { ISK_CapturedVLAType, }; - /// \brief Storage for either the bit-width, the in-class - /// initializer, or the captured variable length array bound. - /// - /// We can safely combine these because in-class initializers are - /// not permitted for bit-fields, and both are exclusive with VLA - /// captures. + /// If this is a bitfield with a default member initializer, this + /// structure is used to represent the two expressions. + struct InitAndBitWidth { + Expr *Init; + Expr *BitWidth; + }; + + /// \brief Storage for either the bit-width, the in-class initializer, or + /// both (via InitAndBitWidth), or the captured variable length array bound. /// /// If the storage kind is ISK_InClassCopyInit or /// ISK_InClassListInit, but the initializer is null, then this - /// field has an in-class initializer which has not yet been parsed + /// field has an in-class initializer that has not yet been parsed /// and attached. + // FIXME: Tail-allocate this to reduce the size of FieldDecl in the + // overwhelmingly common case that we have none of these things. llvm::PointerIntPair<void *, 2, InitStorageKind> InitStorage; + protected: FieldDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle) : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), - Mutable(Mutable), CachedFieldIndex(0), - InitStorage(BW, (InitStorageKind) InitStyle) { - assert((!BW || InitStyle == ICIS_NoInit) && "got initializer for bitfield"); + BitField(false), Mutable(Mutable), CachedFieldIndex(0), + InitStorage(nullptr, (InitStorageKind) InitStyle) { + if (BW) + setBitWidth(BW); } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static FieldDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, @@ -2431,10 +2532,7 @@ public: bool isMutable() const { return Mutable; } /// \brief Determines whether this field is a bitfield. - bool isBitField() const { - return InitStorage.getInt() == ISK_BitWidthOrNothing && - InitStorage.getPointer() != nullptr; - } + bool isBitField() const { return BitField; } /// @brief Determines whether this is an unnamed bitfield. bool isUnnamedBitfield() const { return isBitField() && !getDeclName(); } @@ -2446,66 +2544,77 @@ public: bool isAnonymousStructOrUnion() const; Expr *getBitWidth() const { - return isBitField() - ? static_cast<Expr *>(InitStorage.getPointer()) - : nullptr; + if (!BitField) + return nullptr; + void *Ptr = InitStorage.getPointer(); + if (getInClassInitStyle()) + return static_cast<InitAndBitWidth*>(Ptr)->BitWidth; + return static_cast<Expr*>(Ptr); } + unsigned getBitWidthValue(const ASTContext &Ctx) const; /// setBitWidth - Set the bit-field width for this member. // Note: used by some clients (i.e., do not remove it). void setBitWidth(Expr *Width) { - assert(InitStorage.getInt() == ISK_BitWidthOrNothing && - InitStorage.getPointer() == nullptr && - "bit width, initializer or captured type already set"); - InitStorage.setPointerAndInt(Width, ISK_BitWidthOrNothing); + assert(!hasCapturedVLAType() && !BitField && + "bit width or captured type already set"); + assert(Width && "no bit width specified"); + InitStorage.setPointer( + InitStorage.getInt() + ? new (getASTContext()) + InitAndBitWidth{getInClassInitializer(), Width} + : static_cast<void*>(Width)); + BitField = true; } /// removeBitWidth - Remove the bit-field width from this member. // Note: used by some clients (i.e., do not remove it). void removeBitWidth() { assert(isBitField() && "no bitfield width to remove"); - InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing); + InitStorage.setPointer(getInClassInitializer()); + BitField = false; } - /// getInClassInitStyle - Get the kind of (C++11) in-class initializer which - /// this field has. + /// Get the kind of (C++11) default member initializer that this field has. InClassInitStyle getInClassInitStyle() const { InitStorageKind storageKind = InitStorage.getInt(); return (storageKind == ISK_CapturedVLAType ? ICIS_NoInit : (InClassInitStyle) storageKind); } - /// hasInClassInitializer - Determine whether this member has a C++11 in-class - /// initializer. + /// Determine whether this member has a C++11 default member initializer. bool hasInClassInitializer() const { return getInClassInitStyle() != ICIS_NoInit; } - /// getInClassInitializer - Get the C++11 in-class initializer for this - /// member, or null if one has not been set. If a valid declaration has an - /// in-class initializer, but this returns null, then we have not parsed and - /// attached it yet. + /// Get the C++11 default member initializer for this member, or null if one + /// has not been set. If a valid declaration has a default member initializer, + /// but this returns null, then we have not parsed and attached it yet. Expr *getInClassInitializer() const { - return hasInClassInitializer() - ? static_cast<Expr *>(InitStorage.getPointer()) - : nullptr; + if (!hasInClassInitializer()) + return nullptr; + void *Ptr = InitStorage.getPointer(); + if (BitField) + return static_cast<InitAndBitWidth*>(Ptr)->Init; + return static_cast<Expr*>(Ptr); } /// setInClassInitializer - Set the C++11 in-class initializer for this /// member. void setInClassInitializer(Expr *Init) { - assert(hasInClassInitializer() && - InitStorage.getPointer() == nullptr && - "bit width, initializer or captured type already set"); - InitStorage.setPointer(Init); + assert(hasInClassInitializer() && !getInClassInitializer()); + if (BitField) + static_cast<InitAndBitWidth*>(InitStorage.getPointer())->Init = Init; + else + InitStorage.setPointer(Init); } /// removeInClassInitializer - Remove the C++11 in-class initializer from this /// member. void removeInClassInitializer() { assert(hasInClassInitializer() && "no initializer to remove"); - InitStorage.setPointerAndInt(nullptr, ISK_BitWidthOrNothing); + InitStorage.setPointerAndInt(getBitWidth(), ISK_NoInit); } /// \brief Determine whether this member captures the variable length array @@ -2520,6 +2629,7 @@ public: InitStorage.getPointer()) : nullptr; } + /// \brief Set the captured variable length array type for this field. void setCapturedVLAType(const VariableArrayType *VLAType); @@ -2542,9 +2652,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstField && K <= lastField; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// EnumConstantDecl - An instance of this object exists for each enum constant @@ -2554,6 +2661,7 @@ public: class EnumConstantDecl : public ValueDecl, public Mergeable<EnumConstantDecl> { Stmt *Init; // an integer constant expression llvm::APSInt Val; // The value. + protected: EnumConstantDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, @@ -2561,6 +2669,7 @@ protected: : ValueDecl(EnumConstant, DC, L, Id, T), Init((Stmt*)E), Val(V) {} public: + friend class StmtIteratorBase; static EnumConstantDecl *Create(ASTContext &C, EnumDecl *DC, SourceLocation L, IdentifierInfo *Id, @@ -2584,8 +2693,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == EnumConstant; } - - friend class StmtIteratorBase; }; /// IndirectFieldDecl - An instance of this class is created to represent a @@ -2593,7 +2700,6 @@ public: /// IndirectFieldDecl are always implicit. class IndirectFieldDecl : public ValueDecl, public Mergeable<IndirectFieldDecl> { - void anchor() override; NamedDecl **Chaining; unsigned ChainingSize; @@ -2601,14 +2707,18 @@ class IndirectFieldDecl : public ValueDecl, DeclarationName N, QualType T, MutableArrayRef<NamedDecl *> CH); + void anchor() override; + public: + friend class ASTDeclReader; + static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, llvm::MutableArrayRef<NamedDecl *> CH); static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); - typedef ArrayRef<NamedDecl *>::const_iterator chain_iterator; + using chain_iterator = ArrayRef<NamedDecl *>::const_iterator; ArrayRef<NamedDecl *> chain() const { return llvm::makeArrayRef(Chaining, ChainingSize); @@ -2634,26 +2744,27 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == IndirectField; } - friend class ASTDeclReader; }; /// TypeDecl - Represents a declaration of a type. -/// class TypeDecl : public NamedDecl { - void anchor() override; + friend class ASTContext; + /// TypeForDecl - This indicates the Type object that represents /// this TypeDecl. It is a cache maintained by /// ASTContext::getTypedefType, ASTContext::getTagDeclType, and /// ASTContext::getTemplateTypeParmType, and TemplateTypeParmDecl. - mutable const Type *TypeForDecl; + mutable const Type *TypeForDecl = nullptr; + /// LocStart - The start of the source range for this declaration. SourceLocation LocStart; - friend class ASTContext; + + void anchor() override; protected: TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation StartL = SourceLocation()) - : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {} + : NamedDecl(DK, DC, L, Id), LocStart(StartL) {} public: // Low-level accessor. If you just want the type defined by this node, @@ -2677,18 +2788,18 @@ public: static bool classofKind(Kind K) { return K >= firstType && K <= lastType; } }; - /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> { - void anchor() override; - typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo; - llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo; + using ModedTInfo = std::pair<TypeSourceInfo *, QualType>; + llvm::PointerUnion<TypeSourceInfo *, ModedTInfo *> MaybeModedTInfo; // FIXME: This can be packed into the bitfields in Decl. /// If 0, we have not computed IsTransparentTag. /// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1). mutable unsigned CacheIsTransparentTag : 2; + void anchor() override; + protected: TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -2696,20 +2807,24 @@ protected: : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C), MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {} - typedef Redeclarable<TypedefNameDecl> redeclarable_base; + using redeclarable_base = Redeclarable<TypedefNameDecl>; + TypedefNameDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + TypedefNameDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + TypedefNameDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -2724,14 +2839,17 @@ public: ? MaybeModedTInfo.get<ModedTInfo*>()->first : MaybeModedTInfo.get<TypeSourceInfo*>(); } + QualType getUnderlyingType() const { return isModed() ? MaybeModedTInfo.get<ModedTInfo*>()->second : MaybeModedTInfo.get<TypeSourceInfo*>()->getType(); } + void setTypeSourceInfo(TypeSourceInfo *newType) { MaybeModedTInfo = newType; } + void setModedTypeSourceInfo(TypeSourceInfo *unmodedTSI, QualType modedTy) { MaybeModedTInfo = new (getASTContext()) ModedTInfo(unmodedTSI, modedTy); } @@ -2817,7 +2935,7 @@ class TagDecl : public TypeDecl, public DeclContext, public Redeclarable<TagDecl> { public: // This is really ugly. - typedef TagTypeKind TagKind; + using TagKind = TagTypeKind; private: // FIXME: This can be packed into the bitfields in Decl. @@ -2850,6 +2968,7 @@ protected: /// IsScoped - True if this tag declaration is a scoped enumeration. Only /// possible in C++11 mode. unsigned IsScoped : 1; + /// IsScopedUsingClassTag - If this tag declaration is a scoped enum, /// then this is true if the scoped enum was declared using the class /// tag, false if it was declared with the struct tag. No meaning is @@ -2869,12 +2988,13 @@ protected: /// Has the full definition of this type been required by a use somewhere in /// the TU. unsigned IsCompleteDefinitionRequired : 1; + private: SourceRange BraceRange; // A struct representing syntactic qualifier info, // to be used for the (uncommon) case of out-of-line declarations. - typedef QualifierInfo ExtInfo; + using ExtInfo = QualifierInfo; /// \brief If the (out-of-line) tag declaration name /// is qualified, it points to the qualifier info (nns and range); @@ -2906,13 +3026,16 @@ protected: setPreviousDecl(PrevDecl); } - typedef Redeclarable<TagDecl> redeclarable_base; + using redeclarable_base = Redeclarable<TagDecl>; + TagDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + TagDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + TagDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } @@ -2923,8 +3046,12 @@ protected: void completeDefinition(); public: - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -3074,10 +3201,12 @@ public: unsigned getNumTemplateParameterLists() const { return hasExtInfo() ? getExtInfo()->NumTemplParamLists : 0; } + TemplateParameterList *getTemplateParameterList(unsigned i) const { assert(i < getNumTemplateParameterLists()); return getExtInfo()->TemplParamLists[i]; } + void setTemplateParameterListsInfo(ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists); @@ -3088,19 +3217,16 @@ public: static DeclContext *castToDeclContext(const TagDecl *D) { return static_cast<DeclContext *>(const_cast<TagDecl*>(D)); } + static TagDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<TagDecl *>(const_cast<DeclContext*>(DC)); } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// EnumDecl - Represents an enum. In C++11, enums can be forward-declared /// with a fixed underlying type, and in C we allow them to be forward-declared /// with no underlying type as an extension. class EnumDecl : public TagDecl { - void anchor() override; /// IntegerType - This represent the integer type that the enum corresponds /// to for code generation purposes. Note that the enumerator constants may /// have a different type than this does. @@ -3115,8 +3241,7 @@ class EnumDecl : public TagDecl { /// The underlying type of an enumeration never has any qualifiers, so /// we can get away with just storing a raw Type*, and thus save an /// extra pointer when TypeSourceInfo is needed. - - llvm::PointerUnion<const Type*, TypeSourceInfo*> IntegerType; + llvm::PointerUnion<const Type *, TypeSourceInfo *> IntegerType; /// PromotionType - The integer type that values of this type should /// promote to. In C, enumerators are generally of an integer type @@ -3127,13 +3252,12 @@ class EnumDecl : public TagDecl { /// \brief If this enumeration is an instantiation of a member enumeration /// of a class template specialization, this is the member specialization /// information. - MemberSpecializationInfo *SpecializationInfo; + MemberSpecializationInfo *SpecializationInfo = nullptr; EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, bool Scoped, bool ScopedUsingClassTag, bool Fixed) - : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc), - SpecializationInfo(nullptr) { + : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) { assert(Scoped || !ScopedUsingClassTag); IntegerType = (const Type *)nullptr; NumNegativeBits = 0; @@ -3143,9 +3267,13 @@ class EnumDecl : public TagDecl { IsFixed = Fixed; } + void anchor() override; + void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, TemplateSpecializationKind TSK); public: + friend class ASTDeclReader; + EnumDecl *getCanonicalDecl() override { return cast<EnumDecl>(TagDecl::getCanonicalDecl()); } @@ -3191,9 +3319,9 @@ public: // enumerator_iterator - Iterates through the enumerators of this // enumeration. - typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator; - typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>> - enumerator_range; + using enumerator_iterator = specific_decl_iterator<EnumConstantDecl>; + using enumerator_range = + llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>; enumerator_range enumerators() const { return enumerator_range(enumerator_begin(), enumerator_end()); @@ -3341,17 +3469,15 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Enum; } - - friend class ASTDeclReader; }; - /// RecordDecl - Represents a struct/union/class. For example: /// struct X; // Forward declaration, no "body". /// union Y { int A, B; }; // Has body with members A and B (FieldDecls). /// This decl will be marked invalid if *any* members are invalid. -/// class RecordDecl : public TagDecl { + friend class DeclContext; + // FIXME: This can be packed into the bitfields in Decl. /// HasFlexibleArrayMember - This is true if this struct ends with a flexible /// array member (e.g. int X[]) or if this union contains a struct that does. @@ -3375,7 +3501,6 @@ class RecordDecl : public TagDecl { /// methods/nested types we allow deserialization of just the fields /// when needed. mutable bool LoadedFieldsFromExternalStorage : 1; - friend class DeclContext; protected: RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, @@ -3458,6 +3583,7 @@ public: /// \brief Determine whether this record is a record for captured variables in /// CapturedStmt construct. bool isCapturedRecord() const; + /// \brief Mark the record as a record for captured variables in CapturedStmt /// construct. void setCapturedRecord(); @@ -3477,8 +3603,8 @@ public: // Iterator access to field members. The field iterator only visits // the non-static data members of this class, ignoring any static // data members, functions, constructors, destructors, etc. - typedef specific_decl_iterator<FieldDecl> field_iterator; - typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range; + using field_iterator = specific_decl_iterator<FieldDecl>; + using field_range = llvm::iterator_range<specific_decl_iterator<FieldDecl>>; field_range fields() const { return field_range(field_begin(), field_end()); } field_iterator field_begin() const; @@ -3502,7 +3628,7 @@ public: return K >= firstRecord && K <= lastRecord; } - /// isMsStrust - Get whether or not this is an ms_struct which can + /// \brief Get whether or not this is an ms_struct which can /// be turned on with an attribute, pragma, or -mms-bitfields /// commandline option. bool isMsStruct(const ASTContext &C) const; @@ -3522,12 +3648,15 @@ private: }; class FileScopeAsmDecl : public Decl { - virtual void anchor(); StringLiteral *AsmString; SourceLocation RParenLoc; + FileScopeAsmDecl(DeclContext *DC, StringLiteral *asmstring, SourceLocation StartL, SourceLocation EndL) : Decl(FileScopeAsm, DC, StartL), AsmString(asmstring), RParenLoc(EndL) {} + + virtual void anchor(); + public: static FileScopeAsmDecl *Create(ASTContext &C, DeclContext *DC, StringLiteral *Str, SourceLocation AsmLoc, @@ -3553,7 +3682,6 @@ public: /// BlockDecl - This represents a block literal declaration, which is like an /// unnamed FunctionDecl. For example: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } -/// class BlockDecl : public Decl, public DeclContext { public: /// A class which contains all the information about a particular @@ -3600,29 +3728,27 @@ private: bool CapturesCXXThis : 1; bool BlockMissingReturnType : 1; bool IsConversionFromLambda : 1; + /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal /// parameters of this function. This is null if a prototype or if there are /// no formals. - ParmVarDecl **ParamInfo; - unsigned NumParams; + ParmVarDecl **ParamInfo = nullptr; + unsigned NumParams = 0; - Stmt *Body; - TypeSourceInfo *SignatureAsWritten; + Stmt *Body = nullptr; + TypeSourceInfo *SignatureAsWritten = nullptr; - const Capture *Captures; - unsigned NumCaptures; + const Capture *Captures = nullptr; + unsigned NumCaptures = 0; - unsigned ManglingNumber; - Decl *ManglingContextDecl; + unsigned ManglingNumber = 0; + Decl *ManglingContextDecl = nullptr; protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) - : Decl(Block, DC, CaretLoc), DeclContext(Block), - IsVariadic(false), CapturesCXXThis(false), - BlockMissingReturnType(true), IsConversionFromLambda(false), - ParamInfo(nullptr), NumParams(0), Body(nullptr), - SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0), - ManglingNumber(0), ManglingContextDecl(nullptr) {} + : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), + CapturesCXXThis(false), BlockMissingReturnType(true), + IsConversionFromLambda(false) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -3649,8 +3775,9 @@ public: } // Iterator access to formal parameters. - typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator; - typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator; + using param_iterator = MutableArrayRef<ParmVarDecl *>::iterator; + using param_const_iterator = ArrayRef<ParmVarDecl *>::const_iterator; + bool param_empty() const { return parameters().empty(); } param_iterator param_begin() { return parameters().begin(); } param_iterator param_end() { return parameters().end(); } @@ -3659,6 +3786,7 @@ public: size_t param_size() const { return parameters().size(); } unsigned getNumParams() const { return NumParams; } + const ParmVarDecl *getParamDecl(unsigned i) const { assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; @@ -3667,6 +3795,7 @@ public: assert(i < getNumParams() && "Illegal param #"); return ParamInfo[i]; } + void setParams(ArrayRef<ParmVarDecl *> NewParamInfo); /// hasCaptures - True if this block (or its nested blocks) captures @@ -3677,7 +3806,7 @@ public: /// Does not include an entry for 'this'. unsigned getNumCaptures() const { return NumCaptures; } - typedef ArrayRef<Capture>::const_iterator capture_const_iterator; + using capture_const_iterator = ArrayRef<Capture>::const_iterator; ArrayRef<Capture> captures() const { return {Captures, NumCaptures}; } @@ -3699,6 +3828,7 @@ public: unsigned getBlockManglingNumber() const { return ManglingNumber; } + Decl *getBlockManglingContextDecl() const { return ManglingContextDecl; } @@ -3735,8 +3865,10 @@ protected: private: /// \brief The number of parameters to the outlined function. unsigned NumParams; + /// \brief The position of context parameter in list of parameters. unsigned ContextParam; + /// \brief The body of the outlined function. llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow; @@ -3751,6 +3883,10 @@ private: } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend TrailingObjects; + static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, @@ -3793,8 +3929,8 @@ public: } unsigned getContextParamPosition() const { return ContextParam; } - typedef ImplicitParamDecl *const *param_iterator; - typedef llvm::iterator_range<param_iterator> param_range; + using param_iterator = ImplicitParamDecl *const *; + using param_range = llvm::iterator_range<param_iterator>; /// \brief Retrieve an iterator pointing to the first parameter decl. param_iterator param_begin() const { return getParams(); } @@ -3810,10 +3946,6 @@ public: static CapturedDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<CapturedDecl *>(const_cast<DeclContext *>(DC)); } - - friend class ASTDeclReader; - friend class ASTDeclWriter; - friend TrailingObjects; }; /// \brief Describes a module import declaration, which makes the contents @@ -3828,6 +3960,11 @@ public: /// \#include/\#import directives. class ImportDecl final : public Decl, llvm::TrailingObjects<ImportDecl, SourceLocation> { + friend class ASTContext; + friend class ASTDeclReader; + friend class ASTReader; + friend TrailingObjects; + /// \brief The imported module, along with a bit that indicates whether /// we have source-location information for each identifier in the module /// name. @@ -3838,20 +3975,15 @@ class ImportDecl final : public Decl, /// \brief The next import in the list of imports local to the translation /// unit being parsed (not loaded from an AST file). - ImportDecl *NextLocalImport; + ImportDecl *NextLocalImport = nullptr; - friend class ASTReader; - friend class ASTDeclReader; - friend class ASTContext; - friend TrailingObjects; - ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef<SourceLocation> IdentifierLocs); ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc); - ImportDecl(EmptyShell Empty) : Decl(Import, Empty), NextLocalImport() { } + ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {} public: /// \brief Create a new module import declaration. @@ -3893,15 +4025,16 @@ public: /// \endcode class ExportDecl final : public Decl, public DeclContext { virtual void anchor(); + private: + friend class ASTDeclReader; + /// \brief The source location for the right brace (if valid). SourceLocation RBraceLoc; ExportDecl(DeclContext *DC, SourceLocation ExportLoc) - : Decl(Export, DC, ExportLoc), DeclContext(Export), - RBraceLoc(SourceLocation()) { } - - friend class ASTDeclReader; + : Decl(Export, DC, ExportLoc), DeclContext(Export), + RBraceLoc(SourceLocation()) {} public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, @@ -3936,9 +4069,9 @@ public: /// \brief Represents an empty-declaration. class EmptyDecl : public Decl { + EmptyDecl(DeclContext *DC, SourceLocation L) : Decl(Empty, DC, L) {} + virtual void anchor(); - EmptyDecl(DeclContext *DC, SourceLocation L) - : Decl(Empty, DC, L) { } public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, @@ -4015,6 +4148,6 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) { return ED->isScoped(); } -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DECL_H diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 041f0fd484d4..f93c9f0b9aaa 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1,4 +1,4 @@ -//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===// +//===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,33 +16,40 @@ #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <iterator> +#include <string> +#include <type_traits> +#include <utility> namespace clang { + +class ASTContext; class ASTMutationListener; -class BlockDecl; -class CXXRecordDecl; -class CompoundStmt; +class Attr; class DeclContext; -class DeclarationName; -class DependentDiagnostic; -class EnumDecl; -class ExportDecl; class ExternalSourceSymbolAttr; class FunctionDecl; class FunctionType; +class IdentifierInfo; enum Linkage : unsigned char; -class LinkageComputer; class LinkageSpecDecl; class Module; class NamedDecl; -class NamespaceDecl; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCContainerDecl; @@ -53,23 +60,21 @@ class ObjCMethodDecl; class ObjCProtocolDecl; struct PrintingPolicy; class RecordDecl; +class SourceManager; class Stmt; class StoredDeclsMap; class TemplateDecl; class TranslationUnitDecl; class UsingDirectiveDecl; -} - -namespace clang { - /// \brief Captures the result of checking the availability of a - /// declaration. - enum AvailabilityResult { - AR_Available = 0, - AR_NotYetIntroduced, - AR_Deprecated, - AR_Unavailable - }; +/// \brief Captures the result of checking the availability of a +/// declaration. +enum AvailabilityResult { + AR_Available = 0, + AR_NotYetIntroduced, + AR_Deprecated, + AR_Unavailable +}; /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. @@ -94,7 +99,7 @@ public: /// \brief A placeholder type used to construct an empty shell of a /// decl-derived type that will be filled in later (e.g., by some /// deserialization method). - struct EmptyShell { }; + struct EmptyShell {}; /// IdentifierNamespace - The different namespaces in which /// declarations may appear. According to C99 6.2.3, there are @@ -208,15 +213,18 @@ public: enum class ModuleOwnershipKind : unsigned { /// This declaration is not owned by a module. Unowned, + /// This declaration has an owning module, but is globally visible /// (typically because its owning module is visible and we know that /// modules cannot later become hidden in this compilation). /// After serialization and deserialization, this will be converted /// to VisibleWhenImported. Visible, + /// This declaration has an owning module, and is visible when that /// module is imported. VisibleWhenImported, + /// This declaration has an owning module, but is only visible to /// lookups that occur within that module. ModulePrivate @@ -238,7 +246,6 @@ private: DeclContext *LexicalDC; }; - /// DeclCtx - Holds either a DeclContext* or a MultipleDC*. /// For declarations that don't contain C++ scope specifiers, it contains /// the DeclContext where the Decl was declared. @@ -254,12 +261,14 @@ private: /// // LexicalDC == global namespace llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; - inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } - inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } - inline MultipleDC *getMultipleDC() const { + bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } + bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } + + MultipleDC *getMultipleDC() const { return DeclCtx.get<MultipleDC*>(); } - inline DeclContext *getSemanticDC() const { + + DeclContext *getSemanticDC() const { return DeclCtx.get<DeclContext*>(); } @@ -298,10 +307,16 @@ private: static bool StatisticsEnabled; protected: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; + friend class CXXClassMemberWrapper; + friend class LinkageComputer; + template<typename decl_type> friend class Redeclarable; + /// Access - Used by C++ decls for the access specifier. // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum unsigned Access : 2; - friend class CXXClassMemberWrapper; /// \brief Whether this declaration was loaded from an AST file. unsigned FromASTFile : 1; @@ -313,13 +328,6 @@ protected: /// Otherwise, it is the linkage + 1. mutable unsigned CacheValidAndLinkage : 3; - friend class ASTDeclWriter; - friend class ASTDeclReader; - friend class ASTReader; - friend class LinkageComputer; - - template<typename decl_type> friend class Redeclarable; - /// \brief Allocate memory for a deserialized declaration. /// /// This routine must be used to allocate memory for any declaration that is @@ -357,7 +365,7 @@ private: protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), - DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), + DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), @@ -366,9 +374,9 @@ protected: } Decl(Kind DK, EmptyShell Empty) - : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false), - Implicit(false), Used(false), Referenced(false), - TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), + : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), + Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), + Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); @@ -392,14 +400,15 @@ protected: } public: - /// \brief Source range that this declaration covers. virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocation(), getLocation()); } + SourceLocation getLocStart() const LLVM_READONLY { return getSourceRange().getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getSourceRange().getEnd(); } @@ -460,12 +469,15 @@ public: } bool hasAttrs() const { return HasAttrs; } + void setAttrs(const AttrVec& Attrs) { return setAttrsImpl(Attrs, getASTContext()); } + AttrVec &getAttrs() { return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs()); } + const AttrVec &getAttrs() const; void dropAttrs(); @@ -476,8 +488,8 @@ public: setAttrs(AttrVec(1, A)); } - typedef AttrVec::const_iterator attr_iterator; - typedef llvm::iterator_range<attr_iterator> attr_range; + using attr_iterator = AttrVec::const_iterator; + using attr_range = llvm::iterator_range<attr_iterator>; attr_range attrs() const { return attr_range(attr_begin(), attr_end()); @@ -510,6 +522,7 @@ public: specific_attr_iterator<T> specific_attr_begin() const { return specific_attr_iterator<T>(attr_begin()); } + template <typename T> specific_attr_iterator<T> specific_attr_end() const { return specific_attr_iterator<T>(attr_end()); @@ -518,6 +531,7 @@ public: template<typename T> T *getAttr() const { return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr; } + template<typename T> bool hasAttr() const { return hasAttrs() && hasSpecificAttr<T>(getAttrs()); } @@ -616,7 +630,6 @@ protected: } public: - /// \brief Determine the availability of the given declaration. /// /// This routine will determine the most restrictive availability of @@ -698,6 +711,7 @@ public: private: Module *getOwningModuleSlow() const; + protected: bool hasLocalOwningModuleStorage() const; @@ -733,11 +747,18 @@ public: return getModuleOwnershipKind() != ModuleOwnershipKind::Unowned; } - /// Get the module that owns this declaration. + /// Get the module that owns this declaration (for visibility purposes). Module *getOwningModule() const { return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule(); } + /// Get the module that owns this declaration for linkage purposes. + /// There only ever is such a module under the C++ Modules TS. + /// + /// \param IgnoreLinkage Ignore the linkage of the entity; assume that + /// all declarations in a global module fragment are unowned. + Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const; + /// \brief Determine whether this declaration might be hidden from name /// lookup. Note that the declaration might be visible even if this returns /// \c false, if the owning module is visible within the query context. @@ -770,14 +791,17 @@ public: unsigned getIdentifierNamespace() const { return IdentifierNamespace; } + bool isInIdentifierNamespace(unsigned NS) const { return getIdentifierNamespace() & NS; } + static unsigned getIdentifierNamespaceForKind(Kind DK); bool hasTagIdentifierNamespace() const { return isTagIdentifierNamespace(getIdentifierNamespace()); } + static bool isTagIdentifierNamespace(unsigned NS) { // TagDecls have Tag and Type set and may also have TagFriend. return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type); @@ -865,18 +889,18 @@ public: /// \brief Iterates through all the redeclarations of the same decl. class redecl_iterator { /// Current - The current declaration. - Decl *Current; + Decl *Current = nullptr; Decl *Starter; public: - typedef Decl *value_type; - typedef const value_type &reference; - typedef const value_type *pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = Decl *; + using reference = const value_type &; + using pointer = const value_type *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - redecl_iterator() : Current(nullptr) { } - explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { } + redecl_iterator() = default; + explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {} reference operator*() const { return Current; } value_type operator->() const { return Current; } @@ -899,12 +923,13 @@ public: friend bool operator==(redecl_iterator x, redecl_iterator y) { return x.Current == y.Current; } + friend bool operator!=(redecl_iterator x, redecl_iterator y) { return x.Current != y.Current; } }; - typedef llvm::iterator_range<redecl_iterator> redecl_range; + using redecl_range = llvm::iterator_range<redecl_iterator>; /// \brief Returns an iterator range for all the redeclarations of the same /// decl. It will iterate at least once (when this decl is the only one). @@ -915,6 +940,7 @@ public: redecl_iterator redecls_begin() const { return redecl_iterator(const_cast<Decl *>(this)); } + redecl_iterator redecls_end() const { return redecl_iterator(); } /// \brief Retrieve the previous declaration that declares the same entity @@ -1002,13 +1028,15 @@ public: /// declaration, but in the semantic context of the enclosing namespace /// scope. void setLocalExternDecl() { - assert((IdentifierNamespace == IDNS_Ordinary || - IdentifierNamespace == IDNS_OrdinaryFriend) && - "namespace is not ordinary"); - Decl *Prev = getPreviousDecl(); IdentifierNamespace &= ~IDNS_Ordinary; + // It's OK for the declaration to still have the "invisible friend" flag or + // the "conflicts with tag declarations in this scope" flag for the outer + // scope. + assert((IdentifierNamespace & ~(IDNS_OrdinaryFriend | IDNS_Tag)) == 0 && + "namespace is not ordinary"); + IdentifierNamespace |= IDNS_LocalExtern; if (Prev && Prev->getIdentifierNamespace() & IDNS_Ordinary) IdentifierNamespace |= IDNS_Ordinary; @@ -1094,10 +1122,13 @@ public: static void printGroup(Decl** Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); + // Debuggers don't usually respect default arguments. void dump() const; + // Same as dump(), but forces color printing. void dumpColor() const; + void dump(raw_ostream &Out, bool Deserialize = false) const; /// \brief Looks through the Decl's underlying type to extract a FunctionType @@ -1132,10 +1163,11 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { SourceLocation Loc; SourceManager &SM; const char *Message; + public: PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, SourceManager &sm, const char *Msg) - : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} + : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} void print(raw_ostream &OS) const override; }; @@ -1144,30 +1176,35 @@ public: /// 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; + using ResultTy = ArrayRef<NamedDecl *>; + 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; + NamedDecl *Single = nullptr; static NamedDecl *const SingleElementDummyList; public: - DeclContextLookupResult() : Result(), Single() {} + DeclContextLookupResult() = default; DeclContextLookupResult(ArrayRef<NamedDecl *> Result) - : Result(Result), Single() {} + : Result(Result) {} 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; + + using IteratorBase = + llvm::iterator_adaptor_base<iterator, ResultTy::iterator, + std::random_access_iterator_tag, + NamedDecl *const>; + class iterator : public IteratorBase { value_type SingleElement; public: - iterator() : IteratorBase(), SingleElement() {} + iterator() = default; explicit iterator(pointer Pos, value_type Single = nullptr) : IteratorBase(Pos), SingleElement(Single) {} @@ -1175,9 +1212,10 @@ public: return SingleElement ? SingleElement : IteratorBase::operator*(); } }; - typedef iterator const_iterator; - typedef iterator::pointer pointer; - typedef iterator::reference reference; + + using const_iterator = iterator; + using pointer = iterator::pointer; + using reference = iterator::reference; iterator begin() const { return iterator(Result.begin(), Single); } iterator end() const { return iterator(Result.end(), Single); } @@ -1211,7 +1249,6 @@ public: /// ExportDecl /// BlockDecl /// OMPDeclareReductionDecl -/// class DeclContext { /// DeclKind - This indicates which class this is. unsigned DeclKind : 8; @@ -1251,22 +1288,22 @@ class DeclContext { /// 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; + mutable StoredDeclsMap *LookupPtr = nullptr; protected: + friend class ASTDeclReader; + friend class ASTWriter; + friend class ExternalASTSource; + /// FirstDecl - The first declaration stored within this declaration /// context. - mutable Decl *FirstDecl; + mutable Decl *FirstDecl = nullptr; /// LastDecl - The last declaration stored within this declaration /// context. FIXME: We could probably cache this value somewhere /// outside of the DeclContext, to reduce the size of DeclContext by /// another pointer. - mutable Decl *LastDecl; - - friend class ExternalASTSource; - friend class ASTDeclReader; - friend class ASTWriter; + mutable Decl *LastDecl = nullptr; /// \brief Build up a chain of declarations. /// @@ -1279,8 +1316,7 @@ protected: ExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), - UseQualifiedLookup(false), - LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {} + UseQualifiedLookup(false) {} public: ~DeclContext(); @@ -1288,6 +1324,7 @@ public: Decl::Kind getDeclKind() const { return static_cast<Decl::Kind>(DeclKind); } + const char *getDeclKindName() const; /// getParent - Returns the containing DeclContext. @@ -1495,19 +1532,20 @@ public: /// within this context. class decl_iterator { /// Current - The current declaration. - Decl *Current; + Decl *Current = nullptr; public: - typedef Decl *value_type; - typedef const value_type &reference; - typedef const value_type *pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = Decl *; + using reference = const value_type &; + using pointer = const value_type *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - decl_iterator() : Current(nullptr) { } - explicit decl_iterator(Decl *C) : Current(C) { } + decl_iterator() = default; + explicit decl_iterator(Decl *C) : Current(C) {} reference operator*() const { return Current; } + // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return Current; } @@ -1525,12 +1563,13 @@ public: friend bool operator==(decl_iterator x, decl_iterator y) { return x.Current == y.Current; } + friend bool operator!=(decl_iterator x, decl_iterator y) { return x.Current != y.Current; } }; - typedef llvm::iterator_range<decl_iterator> decl_range; + using decl_range = llvm::iterator_range<decl_iterator>; /// decls_begin/decls_end - Iterate over the declarations stored in /// this context. @@ -1569,16 +1608,16 @@ public: } public: - typedef SpecificDecl *value_type; - // TODO: Add reference and pointer typedefs (with some appropriate proxy - // type) if we ever have a need for them. - typedef void reference; - typedef void pointer; - typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = SpecificDecl *; + // TODO: Add reference and pointer types (with some appropriate proxy type) + // if we ever have a need for them. + using reference = void; + using pointer = void; + using difference_type = + std::iterator_traits<DeclContext::decl_iterator>::difference_type; + using iterator_category = std::forward_iterator_tag; - specific_decl_iterator() : Current() { } + specific_decl_iterator() = default; /// specific_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -1593,6 +1632,7 @@ public: } value_type operator*() const { return cast<SpecificDecl>(*Current); } + // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return **this; } @@ -1646,16 +1686,16 @@ public: } public: - typedef SpecificDecl *value_type; - // TODO: Add reference and pointer typedefs (with some appropriate proxy - // type) if we ever have a need for them. - typedef void reference; - typedef void pointer; - typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = SpecificDecl *; + // TODO: Add reference and pointer types (with some appropriate proxy type) + // if we ever have a need for them. + using reference = void; + using pointer = void; + using difference_type = + std::iterator_traits<DeclContext::decl_iterator>::difference_type; + using iterator_category = std::forward_iterator_tag; - filtered_decl_iterator() : Current() { } + filtered_decl_iterator() = default; /// filtered_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -1733,8 +1773,8 @@ public: /// @brief Checks whether a declaration is in this context. bool containsDecl(Decl *D) const; - typedef DeclContextLookupResult lookup_result; - typedef lookup_result::iterator lookup_iterator; + using lookup_result = DeclContextLookupResult; + using lookup_iterator = lookup_result::iterator; /// lookup - Find the declarations (if any) with the given Name in /// this context. Returns a range of iterators that contains all of @@ -1780,7 +1820,7 @@ public: /// of looking up every possible name. class all_lookups_iterator; - typedef llvm::iterator_range<all_lookups_iterator> lookups_range; + using lookups_range = llvm::iterator_range<all_lookups_iterator>; lookups_range lookups() const; lookups_range noload_lookups() const; @@ -1796,21 +1836,26 @@ public: all_lookups_iterator noload_lookups_end() const; struct udir_iterator; - typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, - std::random_access_iterator_tag, - UsingDirectiveDecl *> udir_iterator_base; + + using udir_iterator_base = + llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, + std::random_access_iterator_tag, + UsingDirectiveDecl *>; + 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; + using udir_range = llvm::iterator_range<udir_iterator>; udir_range using_directives() const; // These are all defined in DependentDiagnostic.h. class ddiag_iterator; - typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range; + + using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>; inline ddiag_range ddiags() const; @@ -1883,6 +1928,8 @@ public: bool Deserialize = false) const; private: + friend class DependentDiagnostic; + void reconcileExternalVisibleStorage() const; bool LoadLexicalDeclsFromExternalStorage() const; @@ -1894,7 +1941,6 @@ private: /// use of addDeclInternal(). void makeDeclVisibleInContextInternal(NamedDecl *D); - friend class DependentDiagnostic; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; void buildLookupImpl(DeclContext *DCtx, bool Internal); @@ -1933,8 +1979,7 @@ struct cast_convert_decl_context<ToTy, true> { } }; - -} // end clang. +} // namespace clang namespace llvm { @@ -1954,12 +1999,14 @@ struct cast_convert_val<ToTy, return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> { static ToTy &doit(::clang::DeclContext &Val) { return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, const ::clang::DeclContext*, const ::clang::DeclContext*> { @@ -1967,6 +2014,7 @@ struct cast_convert_val<ToTy, return ::clang::cast_convert_decl_context<ToTy>::doit(Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> { static ToTy *doit(::clang::DeclContext *Val) { @@ -2003,6 +2051,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> { } }; -} // end namespace llvm +} // namespace llvm -#endif +#endif // LLVM_CLANG_AST_DECLBASE_H diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 2f735c5506c4..88dc9a655917 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -1,4 +1,4 @@ -//===-- DeclCXX.h - Classes for representing C++ declarations -*- C++ -*-=====// +//===- DeclCXX.h - Classes for representing C++ declarations --*- C++ -*-=====// // // The LLVM Compiler Infrastructure // @@ -6,11 +6,11 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the C++ Decl subclasses, other than those for templates /// (found in DeclTemplate.h) and friends (in DeclFriend.h). -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLCXX_H @@ -20,29 +20,56 @@ #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExternalASTSource.h" #include "clang/AST/LambdaCapture.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/Redeclarable.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" +#include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/Lambda.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <cstddef> +#include <iterator> +#include <memory> +#include <vector> namespace clang { class ClassTemplateDecl; -class ClassTemplateSpecializationDecl; class ConstructorUsingShadowDecl; class CXXBasePath; class CXXBasePaths; class CXXConstructorDecl; -class CXXConversionDecl; class CXXDestructorDecl; -class CXXMethodDecl; -class CXXRecordDecl; -class CXXMemberLookupCriteria; class CXXFinalOverriderMap; class CXXIndirectPrimaryBaseSet; +class CXXMethodDecl; +class DiagnosticBuilder; class FriendDecl; -class LambdaExpr; +class FunctionTemplateDecl; +class IdentifierInfo; +class MemberSpecializationInfo; +class TemplateDecl; +class TemplateParameterList; class UsingDecl; /// \brief Represents any kind of function declaration, whether it is a @@ -50,10 +77,10 @@ class UsingDecl; class AnyFunctionDecl { NamedDecl *Function; - AnyFunctionDecl(NamedDecl *ND) : Function(ND) { } + AnyFunctionDecl(NamedDecl *ND) : Function(ND) {} public: - AnyFunctionDecl(FunctionDecl *FD) : Function(FD) { } + AnyFunctionDecl(FunctionDecl *FD) : Function(FD) {} AnyFunctionDecl(FunctionTemplateDecl *FTD); /// \brief Implicily converts any function or function template into a @@ -68,17 +95,18 @@ public: } }; -} // end namespace clang +} // namespace clang namespace llvm { + // Provide PointerLikeTypeTraits for non-cvr pointers. template<> - class PointerLikeTypeTraits< ::clang::AnyFunctionDecl> { - public: - static inline void *getAsVoidPointer(::clang::AnyFunctionDecl F) { + struct PointerLikeTypeTraits< ::clang::AnyFunctionDecl> { + static void *getAsVoidPointer(::clang::AnyFunctionDecl F) { return F.get(); } - static inline ::clang::AnyFunctionDecl getFromVoidPointer(void *P) { + + static ::clang::AnyFunctionDecl getFromVoidPointer(void *P) { return ::clang::AnyFunctionDecl::getFromNamedDecl( static_cast< ::clang::NamedDecl*>(P)); } @@ -86,7 +114,7 @@ namespace llvm { enum { NumLowBitsAvailable = 2 }; }; -} // end namespace llvm +} // namespace llvm namespace clang { @@ -101,7 +129,6 @@ namespace clang { /// Also note that this class has nothing to do with so-called /// "access declarations" (C++98 11.3 [class.access.dcl]). class AccessSpecDecl : public Decl { - virtual void anchor(); /// \brief The location of the ':'. SourceLocation ColonLoc; @@ -110,16 +137,21 @@ class AccessSpecDecl : public Decl { : Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) { setAccess(AS); } - AccessSpecDecl(EmptyShell Empty) - : Decl(AccessSpec, Empty) { } + + AccessSpecDecl(EmptyShell Empty) : Decl(AccessSpec, Empty) {} + + virtual void anchor(); + public: /// \brief The location of the access specifier. SourceLocation getAccessSpecifierLoc() const { return getLocation(); } + /// \brief Sets the location of the access specifier. void setAccessSpecifierLoc(SourceLocation ASLoc) { setLocation(ASLoc); } /// \brief The location of the colon following the access specifier. SourceLocation getColonLoc() const { return ColonLoc; } + /// \brief Sets the location of the colon. void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; } @@ -132,6 +164,7 @@ public: SourceLocation ColonLoc) { return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } + static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); // Implement isa/cast/dyncast/etc. @@ -191,12 +224,11 @@ class CXXBaseSpecifier { TypeSourceInfo *BaseTypeInfo; public: - CXXBaseSpecifier() { } - + CXXBaseSpecifier() = default; CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A, TypeSourceInfo *TInfo, SourceLocation EllipsisLoc) : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC), - Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { } + Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) {} /// \brief Retrieves the source range that contains the entire base specifier. SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -265,7 +297,16 @@ public: /// \brief Represents a C++ struct/union/class. class CXXRecordDecl : public RecordDecl { + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTNodeImporter; + friend class ASTReader; + friend class ASTRecordWriter; + friend class ASTWriter; + friend class DeclContext; + friend class LambdaExpr; + friend void FunctionDecl::setPure(bool); friend void TagDecl::startDefinition(); /// Values used in DefinitionData fields to represent special members. @@ -280,8 +321,6 @@ class CXXRecordDecl : public RecordDecl { }; struct DefinitionData { - DefinitionData(CXXRecordDecl *D); - /// \brief True if this class has any user-declared constructors. unsigned UserDeclaredConstructor : 1; @@ -475,13 +514,13 @@ class CXXRecordDecl : public RecordDecl { unsigned HasODRHash : 1; /// \brief A hash of parts of the class to help in ODR checking. - unsigned ODRHash; + unsigned ODRHash = 0; /// \brief The number of base class specifiers in Bases. - unsigned NumBases; + unsigned NumBases = 0; /// \brief The number of virtual base class specifiers in VBases. - unsigned NumVBases; + unsigned NumVBases = 0; /// \brief Base classes of this class. /// @@ -513,6 +552,8 @@ class CXXRecordDecl : public RecordDecl { /// This is actually currently stored in reverse order. LazyDeclPtr FirstFriend; + DefinitionData(CXXRecordDecl *D); + /// \brief Retrieve the set of direct base classes. CXXBaseSpecifier *getBases() const { if (!Bases.isOffset()) @@ -530,6 +571,7 @@ class CXXRecordDecl : public RecordDecl { ArrayRef<CXXBaseSpecifier> bases() const { return llvm::makeArrayRef(getBases(), NumBases); } + ArrayRef<CXXBaseSpecifier> vbases() const { return llvm::makeArrayRef(getVBases(), NumVBases); } @@ -543,22 +585,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief Describes a C++ closure type (generated by a lambda expression). struct LambdaDefinitionData : public DefinitionData { - typedef LambdaCapture Capture; - - LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, - bool Dependent, bool IsGeneric, - LambdaCaptureDefault CaptureDefault) - : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), - CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), - ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr), - MethodTyInfo(Info) { - IsLambda = true; - - // C++1z [expr.prim.lambda]p4: - // This class type is not an aggregate type. - Aggregate = false; - PlainOldData = false; - } + using Capture = LambdaCapture; /// \brief Whether this lambda is known to be dependent, even if its /// context isn't dependent. @@ -584,7 +611,7 @@ class CXXRecordDecl : public RecordDecl { /// \brief The number used to indicate this lambda expression for name /// mangling in the Itanium C++ ABI. - unsigned ManglingNumber; + unsigned ManglingNumber = 0; /// \brief The declaration that provides context for this lambda, if the /// actual DeclContext does not suffice. This is used for lambdas that @@ -594,11 +621,24 @@ class CXXRecordDecl : public RecordDecl { /// \brief The list of captures, both explicit and implicit, for this /// lambda. - Capture *Captures; + Capture *Captures = nullptr; /// \brief The type of the call method. TypeSourceInfo *MethodTyInfo; - + + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, + bool Dependent, bool IsGeneric, + LambdaCaptureDefault CaptureDefault) + : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), + CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), + MethodTyInfo(Info) { + IsLambda = true; + + // C++1z [expr.prim.lambda]p4: + // This class type is not an aggregate type. + Aggregate = false; + PlainOldData = false; + } }; struct DefinitionData *dataPtr() const { @@ -630,11 +670,8 @@ class CXXRecordDecl : public RecordDecl { /// classes of class template specializations, this will be the /// MemberSpecializationInfo referring to the member class that was /// instantiated or specialized. - llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*> - TemplateOrInstantiation; - - friend class DeclContext; - friend class LambdaExpr; + llvm::PointerUnion<ClassTemplateDecl *, MemberSpecializationInfo *> + TemplateOrInstantiation; /// \brief Called from setBases and addedMember to notify the class that a /// direct or virtual base class or a member of class type has been added. @@ -648,9 +685,6 @@ class CXXRecordDecl : public RecordDecl { void addedMember(Decl *D); void markedVirtualFunctionPure(); - friend void FunctionDecl::setPure(bool); - - friend class ASTNodeImporter; /// \brief Get the head of our list of friend declarations, possibly /// deserializing the friends from an external AST source. @@ -663,14 +697,15 @@ protected: public: /// \brief Iterator that traverses the base classes of a class. - typedef CXXBaseSpecifier* base_class_iterator; + using base_class_iterator = CXXBaseSpecifier *; /// \brief Iterator that traverses the base classes of a class. - typedef const CXXBaseSpecifier* base_class_const_iterator; + using base_class_const_iterator = const CXXBaseSpecifier *; CXXRecordDecl *getCanonicalDecl() override { return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl()); } + const CXXRecordDecl *getCanonicalDecl() const { return const_cast<CXXRecordDecl*>(this)->getCanonicalDecl(); } @@ -679,6 +714,7 @@ public: return cast_or_null<CXXRecordDecl>( static_cast<RecordDecl *>(this)->getPreviousDecl()); } + const CXXRecordDecl *getPreviousDecl() const { return const_cast<CXXRecordDecl*>(this)->getPreviousDecl(); } @@ -730,9 +766,9 @@ public: /// \brief Retrieves the number of base classes of this class. unsigned getNumBases() const { return data().NumBases; } - typedef llvm::iterator_range<base_class_iterator> base_class_range; - typedef llvm::iterator_range<base_class_const_iterator> - base_class_const_range; + using base_class_range = llvm::iterator_range<base_class_iterator>; + using base_class_const_range = + llvm::iterator_range<base_class_const_iterator>; base_class_range bases() { return base_class_range(bases_begin(), bases_end()); @@ -772,9 +808,9 @@ public: /// Iterator access to method members. The method iterator visits /// all method members of the class, including non-instance methods, /// special methods, etc. - typedef specific_decl_iterator<CXXMethodDecl> method_iterator; - typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>> - method_range; + using method_iterator = specific_decl_iterator<CXXMethodDecl>; + using method_range = + llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>; method_range methods() const { return method_range(method_begin(), method_end()); @@ -785,21 +821,23 @@ public: method_iterator method_begin() const { return method_iterator(decls_begin()); } + /// \brief Method past-the-end iterator. method_iterator method_end() const { return method_iterator(decls_end()); } /// Iterator access to constructor members. - typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator; - typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>> - ctor_range; + using ctor_iterator = specific_decl_iterator<CXXConstructorDecl>; + using ctor_range = + llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>; ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); } ctor_iterator ctor_begin() const { return ctor_iterator(decls_begin()); } + ctor_iterator ctor_end() const { return ctor_iterator(decls_end()); } @@ -807,7 +845,7 @@ public: /// An iterator over friend declarations. All of these are defined /// in DeclFriend.h. class friend_iterator; - typedef llvm::iterator_range<friend_iterator> friend_range; + using friend_range = llvm::iterator_range<friend_iterator>; friend_range friends() const; friend_iterator friend_begin() const; @@ -839,7 +877,10 @@ public: /// \brief \c true if a defaulted destructor for this class would be deleted. bool defaultedDestructorIsDeleted() const { - return !data().DefaultedDestructorIsDeleted; + assert((!needsOverloadResolutionForDestructor() || + (data().DeclaredSpecialMembers & SMF_Destructor)) && + "this property has not yet been computed by Sema"); + return data().DefaultedDestructorIsDeleted; } /// \brief \c true if we know for sure that this class has a single, @@ -986,6 +1027,15 @@ public: data().DefaultedMoveConstructorIsDeleted = true; } + /// \brief Set that we attempted to declare an implicit destructor, + /// but overload resolution failed so we deleted it. + void setImplicitDestructorIsDeleted() { + assert((data().DefaultedDestructorIsDeleted || + needsOverloadResolutionForDestructor()) && + "destructor should not be deleted"); + data().DefaultedDestructorIsDeleted = true; + } + /// \brief Determine whether this class should get an implicit move /// constructor or if any existing special member function inhibits this. bool needsImplicitMoveConstructor() const { @@ -1144,24 +1194,28 @@ public: void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures, FieldDecl *&ThisCapture) const; - typedef const LambdaCapture *capture_const_iterator; - typedef llvm::iterator_range<capture_const_iterator> capture_const_range; + using capture_const_iterator = const LambdaCapture *; + using capture_const_range = llvm::iterator_range<capture_const_iterator>; capture_const_range captures() const { return capture_const_range(captures_begin(), captures_end()); } + capture_const_iterator captures_begin() const { return isLambda() ? getLambdaData().Captures : nullptr; } + capture_const_iterator captures_end() const { return isLambda() ? captures_begin() + getLambdaData().NumCaptures : nullptr; } - typedef UnresolvedSetIterator conversion_iterator; + using conversion_iterator = UnresolvedSetIterator; + conversion_iterator conversion_begin() const { return data().Conversions.get(getASTContext()).begin(); } + conversion_iterator conversion_end() const { return data().Conversions.get(getASTContext()).end(); } @@ -1433,10 +1487,10 @@ public: /// We resolve DR1361 by ignoring the second bullet. We resolve DR1452 by /// treating types with trivial default constructors as literal types. /// - /// Only in C++1z and beyond, are lambdas literal types. + /// Only in C++17 and beyond, are lambdas literal types. bool isLiteral() const { return hasTrivialDestructor() && - (!isLambda() || getASTContext().getLangOpts().CPlusPlus1z) && + (!isLambda() || getASTContext().getLangOpts().CPlusPlus17) && !hasNonLiteralTypeFieldsOrBases() && (isAggregate() || isLambda() || hasConstexprNonCopyMoveConstructor() || @@ -1585,8 +1639,8 @@ public: /// \param BaseDefinition the definition of the base class /// /// \returns true if this base matched the search criteria - typedef llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)> - ForallBasesCallback; + using ForallBasesCallback = + llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)>; /// \brief Determines if the given callback holds for all the direct /// or indirect base classes of this type. @@ -1614,8 +1668,9 @@ public: /// base named by the \p Specifier. /// /// \returns true if this base matched the search criteria, false otherwise. - typedef llvm::function_ref<bool(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path)> BaseMatchesCallback; + using BaseMatchesCallback = + llvm::function_ref<bool(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path)>; /// \brief Look for entities within the base classes of this C++ class, /// transitively searching all base class subobjects. @@ -1794,6 +1849,7 @@ public: /// \brief Returns the inheritance model used for this record. MSInheritanceAttr::Spelling getMSInheritanceModel() const; + /// \brief Calculate what the inheritance model would be for this class. MSInheritanceAttr::Spelling calculateInheritanceModel() const; @@ -1832,16 +1888,14 @@ public: return getLambdaData().MethodTyInfo; } + // \brief Determine whether this type is an Interface Like type for + // __interface inheritence purposes. + bool isInterfaceLike() const; + static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K >= firstCXXRecord && K <= lastCXXRecord; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; - friend class ASTRecordWriter; - friend class ASTReader; - friend class ASTWriter; }; /// \brief Represents a C++ deduction guide declaration. @@ -1856,6 +1910,7 @@ public: /// the constructors of \c A. class CXXDeductionGuideDecl : public FunctionDecl { void anchor() override; + private: CXXDeductionGuideDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit, const DeclarationNameInfo &NameInfo, @@ -1869,6 +1924,9 @@ private: } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static CXXDeductionGuideDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit, const DeclarationNameInfo &NameInfo, @@ -1888,12 +1946,15 @@ public: return getDeclName().getCXXDeductionGuideTemplate(); } + void setIsCopyDeductionCandidate() { + IsCopyDeductionCandidate = true; + } + + bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == CXXDeductionGuide; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Represents a static or instance method of a struct/union/class. @@ -1902,6 +1963,7 @@ public: /// non-static) member functions, whether virtual or not. class CXXMethodDecl : public FunctionDecl { void anchor() override; + protected: CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -1953,7 +2015,7 @@ public: if (CD->isVirtualAsWritten() || CD->isPure()) return true; - return (CD->begin_overridden_methods() != CD->end_overridden_methods()); + return CD->size_overridden_methods() != 0; } /// If it's possible to devirtualize a call to this method, return the called @@ -1999,18 +2061,23 @@ public: /// True if this method is user-declared and was not /// deleted or defaulted on its first declaration. bool isUserProvided() const { - return !(isDeleted() || getCanonicalDecl()->isDefaulted()); + auto *DeclAsWritten = this; + if (auto *Pattern = getTemplateInstantiationPattern()) + DeclAsWritten = cast<CXXMethodDecl>(Pattern); + return !(DeclAsWritten->isDeleted() || + DeclAsWritten->getCanonicalDecl()->isDefaulted()); } - /// void addOverriddenMethod(const CXXMethodDecl *MD); - typedef const CXXMethodDecl *const* method_iterator; + using method_iterator = const CXXMethodDecl *const *; method_iterator begin_overridden_methods() const; method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; - typedef ASTContext::overridden_method_range overridden_method_range; + + using overridden_method_range= ASTContext::overridden_method_range; + overridden_method_range overridden_methods() const; /// Returns the parent of this method declaration, which @@ -2240,6 +2307,7 @@ public: return Initializee.get<FieldDecl*>(); return nullptr; } + FieldDecl *getAnyMember() const { if (isMemberInitializer()) return Initializee.get<FieldDecl*>(); @@ -2301,11 +2369,11 @@ public: /// Description of a constructor that was inherited from a base class. class InheritedConstructor { - ConstructorUsingShadowDecl *Shadow; - CXXConstructorDecl *BaseCtor; + ConstructorUsingShadowDecl *Shadow = nullptr; + CXXConstructorDecl *BaseCtor = nullptr; public: - InheritedConstructor() : Shadow(), BaseCtor() {} + InheritedConstructor() = default; InheritedConstructor(ConstructorUsingShadowDecl *Shadow, CXXConstructorDecl *BaseCtor) : Shadow(Shadow), BaseCtor(BaseCtor) {} @@ -2329,8 +2397,6 @@ public: class CXXConstructorDecl final : public CXXMethodDecl, private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> { - void anchor() override; - /// \name Support for base and member initializers. /// \{ /// \brief The arguments used to initialize the base or member. @@ -2350,15 +2416,20 @@ class CXXConstructorDecl final InheritedConstructor Inherited) : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), - CtorInitializers(nullptr), NumCtorInitializers(0), - IsInheritingConstructor((bool)Inherited) { + NumCtorInitializers(0), IsInheritingConstructor((bool)Inherited) { setImplicit(isImplicitlyDeclared); if (Inherited) *getTrailingObjects<InheritedConstructor>() = Inherited; IsExplicitSpecified = isExplicitSpecified; } + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend TrailingObjects; + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, bool InheritsConstructor); static CXXConstructorDecl * @@ -2369,13 +2440,13 @@ public: InheritedConstructor Inherited = InheritedConstructor()); /// \brief Iterates through the member/base initializer list. - typedef CXXCtorInitializer **init_iterator; + using init_iterator = CXXCtorInitializer **; /// \brief Iterates through the member/base initializer list. - typedef CXXCtorInitializer *const *init_const_iterator; + using init_const_iterator = CXXCtorInitializer *const *; - typedef llvm::iterator_range<init_iterator> init_range; - typedef llvm::iterator_range<init_const_iterator> init_const_range; + using init_range = llvm::iterator_range<init_iterator>; + using init_const_range = llvm::iterator_range<init_const_iterator>; init_range inits() { return init_range(init_begin(), init_end()); } init_const_range inits() const { @@ -2387,6 +2458,7 @@ public: 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; @@ -2394,14 +2466,15 @@ public: init_iterator init_end() { return init_begin() + NumCtorInitializers; } + /// \brief Retrieve an iterator past the last initializer. init_const_iterator init_end() const { return init_begin() + NumCtorInitializers; } - typedef std::reverse_iterator<init_iterator> init_reverse_iterator; - typedef std::reverse_iterator<init_const_iterator> - init_const_reverse_iterator; + using init_reverse_iterator = std::reverse_iterator<init_iterator>; + using init_const_reverse_iterator = + std::reverse_iterator<init_const_iterator>; init_reverse_iterator init_rbegin() { return init_reverse_iterator(init_end()); @@ -2532,10 +2605,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == CXXConstructor; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; - friend TrailingObjects; }; /// \brief Represents a C++ destructor within a class. @@ -2549,20 +2618,26 @@ public: /// }; /// \endcode class CXXDestructorDecl : public CXXMethodDecl { - void anchor() override; + friend class ASTDeclReader; + friend class ASTDeclWriter; - FunctionDecl *OperatorDelete; + // FIXME: Don't allocate storage for these except in the first declaration + // of a virtual destructor. + FunctionDecl *OperatorDelete = nullptr; + Expr *OperatorDeleteThisArg = nullptr; CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, bool isImplicitlyDeclared) : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, /*isConstexpr=*/false, SourceLocation()), - OperatorDelete(nullptr) { + SC_None, isInline, /*isConstexpr=*/false, SourceLocation()) + { setImplicit(isImplicitlyDeclared); } + void anchor() override; + public: static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2572,11 +2647,16 @@ public: bool isImplicitlyDeclared); static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); - void setOperatorDelete(FunctionDecl *OD); + void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); + const FunctionDecl *getOperatorDelete() const { return getCanonicalDecl()->OperatorDelete; } + Expr *getOperatorDeleteThisArg() const { + return getCanonicalDecl()->OperatorDeleteThisArg; + } + CXXDestructorDecl *getCanonicalDecl() override { return cast<CXXDestructorDecl>(FunctionDecl::getCanonicalDecl()); } @@ -2587,9 +2667,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == CXXDestructor; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Represents a C++ conversion function within a class. @@ -2603,8 +2680,6 @@ public: /// }; /// \endcode class CXXConversionDecl : public CXXMethodDecl { - void anchor() override; - CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, @@ -2615,7 +2690,12 @@ class CXXConversionDecl : public CXXMethodDecl { IsExplicitSpecified = isExplicitSpecified; } + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, @@ -2652,9 +2732,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == CXXConversion; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Represents a linkage specification. @@ -2665,6 +2742,7 @@ public: /// \endcode class LinkageSpecDecl : public Decl, public DeclContext { virtual void anchor(); + public: /// \brief Represents the language in a linkage specification. /// @@ -2676,25 +2754,29 @@ public: lang_c = /* DW_LANG_C */ 0x0002, lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 }; + private: /// \brief The language for this linkage specification. unsigned Language : 3; + /// \brief True if this linkage spec has braces. /// /// This is needed so that hasBraces() returns the correct result while the /// linkage spec body is being parsed. Once RBraceLoc has been set this is /// not used, so it doesn't need to be serialized. unsigned HasBraces : 1; + /// \brief The source location for the extern keyword. SourceLocation ExternLoc; + /// \brief The source location for the right brace (if valid). SourceLocation RBraceLoc; LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, SourceLocation LangLoc, LanguageIDs lang, bool HasBraces) - : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), - Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc), - RBraceLoc(SourceLocation()) { } + : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), + Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc), + RBraceLoc(SourceLocation()) {} public: static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC, @@ -2705,6 +2787,7 @@ public: /// \brief Return the language specified by this linkage specification. LanguageIDs getLanguage() const { return LanguageIDs(Language); } + /// \brief Set the language specified by this linkage specification. void setLanguage(LanguageIDs L) { Language = L; } @@ -2737,9 +2820,11 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == LinkageSpec; } + static DeclContext *castToDeclContext(const LinkageSpecDecl *D) { return static_cast<DeclContext *>(const_cast<LinkageSpecDecl*>(D)); } + static LinkageSpecDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<LinkageSpecDecl *>(const_cast<DeclContext*>(DC)); } @@ -2756,7 +2841,6 @@ public: /// artificial names for all using-directives in order to store /// them in DeclContext effectively. class UsingDirectiveDecl : public NamedDecl { - void anchor() override; /// \brief The location of the \c using keyword. SourceLocation UsingLoc; @@ -2773,6 +2857,16 @@ class UsingDirectiveDecl : public NamedDecl { /// namespace. DeclContext *CommonAncestor; + UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc, + SourceLocation NamespcLoc, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation IdentLoc, + NamedDecl *Nominated, + DeclContext *CommonAncestor) + : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc), + NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc), + NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) {} + /// \brief Returns special DeclarationName used by using-directives. /// /// This is only used by DeclContext for storing UsingDirectiveDecls in @@ -2781,17 +2875,14 @@ class UsingDirectiveDecl : public NamedDecl { return DeclarationName::getUsingDirectiveName(); } - UsingDirectiveDecl(DeclContext *DC, SourceLocation UsingLoc, - SourceLocation NamespcLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation IdentLoc, - NamedDecl *Nominated, - DeclContext *CommonAncestor) - : NamedDecl(UsingDirective, DC, IdentLoc, getName()), UsingLoc(UsingLoc), - NamespaceLoc(NamespcLoc), QualifierLoc(QualifierLoc), - NominatedNamespace(Nominated), CommonAncestor(CommonAncestor) { } + void anchor() override; public: + friend class ASTDeclReader; + + // Friend for getUsingDirectiveName. + friend class DeclContext; + /// \brief Retrieve the nested-name-specifier that qualifies the /// name of the namespace, with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } @@ -2844,11 +2935,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == UsingDirective; } - - // Friend for getUsingDirectiveName. - friend class DeclContext; - - friend class ASTDeclReader; }; /// \brief Represents a C++ namespace alias. @@ -2860,7 +2946,7 @@ public: /// \endcode class NamespaceAliasDecl : public NamedDecl, public Redeclarable<NamespaceAliasDecl> { - void anchor() override; + friend class ASTDeclReader; /// \brief The location of the \c namespace keyword. SourceLocation NamespaceLoc; @@ -2885,13 +2971,14 @@ class NamespaceAliasDecl : public NamedDecl, NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc), QualifierLoc(QualifierLoc), Namespace(Namespace) {} - typedef Redeclarable<NamespaceAliasDecl> redeclarable_base; + void anchor() override; + + using redeclarable_base = Redeclarable<NamespaceAliasDecl>; + NamespaceAliasDecl *getNextRedeclarationImpl() override; NamespaceAliasDecl *getPreviousDeclImpl() override; NamespaceAliasDecl *getMostRecentDeclImpl() override; - friend class ASTDeclReader; - public: static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation NamespaceLoc, @@ -2903,8 +2990,9 @@ public: static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -2976,23 +3064,27 @@ public: /// } /// \endcode class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { - void anchor() override; + friend class UsingDecl; /// The referenced declaration. - NamedDecl *Underlying; + NamedDecl *Underlying = nullptr; /// \brief The using declaration which introduced this decl or the next using /// shadow declaration contained in the aforementioned using declaration. - NamedDecl *UsingOrNextShadow; - friend class UsingDecl; + NamedDecl *UsingOrNextShadow = nullptr; + + void anchor() override; + + using redeclarable_base = Redeclarable<UsingShadowDecl>; - typedef Redeclarable<UsingShadowDecl> redeclarable_base; UsingShadowDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + UsingShadowDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + UsingShadowDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } @@ -3003,6 +3095,9 @@ protected: UsingShadowDecl(Kind K, ASTContext &C, EmptyShell); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target) { @@ -3011,8 +3106,9 @@ public: static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -3052,9 +3148,6 @@ public: static bool classofKind(Kind K) { return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Represents a shadow constructor declaration introduced into a @@ -3068,18 +3161,16 @@ public: /// }; /// \endcode class ConstructorUsingShadowDecl final : public UsingShadowDecl { - void anchor() override; - /// \brief If this constructor using declaration inherted the constructor /// from an indirect base class, this is the ConstructorUsingShadowDecl /// in the named direct base class from which the declaration was inherited. - ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl; + ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl = nullptr; /// \brief If this constructor using declaration inherted the constructor /// from an indirect base class, this is the ConstructorUsingShadowDecl /// that will be used to construct the unique direct or virtual base class /// that receives the constructor arguments. - ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl; + ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl = nullptr; /// \brief \c true if the constructor ultimately named by this using shadow /// declaration is within a virtual base class subobject of the class that @@ -3105,12 +3196,16 @@ class ConstructorUsingShadowDecl final : public UsingShadowDecl { IsVirtual = true; } } + ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty) - : UsingShadowDecl(ConstructorUsingShadow, C, Empty), - NominatedBaseClassShadowDecl(), ConstructedBaseClassShadowDecl(), - IsVirtual(false) {} + : UsingShadowDecl(ConstructorUsingShadow, C, Empty), IsVirtual(false) {} + + void anchor() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target, @@ -3169,9 +3264,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ConstructorUsingShadow; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Represents a C++ using-declaration. @@ -3181,8 +3273,6 @@ public: /// using someNameSpace::someIdentifier; /// \endcode class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> { - void anchor() override; - /// \brief The source location of the 'using' keyword itself. SourceLocation UsingLocation; @@ -3208,7 +3298,12 @@ class UsingDecl : public NamedDecl, public Mergeable<UsingDecl> { DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) { } + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + /// \brief Return the source location of the 'using' keyword. SourceLocation getUsingLoc() const { return UsingLocation; } @@ -3241,17 +3336,17 @@ public: /// this using declaration. class shadow_iterator { /// \brief The current using shadow declaration. - UsingShadowDecl *Current; + UsingShadowDecl *Current = nullptr; public: - typedef UsingShadowDecl* value_type; - typedef UsingShadowDecl* reference; - typedef UsingShadowDecl* pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = UsingShadowDecl *; + using reference = UsingShadowDecl *; + using pointer = UsingShadowDecl *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - shadow_iterator() : Current(nullptr) { } - explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { } + shadow_iterator() = default; + explicit shadow_iterator(UsingShadowDecl *C) : Current(C) {} reference operator*() const { return Current; } pointer operator->() const { return Current; } @@ -3275,14 +3370,16 @@ public: } }; - typedef llvm::iterator_range<shadow_iterator> shadow_range; + using shadow_range = llvm::iterator_range<shadow_iterator>; shadow_range shadows() const { return shadow_range(shadow_begin(), shadow_end()); } + shadow_iterator shadow_begin() const { return shadow_iterator(FirstUsingShadow.getPointer()); } + shadow_iterator shadow_end() const { return shadow_iterator(); } /// \brief Return the number of shadowed declarations associated with this @@ -3310,9 +3407,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Using; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// Represents a pack of using declarations that a single @@ -3331,8 +3425,6 @@ public: class UsingPackDecl final : public NamedDecl, public Mergeable<UsingPackDecl>, private llvm::TrailingObjects<UsingPackDecl, NamedDecl *> { - void anchor() override; - /// The UnresolvedUsingValueDecl or UnresolvedUsingTypenameDecl from /// which this waas instantiated. NamedDecl *InstantiatedFrom; @@ -3352,7 +3444,13 @@ class UsingPackDecl final getTrailingObjects<NamedDecl *>()); } + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend TrailingObjects; + /// Get the using declaration from which this was instantiated. This will /// always be an UnresolvedUsingValueDecl or an UnresolvedUsingTypenameDecl /// that is a pack expansion. @@ -3380,10 +3478,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == UsingPack; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; - friend TrailingObjects; }; /// \brief Represents a dependent using declaration which was not marked with @@ -3399,8 +3493,6 @@ public: /// \endcode class UnresolvedUsingValueDecl : public ValueDecl, public Mergeable<UnresolvedUsingValueDecl> { - void anchor() override; - /// \brief The source location of the 'using' keyword SourceLocation UsingLocation; @@ -3419,13 +3511,17 @@ class UnresolvedUsingValueDecl : public ValueDecl, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc) - : ValueDecl(UnresolvedUsingValue, DC, - NameInfo.getLoc(), NameInfo.getName(), Ty), - UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc), - QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo()) - { } + : ValueDecl(UnresolvedUsingValue, DC, + NameInfo.getLoc(), NameInfo.getName(), Ty), + UsingLocation(UsingLoc), EllipsisLoc(EllipsisLoc), + QualifierLoc(QualifierLoc), DNLoc(NameInfo.getInfo()) {} + + void anchor() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + /// \brief Returns the source location of the 'using' keyword. SourceLocation getUsingLoc() const { return UsingLocation; } @@ -3478,9 +3574,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == UnresolvedUsingValue; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Represents a dependent using declaration which was marked with @@ -3497,7 +3590,7 @@ public: class UnresolvedUsingTypenameDecl : public TypeDecl, public Mergeable<UnresolvedUsingTypenameDecl> { - void anchor() override; + friend class ASTDeclReader; /// \brief The source location of the 'typename' keyword SourceLocation TypenameLocation; @@ -3517,9 +3610,9 @@ class UnresolvedUsingTypenameDecl : TypeDecl(UnresolvedUsingTypename, DC, TargetNameLoc, TargetName, UsingLoc), TypenameLocation(TypenameLoc), EllipsisLoc(EllipsisLoc), - QualifierLoc(QualifierLoc) { } + QualifierLoc(QualifierLoc) {} - friend class ASTDeclReader; + void anchor() override; public: /// \brief Returns the source location of the 'using' keyword. @@ -3574,7 +3667,6 @@ public: /// \brief Represents a C++11 static_assert declaration. class StaticAssertDecl : public Decl { - virtual void anchor(); llvm::PointerIntPair<Expr *, 1, bool> AssertExprAndFailed; StringLiteral *Message; SourceLocation RParenLoc; @@ -3582,11 +3674,15 @@ class StaticAssertDecl : public Decl { StaticAssertDecl(DeclContext *DC, SourceLocation StaticAssertLoc, Expr *AssertExpr, StringLiteral *Message, SourceLocation RParenLoc, bool Failed) - : Decl(StaticAssert, DC, StaticAssertLoc), - AssertExprAndFailed(AssertExpr, Failed), Message(Message), - RParenLoc(RParenLoc) { } + : Decl(StaticAssert, DC, StaticAssertLoc), + AssertExprAndFailed(AssertExpr, Failed), Message(Message), + RParenLoc(RParenLoc) {} + + virtual void anchor(); public: + friend class ASTDeclReader; + static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StaticAssertLoc, Expr *AssertExpr, StringLiteral *Message, @@ -3609,8 +3705,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == StaticAssert; } - - friend class ASTDeclReader; }; /// A binding in a decomposition declaration. For instance, given: @@ -3622,18 +3716,20 @@ public: /// x[0], x[1], and x[2] respectively, where x is the implicit /// DecompositionDecl of type 'int (&)[3]'. class BindingDecl : public ValueDecl { - void anchor() override; - /// The binding represented by this declaration. References to this /// declaration are effectively equivalent to this expression (except /// that it is only evaluated once at the point of declaration of the /// binding). - Expr *Binding; + Expr *Binding = nullptr; BindingDecl(DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id) - : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()), Binding(nullptr) {} + : ValueDecl(Decl::Binding, DC, IdLoc, Id, QualType()) {} + + void anchor() override; public: + friend class ASTDeclReader; + static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); static BindingDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -3657,8 +3753,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::Binding; } - - friend class ASTDeclReader; }; /// A decomposition declaration. For instance, given: @@ -3672,8 +3766,6 @@ public: class DecompositionDecl final : public VarDecl, private llvm::TrailingObjects<DecompositionDecl, BindingDecl *> { - void anchor() override; - /// The number of BindingDecl*s following this object. unsigned NumBindings; @@ -3688,7 +3780,12 @@ class DecompositionDecl final getTrailingObjects<BindingDecl *>()); } + void anchor() override; + public: + friend class ASTDeclReader; + friend TrailingObjects; + static DecompositionDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation LSquareLoc, @@ -3706,9 +3803,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decomposition; } - - friend TrailingObjects; - friend class ASTDeclReader; }; /// An instance of this class represents the declaration of a property @@ -3748,6 +3842,8 @@ class MSPropertyDecl : public DeclaratorDecl { GetterId(Getter), SetterId(Setter) {} public: + friend class ASTDeclReader; + static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, @@ -3760,8 +3856,6 @@ public: IdentifierInfo* getGetterId() const { return GetterId; } bool hasSetter() const { return SetterId != nullptr; } IdentifierInfo* getSetterId() const { return SetterId; } - - friend class ASTDeclReader; }; /// Insertion operator for diagnostics. This allows sending an AccessSpecifier @@ -3772,6 +3866,6 @@ const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, const PartialDiagnostic &operator<<(const PartialDiagnostic &DB, AccessSpecifier AS); -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DECLCXX_H diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h index eb86526e8eca..6545f70f70b5 100644 --- a/include/clang/AST/DeclContextInternals.h +++ b/include/clang/AST/DeclContextInternals.h @@ -1,4 +1,4 @@ -//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===// +//===- DeclContextInternals.h - DeclContext Representation ------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,10 +11,12 @@ // of DeclContext. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "llvm/ADT/DenseMap.h" @@ -22,6 +24,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include <algorithm> +#include <cassert> namespace clang { @@ -30,21 +33,20 @@ class DependentDiagnostic; /// \brief An array of decls optimized for the common case of only containing /// one entry. struct StoredDeclsList { - /// \brief When in vector form, this is what the Data pointer points to. - typedef SmallVector<NamedDecl *, 4> DeclsTy; + using DeclsTy = SmallVector<NamedDecl *, 4>; /// \brief A collection of declarations, with a flag to indicate if we have /// further external declarations. - typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy; + using DeclsAndHasExternalTy = llvm::PointerIntPair<DeclsTy *, 1, bool>; /// \brief The stored data, which will be either a pointer to a NamedDecl, /// or a pointer to a vector with a flag to indicate if there are further /// external declarations. - llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data; + llvm::PointerUnion<NamedDecl *, DeclsAndHasExternalTy> Data; public: - StoredDeclsList() {} + StoredDeclsList() = default; StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) { RHS.Data = (NamedDecl *)nullptr; @@ -186,7 +188,6 @@ public: /// AddSubsequentDecl - This is called on the second and later decl when it is /// not a redeclaration to merge it into the appropriate place in our list. - /// void AddSubsequentDecl(NamedDecl *D) { assert(!isNull() && "don't AddSubsequentDecl when we have no decls"); @@ -237,28 +238,28 @@ public: }; class StoredDeclsMap - : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> { - + : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> { public: static void DestroyAll(StoredDeclsMap *Map, bool Dependent); private: friend class ASTContext; // walks the chain deleting these friend class DeclContext; + llvm::PointerIntPair<StoredDeclsMap*, 1> Previous; }; class DependentStoredDeclsMap : public StoredDeclsMap { public: - DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {} + DependentStoredDeclsMap() = default; private: - friend class DependentDiagnostic; friend class DeclContext; // iterates over diagnostics + friend class DependentDiagnostic; - DependentDiagnostic *FirstDiagnostic; + DependentDiagnostic *FirstDiagnostic = nullptr; }; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 172c46a44ac1..5d1c6b86fe11 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -1,4 +1,4 @@ -//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===// +//===- DeclFriend.h - Classes for C++ friend declarations -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,16 +15,30 @@ #ifndef LLVM_CLANG_AST_DECLFRIEND_H #define LLVM_CLANG_AST_DECLFRIEND_H +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/ExternalASTSource.h" #include "clang/AST/TypeLoc.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <iterator> namespace clang { +class ASTContext; + /// FriendDecl - Represents the declaration of a friend entity, /// which can be a function, a type, or a templated function or type. -// For example: +/// For example: /// /// @code /// template <typename T> class A { @@ -41,10 +55,14 @@ class FriendDecl final : public Decl, private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> { virtual void anchor(); + public: - typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; + using FriendUnion = llvm::PointerUnion<NamedDecl *, TypeSourceInfo *>; private: + friend class CXXRecordDecl; + friend class CXXRecordDecl::friend_iterator; + // The declaration that's a friend of this class. FriendUnion Friend; @@ -64,35 +82,33 @@ private: // template <class T> friend class A<T>::B; unsigned NumTPLists : 31; - friend class CXXRecordDecl::friend_iterator; - friend class CXXRecordDecl; - FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, SourceLocation FriendL, - ArrayRef<TemplateParameterList*> FriendTypeTPLists) - : Decl(Decl::Friend, DC, L), - Friend(Friend), - NextFriend(), - FriendLoc(FriendL), - UnsupportedFriend(false), - NumTPLists(FriendTypeTPLists.size()) { + ArrayRef<TemplateParameterList *> FriendTypeTPLists) + : Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL), + UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) { for (unsigned i = 0; i < NumTPLists; ++i) getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i]; } FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists) - : Decl(Decl::Friend, Empty), NextFriend(), - UnsupportedFriend(false), - NumTPLists(NumFriendTypeTPLists) { } + : Decl(Decl::Friend, Empty), UnsupportedFriend(false), + NumTPLists(NumFriendTypeTPLists) {} FriendDecl *getNextFriend() { if (!NextFriend.isOffset()) return cast_or_null<FriendDecl>(NextFriend.get(nullptr)); return getNextFriendSlowCase(); } + FriendDecl *getNextFriendSlowCase(); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTNodeImporter; + friend TrailingObjects; + static FriendDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, @@ -108,9 +124,11 @@ public: TypeSourceInfo *getFriendType() const { return Friend.dyn_cast<TypeSourceInfo*>(); } + unsigned getFriendTypeNumTemplateParameterLists() const { return NumTPLists; } + TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const { assert(N < NumTPLists); return getTrailingObjects<TemplateParameterList *>()[N]; @@ -119,7 +137,7 @@ public: /// If this friend declaration doesn't name a type, return the inner /// declaration. NamedDecl *getFriendDecl() const { - return Friend.dyn_cast<NamedDecl*>(); + return Friend.dyn_cast<NamedDecl *>(); } /// Retrieves the location of the 'friend' keyword. @@ -164,27 +182,24 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::Friend; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; - friend class ASTNodeImporter; - friend TrailingObjects; }; /// An iterator over the friend declarations of a class. class CXXRecordDecl::friend_iterator { + friend class CXXRecordDecl; + FriendDecl *Ptr; - friend class CXXRecordDecl; explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {} + public: - friend_iterator() {} + friend_iterator() = default; - typedef FriendDecl *value_type; - typedef FriendDecl *reference; - typedef FriendDecl *pointer; - typedef int difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = FriendDecl *; + using reference = FriendDecl *; + using pointer = FriendDecl *; + using difference_type = int; + using iterator_category = std::forward_iterator_tag; reference operator*() const { return Ptr; } @@ -240,6 +255,6 @@ inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { data().FirstFriend = FD; } -} +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DECLFRIEND_H diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h index 6353b26f7bf5..6d5aaadf529c 100644 --- a/include/clang/AST/DeclGroup.h +++ b/include/clang/AST/DeclGroup.h @@ -1,4 +1,4 @@ -//===--- DeclGroup.h - Classes for representing groups of Decls -*- C++ -*-===// +//===- DeclGroup.h - Classes for representing groups of Decls ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,26 +14,26 @@ #ifndef LLVM_CLANG_AST_DECLGROUP_H #define LLVM_CLANG_AST_DECLGROUP_H -#include "llvm/Support/DataTypes.h" #include "llvm/Support/TrailingObjects.h" #include <cassert> +#include <cstdint> namespace clang { class ASTContext; class Decl; -class DeclGroup; -class DeclGroupIterator; class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> { // FIXME: Include a TypeSpecifier object. - unsigned NumDecls; + unsigned NumDecls = 0; private: - DeclGroup() : NumDecls(0) {} + DeclGroup() = default; DeclGroup(unsigned numdecls, Decl** decls); public: + friend TrailingObjects; + static DeclGroup *Create(ASTContext &C, Decl **Decls, unsigned NumDecls); unsigned size() const { return NumDecls; } @@ -47,23 +47,21 @@ public: assert (i < NumDecls && "Out-of-bounds access."); return getTrailingObjects<Decl *>()[i]; } - - friend TrailingObjects; }; class DeclGroupRef { // Note this is not a PointerIntPair because we need the address of the // non-group case to be valid as a Decl** for iteration. enum Kind { SingleDeclKind=0x0, DeclGroupKind=0x1, Mask=0x1 }; - Decl* D; + + Decl* D = nullptr; Kind getKind() const { return (Kind) (reinterpret_cast<uintptr_t>(D) & Mask); } public: - DeclGroupRef() : D(nullptr) {} - + DeclGroupRef() = default; explicit DeclGroupRef(Decl* d) : D(d) {} explicit DeclGroupRef(DeclGroup* dg) : D((Decl*) (reinterpret_cast<uintptr_t>(dg) | DeclGroupKind)) {} @@ -76,8 +74,8 @@ public: return DeclGroupRef(DeclGroup::Create(C, Decls, NumDecls)); } - typedef Decl** iterator; - typedef Decl* const * const_iterator; + using iterator = Decl **; + using const_iterator = Decl * const *; bool isNull() const { return D == nullptr; } bool isSingleDecl() const { return getKind() == SingleDeclKind; } @@ -133,22 +131,26 @@ public: } }; -} // end clang namespace +} // namespace clang namespace llvm { + // DeclGroupRef is "like a pointer", implement PointerLikeTypeTraits. template <typename T> - class PointerLikeTypeTraits; + struct PointerLikeTypeTraits; template <> - class PointerLikeTypeTraits<clang::DeclGroupRef> { - public: + struct PointerLikeTypeTraits<clang::DeclGroupRef> { static inline void *getAsVoidPointer(clang::DeclGroupRef P) { return P.getAsOpaquePtr(); } + static inline clang::DeclGroupRef getFromVoidPointer(void *P) { return clang::DeclGroupRef::getFromOpaquePtr(P); } + enum { NumLowBitsAvailable = 0 }; }; -} -#endif + +} // namespace llvm + +#endif // LLVM_CLANG_AST_DECLGROUP_H diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h index eba2266724fd..2fff05582563 100644 --- a/include/clang/AST/DeclLookups.h +++ b/include/clang/AST/DeclLookups.h @@ -1,4 +1,4 @@ -//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===// +//===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,6 +18,9 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclContextInternals.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/ExternalASTSource.h" +#include <cstddef> +#include <iterator> namespace clang { @@ -25,14 +28,15 @@ namespace clang { /// of looking up every possible name. class DeclContext::all_lookups_iterator { StoredDeclsMap::iterator It, End; + public: - typedef lookup_result value_type; - typedef lookup_result reference; - typedef lookup_result pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = lookup_result; + using reference = lookup_result; + using pointer = lookup_result; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - all_lookups_iterator() {} + all_lookups_iterator() = default; all_lookups_iterator(StoredDeclsMap::iterator It, StoredDeclsMap::iterator End) : It(It), End(End) {} @@ -63,6 +67,7 @@ public: friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) { return x.It == y.It; } + friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) { return x.It != y.It; } @@ -110,6 +115,6 @@ DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const { return noload_lookups().end(); } -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DECLLOOKUPS_H diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 1cd6e004f751..cef7d935370a 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1,4 +1,4 @@ -//===--- DeclObjC.h - Classes for representing declarations -----*- C++ -*-===// +//===- DeclObjC.h - Classes for representing declarations -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,33 +15,59 @@ #define LLVM_CLANG_AST_DECLOBJC_H #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Redeclarable.h" #include "clang/AST/SelectorLocationsKind.h" +#include "clang/AST/Type.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <string> +#include <utility> namespace clang { + +class ASTContext; +class CompoundStmt; +class CXXCtorInitializer; class Expr; -class Stmt; -class FunctionDecl; -class RecordDecl; -class ObjCIvarDecl; -class ObjCMethodDecl; -class ObjCProtocolDecl; class ObjCCategoryDecl; +class ObjCCategoryImplDecl; +class ObjCImplementationDecl; +class ObjCInterfaceDecl; +class ObjCIvarDecl; class ObjCPropertyDecl; class ObjCPropertyImplDecl; -class CXXCtorInitializer; +class ObjCProtocolDecl; +class Stmt; class ObjCListBase { - 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; - unsigned NumElts; + void **List = nullptr; + unsigned NumElts = 0; public: - ObjCListBase() : List(nullptr), NumElts(0) {} + ObjCListBase() = default; + ObjCListBase(const ObjCListBase &) = delete; + ObjCListBase &operator=(const ObjCListBase &) = delete; + unsigned size() const { return NumElts; } bool empty() const { return NumElts == 0; } @@ -49,7 +75,6 @@ protected: void set(void *const* InList, unsigned Elts, ASTContext &Ctx); }; - /// ObjCList - This is a simple template class used to hold various lists of /// decls etc, which is heavily used by the ObjC front-end. This only use case /// this supports is setting the list all at once and then reading elements out @@ -61,7 +86,8 @@ public: ObjCListBase::set(reinterpret_cast<void*const*>(InList), Elts, Ctx); } - typedef T* const * iterator; + using iterator = T* const *; + iterator begin() const { return (iterator)List; } iterator end() const { return (iterator)List+NumElts; } @@ -74,14 +100,15 @@ public: /// \brief A list of Objective-C protocols, along with the source /// locations at which they were referenced. class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> { - SourceLocation *Locations; + SourceLocation *Locations = nullptr; using ObjCList<ObjCProtocolDecl>::set; public: - ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { } + ObjCProtocolList() = default; + + using loc_iterator = const SourceLocation *; - typedef const SourceLocation *loc_iterator; loc_iterator loc_begin() const { return Locations; } loc_iterator loc_end() const { return Locations + size(); } @@ -89,7 +116,6 @@ public: const SourceLocation *Locs, ASTContext &Ctx); }; - /// ObjCMethodDecl - Represents an instance or class method declaration. /// ObjC methods can be declared within 4 contexts: class interfaces, /// categories, protocols, and class implementations. While C++ member @@ -113,6 +139,7 @@ public: class ObjCMethodDecl : public NamedDecl, public DeclContext { public: enum ImplementationControl { None, Required, Optional }; + private: // The conventional meaning of this method; an ObjCMethodFamily. // This is not serialized; instead, it is computed on demand and @@ -170,8 +197,8 @@ private: /// \brief Array of ParmVarDecls for the formal parameters of this method /// and optionally followed by selector locations. - void *ParamsAndSelLocs; - unsigned NumParams; + void *ParamsAndSelLocs = nullptr; + unsigned NumParams = 0; /// List of attributes for this method declaration. SourceLocation DeclEndLoc; // the location of the ';' or '{'. @@ -181,14 +208,35 @@ private: /// SelfDecl - Decl for the implicit self parameter. This is lazily /// constructed by createImplicitParams. - ImplicitParamDecl *SelfDecl; + ImplicitParamDecl *SelfDecl = nullptr; + /// CmdDecl - Decl for the implicit _cmd parameter. This is lazily /// constructed by createImplicitParams. - ImplicitParamDecl *CmdDecl; + ImplicitParamDecl *CmdDecl = nullptr; + + ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, + Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, + DeclContext *contextDecl, bool isInstance = true, + bool isVariadic = false, bool isPropertyAccessor = false, + bool isImplicitlyDeclared = false, bool isDefined = false, + ImplementationControl impControl = None, + bool HasRelatedResultType = false) + : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), + DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), + IsInstance(isInstance), IsVariadic(isVariadic), + IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined), + IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), + objcDeclQualifier(OBJC_TQ_None), + RelatedResultType(HasRelatedResultType), + SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0), + MethodDeclType(T), ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) { + setImplicit(isImplicitlyDeclared); + } SelectorLocationsKind getSelLocsKind() const { return (SelectorLocationsKind)SelLocsKind; } + bool hasStandardSelLocs() const { return getSelLocsKind() != SelLoc_NonStandard; } @@ -223,33 +271,15 @@ private: ArrayRef<ParmVarDecl*> Params, ArrayRef<SourceLocation> SelLocs); - ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, - Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, - DeclContext *contextDecl, bool isInstance = true, - bool isVariadic = false, bool isPropertyAccessor = false, - bool isImplicitlyDeclared = false, bool isDefined = false, - ImplementationControl impControl = None, - bool HasRelatedResultType = false) - : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), - DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), - IsInstance(isInstance), IsVariadic(isVariadic), - IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined), - IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), - objcDeclQualifier(OBJC_TQ_None), - RelatedResultType(HasRelatedResultType), - SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0), - MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr), - NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr), - CmdDecl(nullptr) { - setImplicit(isImplicitlyDeclared); - } - /// \brief A definition will return its interface declaration. /// An interface declaration will return its definition. /// Otherwise it will return itself. ObjCMethodDecl *getNextRedeclarationImpl() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ObjCMethodDecl * Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo, @@ -299,6 +329,7 @@ public: return getLocStart(); return getSelectorLoc(0); } + SourceLocation getSelectorLoc(unsigned Index) const { assert(Index < getNumSelectorLocs() && "Index out of range!"); if (hasStandardSelLocs()) @@ -346,17 +377,20 @@ public: // Iterator access to formal parameters. unsigned param_size() const { return NumParams; } - typedef const ParmVarDecl *const *param_const_iterator; - typedef ParmVarDecl *const *param_iterator; - typedef llvm::iterator_range<param_iterator> param_range; - typedef llvm::iterator_range<param_const_iterator> param_const_range; + + using param_const_iterator = const ParmVarDecl *const *; + using param_iterator = ParmVarDecl *const *; + using param_range = llvm::iterator_range<param_iterator>; + using param_const_range = llvm::iterator_range<param_const_iterator>; param_const_iterator param_begin() const { return param_const_iterator(getParams()); } + param_const_iterator param_end() const { return param_const_iterator(getParams() + NumParams); } + param_iterator param_begin() { return param_iterator(getParams()); } param_iterator param_end() { return param_iterator(getParams() + NumParams); } @@ -384,12 +418,14 @@ public: struct GetTypeFn { QualType operator()(const ParmVarDecl *PD) const { return PD->getType(); } }; - typedef llvm::mapped_iterator<param_const_iterator, GetTypeFn> - param_type_iterator; + + using param_type_iterator = + llvm::mapped_iterator<param_const_iterator, GetTypeFn>; param_type_iterator param_type_begin() const { return llvm::map_iterator(param_begin(), GetTypeFn()); } + param_type_iterator param_type_end() const { return llvm::map_iterator(param_end(), GetTypeFn()); } @@ -462,9 +498,11 @@ public: void setDeclImplementation(ImplementationControl ic) { DeclImplementation = ic; } + ImplementationControl getImplementationControl() const { return ImplementationControl(DeclImplementation); } + bool isOptional() const { return getImplementationControl() == Optional; } @@ -499,24 +537,25 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCMethod; } + static DeclContext *castToDeclContext(const ObjCMethodDecl *D) { return static_cast<DeclContext *>(const_cast<ObjCMethodDecl*>(D)); } + static ObjCMethodDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<ObjCMethodDecl *>(const_cast<DeclContext*>(DC)); } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// Describes the variance of a given generic parameter. enum class ObjCTypeParamVariance : uint8_t { /// The parameter is invariant: must match exactly. Invariant, + /// The parameter is covariant, e.g., X<T> is a subtype of X<U> when /// the type parameter is covariant and T is a subtype of U. Covariant, + /// The parameter is contravariant, e.g., X<T> is a subtype of X<U> /// when the type parameter is covariant and U is a subtype of T. Contravariant, @@ -535,8 +574,6 @@ enum class ObjCTypeParamVariance : uint8_t { /// /// Objective-C type parameters are typedef-names in the grammar, class ObjCTypeParamDecl : public TypedefNameDecl { - void anchor() override; - /// Index of this type parameter in the type parameter list. unsigned Index : 14; @@ -555,12 +592,17 @@ class ObjCTypeParamDecl : public TypedefNameDecl { unsigned index, SourceLocation nameLoc, IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo) - : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name, - boundInfo), - Index(index), Variance(static_cast<unsigned>(variance)), - VarianceLoc(varianceLoc), ColonLoc(colonLoc) { } + : TypedefNameDecl(ObjCTypeParam, ctx, dc, nameLoc, nameLoc, name, + boundInfo), + Index(index), Variance(static_cast<unsigned>(variance)), + VarianceLoc(varianceLoc), ColonLoc(colonLoc) {} + + void anchor() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ObjCTypeParamDecl *Create(ASTContext &ctx, DeclContext *dc, ObjCTypeParamVariance variance, SourceLocation varianceLoc, @@ -600,9 +642,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCTypeParam; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// Stores a list of Objective-C type parameters for a parameterized class @@ -636,6 +675,8 @@ class ObjCTypeParamList final SourceLocation rAngleLoc); public: + friend TrailingObjects; + /// Create a new Objective-C type parameter list. static ObjCTypeParamList *create(ASTContext &ctx, SourceLocation lAngleLoc, @@ -643,7 +684,7 @@ public: SourceLocation rAngleLoc); /// Iterate through the type parameters in the list. - typedef ObjCTypeParamDecl **iterator; + using iterator = ObjCTypeParamDecl **; iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); } @@ -653,7 +694,7 @@ public: unsigned size() const { return NumParams; } // Iterate through the type parameters in the list. - typedef ObjCTypeParamDecl * const *const_iterator; + using const_iterator = ObjCTypeParamDecl * const *; const_iterator begin() const { return getTrailingObjects<ObjCTypeParamDecl *>(); @@ -676,9 +717,11 @@ public: SourceLocation getLAngleLoc() const { return SourceLocation::getFromRawEncoding(Brackets.Begin); } + SourceLocation getRAngleLoc() const { return SourceLocation::getFromRawEncoding(Brackets.End); } + SourceRange getSourceRange() const { return SourceRange(getLAngleLoc(), getRAngleLoc()); } @@ -686,7 +729,6 @@ public: /// Gather the default set of type arguments to be substituted for /// these type parameters when dealing with an unspecialized type. void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const; - friend TrailingObjects; }; enum class ObjCPropertyQueryKind : uint8_t { @@ -703,6 +745,7 @@ enum class ObjCPropertyQueryKind : uint8_t { /// \endcode class ObjCPropertyDecl : public NamedDecl { void anchor() override; + public: enum PropertyAttributeKind { OBJC_PR_noattr = 0x00, @@ -733,24 +776,42 @@ public: enum SetterKind { Assign, Retain, Copy, Weak }; enum PropertyControl { None, Required, Optional }; + private: - SourceLocation AtLoc; // location of \@property - SourceLocation LParenLoc; // location of '(' starting attribute list or null. + // location of \@property + SourceLocation AtLoc; + + // location of '(' starting attribute list or null. + SourceLocation LParenLoc; + QualType DeclType; TypeSourceInfo *DeclTypeSourceInfo; unsigned PropertyAttributes : NumPropertyAttrsBits; unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; + // \@required/\@optional unsigned PropertyImplementation : 2; - Selector GetterName; // getter name of NULL if no getter - Selector SetterName; // setter name of NULL if no setter - SourceLocation GetterNameLoc; // location of the getter attribute's value - SourceLocation SetterNameLoc; // location of the setter attribute's value + // getter name of NULL if no getter + Selector GetterName; + + // setter name of NULL if no setter + Selector SetterName; + + // location of the getter attribute's value + SourceLocation GetterNameLoc; + + // location of the setter attribute's value + SourceLocation SetterNameLoc; + + // Declaration of getter instance method + ObjCMethodDecl *GetterMethodDecl = nullptr; + + // Declaration of setter instance method + ObjCMethodDecl *SetterMethodDecl = nullptr; - ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method - ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method - ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property + // Synthesize ivar for this property + ObjCIvarDecl *PropertyIvarDecl = nullptr; ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, SourceLocation AtLocation, SourceLocation LParenLocation, @@ -760,11 +821,8 @@ private: LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), PropertyAttributes(OBJC_PR_noattr), PropertyAttributesAsWritten(OBJC_PR_noattr), - PropertyImplementation(propControl), - GetterName(Selector()), - SetterName(Selector()), - GetterMethodDecl(nullptr), SetterMethodDecl(nullptr), - PropertyIvarDecl(nullptr) {} + PropertyImplementation(propControl), GetterName(Selector()), + SetterName(Selector()) {} public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, @@ -799,9 +857,11 @@ public: PropertyAttributeKind getPropertyAttributes() const { return PropertyAttributeKind(PropertyAttributes); } + void setPropertyAttributes(PropertyAttributeKind PRVal) { PropertyAttributes |= PRVal; } + void overwritePropertyAttributes(unsigned PRVal) { PropertyAttributes = PRVal; } @@ -834,10 +894,12 @@ public: bool isInstanceProperty() const { return !isClassProperty(); } bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; } + ObjCPropertyQueryKind getQueryKind() const { return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class : ObjCPropertyQueryKind::OBJC_PR_query_instance; } + static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) { return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class : ObjCPropertyQueryKind::OBJC_PR_query_instance; @@ -860,6 +922,7 @@ public: Selector getGetterName() const { return GetterName; } SourceLocation getGetterNameLoc() const { return GetterNameLoc; } + void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) { GetterName = Sel; GetterNameLoc = Loc; @@ -867,6 +930,7 @@ public: Selector getSetterName() const { return SetterName; } SourceLocation getSetterNameLoc() const { return SetterNameLoc; } + void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) { SetterName = Sel; SetterNameLoc = Loc; @@ -882,9 +946,11 @@ public: void setPropertyImplementation(PropertyControl pc) { PropertyImplementation = pc; } + PropertyControl getPropertyImplementation() const { return PropertyControl(PropertyImplementation); } + bool isOptional() const { return getPropertyImplementation() == PropertyControl::Optional; } @@ -892,6 +958,7 @@ public: void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { PropertyIvarDecl = Ivar; } + ObjCIvarDecl *getPropertyIvarDecl() const { return PropertyIvarDecl; } @@ -917,104 +984,116 @@ public: /// ObjCProtocolDecl, and ObjCImplDecl. /// class ObjCContainerDecl : public NamedDecl, public DeclContext { - void anchor() override; - SourceLocation AtStart; // These two locations in the range mark the end of the method container. // The first points to the '@' token, and the second to the 'end' token. SourceRange AtEnd; -public: + void anchor() override; + +public: ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc) - : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} + : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} // Iterator access to instance/class properties. - typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; - typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>> - prop_range; + using prop_iterator = specific_decl_iterator<ObjCPropertyDecl>; + using prop_range = + llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>; prop_range properties() const { return prop_range(prop_begin(), prop_end()); } + prop_iterator prop_begin() const { return prop_iterator(decls_begin()); } + prop_iterator prop_end() const { return prop_iterator(decls_end()); } - typedef filtered_decl_iterator<ObjCPropertyDecl, - &ObjCPropertyDecl::isInstanceProperty> - instprop_iterator; - typedef llvm::iterator_range<instprop_iterator> instprop_range; + using instprop_iterator = + filtered_decl_iterator<ObjCPropertyDecl, + &ObjCPropertyDecl::isInstanceProperty>; + using instprop_range = llvm::iterator_range<instprop_iterator>; instprop_range instance_properties() const { return instprop_range(instprop_begin(), instprop_end()); } + instprop_iterator instprop_begin() const { return instprop_iterator(decls_begin()); } + instprop_iterator instprop_end() const { return instprop_iterator(decls_end()); } - typedef filtered_decl_iterator<ObjCPropertyDecl, - &ObjCPropertyDecl::isClassProperty> - classprop_iterator; - typedef llvm::iterator_range<classprop_iterator> classprop_range; + using classprop_iterator = + filtered_decl_iterator<ObjCPropertyDecl, + &ObjCPropertyDecl::isClassProperty>; + using classprop_range = llvm::iterator_range<classprop_iterator>; classprop_range class_properties() const { return classprop_range(classprop_begin(), classprop_end()); } + classprop_iterator classprop_begin() const { return classprop_iterator(decls_begin()); } + classprop_iterator classprop_end() const { return classprop_iterator(decls_end()); } // Iterator access to instance/class methods. - typedef specific_decl_iterator<ObjCMethodDecl> method_iterator; - typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>> - method_range; + using method_iterator = specific_decl_iterator<ObjCMethodDecl>; + using method_range = + llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>; method_range methods() const { return method_range(meth_begin(), meth_end()); } + method_iterator meth_begin() const { return method_iterator(decls_begin()); } + method_iterator meth_end() const { return method_iterator(decls_end()); } - typedef filtered_decl_iterator<ObjCMethodDecl, - &ObjCMethodDecl::isInstanceMethod> - instmeth_iterator; - typedef llvm::iterator_range<instmeth_iterator> instmeth_range; + using instmeth_iterator = + filtered_decl_iterator<ObjCMethodDecl, + &ObjCMethodDecl::isInstanceMethod>; + using instmeth_range = llvm::iterator_range<instmeth_iterator>; instmeth_range instance_methods() const { return instmeth_range(instmeth_begin(), instmeth_end()); } + instmeth_iterator instmeth_begin() const { return instmeth_iterator(decls_begin()); } + instmeth_iterator instmeth_end() const { return instmeth_iterator(decls_end()); } - typedef filtered_decl_iterator<ObjCMethodDecl, - &ObjCMethodDecl::isClassMethod> - classmeth_iterator; - typedef llvm::iterator_range<classmeth_iterator> classmeth_range; + using classmeth_iterator = + filtered_decl_iterator<ObjCMethodDecl, + &ObjCMethodDecl::isClassMethod>; + using classmeth_range = llvm::iterator_range<classmeth_iterator>; classmeth_range class_methods() const { return classmeth_range(classmeth_begin(), classmeth_end()); } + classmeth_iterator classmeth_begin() const { return classmeth_iterator(decls_begin()); } + classmeth_iterator classmeth_end() const { return classmeth_iterator(decls_end()); } @@ -1022,13 +1101,16 @@ public: // Get the local instance/class method declared in this interface. ObjCMethodDecl *getMethod(Selector Sel, bool isInstance, bool AllowHidden = false) const; + ObjCMethodDecl *getInstanceMethod(Selector Sel, bool AllowHidden = false) const { return getMethod(Sel, true/*isInstance*/, AllowHidden); } + ObjCMethodDecl *getClassMethod(Selector Sel, bool AllowHidden = false) const { return getMethod(Sel, false/*isInstance*/, AllowHidden); } + bool HasUserDeclaredSetterMethod(const ObjCPropertyDecl *P) const; ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; @@ -1036,13 +1118,11 @@ public: FindPropertyDeclaration(const IdentifierInfo *PropertyId, ObjCPropertyQueryKind QueryKind) const; - typedef llvm::DenseMap<std::pair<IdentifierInfo*, - unsigned/*isClassProperty*/>, - ObjCPropertyDecl*> PropertyMap; - - typedef llvm::SmallDenseSet<const ObjCProtocolDecl *, 8> ProtocolPropertySet; - - typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder; + using PropertyMap = + llvm::DenseMap<std::pair<IdentifierInfo *, unsigned/*isClassProperty*/>, + ObjCPropertyDecl *>; + using ProtocolPropertySet = llvm::SmallDenseSet<const ObjCProtocolDecl *, 8>; + using PropertyDeclOrder = llvm::SmallVector<ObjCPropertyDecl *, 8>; /// This routine collects list of properties to be implemented in the class. /// This includes, class's and its conforming protocols' properties. @@ -1057,6 +1137,7 @@ public: SourceRange getAtEndRange() const { return AtEnd; } + void setAtEndRange(SourceRange atEnd) { AtEnd = atEnd; } @@ -1067,6 +1148,7 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K >= firstObjCContainer && K <= lastObjCContainer; @@ -1075,6 +1157,7 @@ public: static DeclContext *castToDeclContext(const ObjCContainerDecl *D) { return static_cast<DeclContext *>(const_cast<ObjCContainerDecl*>(D)); } + static ObjCContainerDecl *castFromDeclContext(const DeclContext *DC) { return static_cast<ObjCContainerDecl *>(const_cast<DeclContext*>(DC)); } @@ -1107,20 +1190,19 @@ public: /// class ObjCInterfaceDecl : public ObjCContainerDecl , public Redeclarable<ObjCInterfaceDecl> { - void anchor() override; + friend class ASTContext; /// TypeForDecl - This indicates the Type object that represents this /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType - mutable const Type *TypeForDecl; - friend class ASTContext; + mutable const Type *TypeForDecl = nullptr; struct DefinitionData { /// \brief The definition of this class, for quick access from any /// declaration. - ObjCInterfaceDecl *Definition; + ObjCInterfaceDecl *Definition = nullptr; /// When non-null, this is always an ObjCObjectType. - TypeSourceInfo *SuperClassTInfo; + TypeSourceInfo *SuperClassTInfo = nullptr; /// Protocols referenced in the \@interface declaration ObjCProtocolList ReferencedProtocols; @@ -1133,11 +1215,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// Categories are stored as a linked list in the AST, since the categories /// and class extensions come long after the initial interface declaration, /// and we avoid dynamically-resized arrays in the AST wherever possible. - ObjCCategoryDecl *CategoryList; + ObjCCategoryDecl *CategoryList = nullptr; /// IvarList - List of all ivars defined by this class; including class /// extensions and implementation. This list is built lazily. - ObjCIvarDecl *IvarList; + ObjCIvarDecl *IvarList = nullptr; /// \brief Indicates that the contents of this Objective-C class will be /// completed by the external AST source when required. @@ -1155,11 +1237,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// We didn't calculate whether the designated initializers should be /// inherited or not. IDI_Unknown = 0, + /// Designated initializers are inherited for the super class. IDI_Inherited = 1, + /// The class does not inherit designated initializers. IDI_NotInherited = 2 }; + /// One of the \c InheritedDesignatedInitializersState enumeratos. mutable unsigned InheritedDesignatedInitializers : 2; @@ -1168,22 +1253,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// identifier, SourceLocation EndLoc; - DefinitionData() : Definition(), SuperClassTInfo(), CategoryList(), IvarList(), - ExternallyCompleted(), - IvarListMissingImplementation(true), - HasDesignatedInitializers(), - InheritedDesignatedInitializers(IDI_Unknown) { } + DefinitionData() + : ExternallyCompleted(false), IvarListMissingImplementation(true), + HasDesignatedInitializers(false), + InheritedDesignatedInitializers(IDI_Unknown) {} }; - ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, - IdentifierInfo *Id, ObjCTypeParamList *typeParamList, - SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, - bool IsInternal); - - void LoadExternalDefinition() const; - /// The type parameters associated with this class, if any. - ObjCTypeParamList *TypeParamList; + ObjCTypeParamList *TypeParamList = nullptr; /// \brief Contains a pointer to the data associated with this class, /// which will be NULL if this class has not yet been defined. @@ -1192,6 +1269,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// declarations. It will be set unless modules are enabled. llvm::PointerIntPair<DefinitionData *, 1, bool> Data; + ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc, + IdentifierInfo *Id, ObjCTypeParamList *typeParamList, + SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl, + bool IsInternal); + + void anchor() override; + + void LoadExternalDefinition() const; + DefinitionData &data() const { assert(Data.getPointer() && "Declaration has no definition!"); return *Data.getPointer(); @@ -1200,13 +1286,16 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// \brief Allocate the definition data for this class. void allocateDefinitionData(); - typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base; + using redeclarable_base = Redeclarable<ObjCInterfaceDecl>; + ObjCInterfaceDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + ObjCInterfaceDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + ObjCInterfaceDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } @@ -1284,17 +1373,19 @@ public: // Get the local instance/class method declared in a category. ObjCMethodDecl *getCategoryInstanceMethod(Selector Sel) const; ObjCMethodDecl *getCategoryClassMethod(Selector Sel) const; + ObjCMethodDecl *getCategoryMethod(Selector Sel, bool isInstance) const { return isInstance ? getCategoryInstanceMethod(Sel) : getCategoryClassMethod(Sel); } - typedef ObjCProtocolList::iterator protocol_iterator; - typedef llvm::iterator_range<protocol_iterator> protocol_range; + using protocol_iterator = ObjCProtocolList::iterator; + using protocol_range = llvm::iterator_range<protocol_iterator>; protocol_range protocols() const { return protocol_range(protocol_begin(), protocol_end()); } + protocol_iterator protocol_begin() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) @@ -1305,6 +1396,7 @@ public: return data().ReferencedProtocols.begin(); } + protocol_iterator protocol_end() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) @@ -1316,12 +1408,13 @@ public: return data().ReferencedProtocols.end(); } - typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; - typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range; + using protocol_loc_iterator = ObjCProtocolList::loc_iterator; + using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>; protocol_loc_range protocol_locs() const { return protocol_loc_range(protocol_loc_begin(), protocol_loc_end()); } + protocol_loc_iterator protocol_loc_begin() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) @@ -1344,13 +1437,14 @@ public: return data().ReferencedProtocols.loc_end(); } - typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator; - typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range; + using all_protocol_iterator = ObjCList<ObjCProtocolDecl>::iterator; + using all_protocol_range = llvm::iterator_range<all_protocol_iterator>; all_protocol_range all_referenced_protocols() const { return all_protocol_range(all_referenced_protocol_begin(), all_referenced_protocol_end()); } + all_protocol_iterator all_referenced_protocol_begin() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) @@ -1363,6 +1457,7 @@ public: ? protocol_begin() : data().AllReferencedProtocols.begin(); } + all_protocol_iterator all_referenced_protocol_end() const { // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) @@ -1376,10 +1471,11 @@ public: : data().AllReferencedProtocols.end(); } - typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; - typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range; + using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>; + using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>; ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); } + ivar_iterator ivar_begin() const { if (const ObjCInterfaceDecl *Def = getDefinition()) return ivar_iterator(Def->decls_begin()); @@ -1387,6 +1483,7 @@ public: // FIXME: Should make sure no callers ever do this. return ivar_iterator(); } + ivar_iterator ivar_end() const { if (const ObjCInterfaceDecl *Def = getDefinition()) return ivar_iterator(Def->decls_end()); @@ -1518,21 +1615,20 @@ public: /// and extension iterators. template<bool (*Filter)(ObjCCategoryDecl *)> class filtered_category_iterator { - ObjCCategoryDecl *Current; + ObjCCategoryDecl *Current = nullptr; void findAcceptableCategory(); public: - typedef ObjCCategoryDecl * value_type; - typedef value_type reference; - typedef value_type pointer; - typedef std::ptrdiff_t difference_type; - typedef std::input_iterator_tag iterator_category; + using value_type = ObjCCategoryDecl *; + using reference = value_type; + using pointer = value_type; + using difference_type = std::ptrdiff_t; + using iterator_category = std::input_iterator_tag; - filtered_category_iterator() : Current(nullptr) { } + filtered_category_iterator() = default; explicit filtered_category_iterator(ObjCCategoryDecl *Current) - : Current(Current) - { + : Current(Current) { findAcceptableCategory(); } @@ -1567,11 +1663,11 @@ private: public: /// \brief Iterator that walks over the list of categories and extensions /// that are visible, i.e., not hidden in a non-imported submodule. - typedef filtered_category_iterator<isVisibleCategory> - visible_categories_iterator; + using visible_categories_iterator = + filtered_category_iterator<isVisibleCategory>; - typedef llvm::iterator_range<visible_categories_iterator> - visible_categories_range; + using visible_categories_range = + llvm::iterator_range<visible_categories_iterator>; visible_categories_range visible_categories() const { return visible_categories_range(visible_categories_begin(), @@ -1603,9 +1699,9 @@ private: public: /// \brief Iterator that walks over all of the known categories and /// extensions, including those that are hidden. - typedef filtered_category_iterator<isKnownCategory> known_categories_iterator; - typedef llvm::iterator_range<known_categories_iterator> - known_categories_range; + using known_categories_iterator = filtered_category_iterator<isKnownCategory>; + using known_categories_range = + llvm::iterator_range<known_categories_iterator>; known_categories_range known_categories() const { return known_categories_range(known_categories_begin(), @@ -1637,11 +1733,11 @@ private: public: /// \brief Iterator that walks over all of the visible extensions, skipping /// any that are known but hidden. - typedef filtered_category_iterator<isVisibleExtension> - visible_extensions_iterator; + using visible_extensions_iterator = + filtered_category_iterator<isVisibleExtension>; - typedef llvm::iterator_range<visible_extensions_iterator> - visible_extensions_range; + using visible_extensions_range = + llvm::iterator_range<visible_extensions_iterator>; visible_extensions_range visible_extensions() const { return visible_extensions_range(visible_extensions_begin(), @@ -1671,11 +1767,15 @@ private: static bool isKnownExtension(ObjCCategoryDecl *Cat); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; + /// \brief Iterator that walks over all of the known extensions. - typedef filtered_category_iterator<isKnownExtension> - known_extensions_iterator; - typedef llvm::iterator_range<known_extensions_iterator> - known_extensions_range; + using known_extensions_iterator = + filtered_category_iterator<isKnownExtension>; + using known_extensions_range = + llvm::iterator_range<known_extensions_iterator>; known_extensions_range known_extensions() const { return known_extensions_range(known_extensions_begin(), @@ -1771,6 +1871,7 @@ public: ObjCMethodDecl *lookupClassMethod(Selector Sel) const { return lookupMethod(Sel, false/*isInstance*/); } + ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName); /// \brief Lookup a method in the classes implementation hierarchy. @@ -1819,8 +1920,9 @@ public: bool lookupCategory, bool RHSIsQualifiedID = false); - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -1839,10 +1941,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCInterface; } - friend class ASTReader; - friend class ASTDeclReader; - friend class ASTDeclWriter; - private: const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const; bool inheritsDesignatedInitializers() const; @@ -1876,9 +1974,9 @@ private: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW, bool synthesized) - : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, - /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), - NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {} + : FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW, + /*Mutable=*/false, /*HasInit=*/ICIS_NoInit), + DeclAccess(ac), Synthesized(synthesized) {} public: static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC, @@ -1918,26 +2016,27 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCIvar; } + private: /// NextIvar - Next Ivar in the list of ivars declared in class; class's /// extensions and class's implementation - ObjCIvarDecl *NextIvar; + ObjCIvarDecl *NextIvar = nullptr; // NOTE: VC++ treats enums as signed, avoid using the AccessControl enum unsigned DeclAccess : 3; unsigned Synthesized : 1; }; - /// \brief Represents a field declaration created by an \@defs(...). class ObjCAtDefsFieldDecl : public FieldDecl { - void anchor() override; ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW) - : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, - /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ? - BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {} + : FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T, + /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ? + BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {} + + void anchor() override; public: static ObjCAtDefsFieldDecl *Create(ASTContext &C, DeclContext *DC, @@ -1981,11 +2080,8 @@ public: /// protocols are referenced using angle brackets as follows: /// /// id \<NSDraggingInfo> anyObjectThatImplementsNSDraggingInfo; -/// class ObjCProtocolDecl : public ObjCContainerDecl, public Redeclarable<ObjCProtocolDecl> { - void anchor() override; - struct DefinitionData { // \brief The declaration that defines this protocol. ObjCProtocolDecl *Definition; @@ -2001,29 +2097,38 @@ class ObjCProtocolDecl : public ObjCContainerDecl, /// declarations. It will be set unless modules are enabled. llvm::PointerIntPair<DefinitionData *, 1, bool> Data; + ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, + SourceLocation nameLoc, SourceLocation atStartLoc, + ObjCProtocolDecl *PrevDecl); + + void anchor() override; + DefinitionData &data() const { assert(Data.getPointer() && "Objective-C protocol has no definition!"); return *Data.getPointer(); } - ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, - SourceLocation nameLoc, SourceLocation atStartLoc, - ObjCProtocolDecl *PrevDecl); - void allocateDefinitionData(); - typedef Redeclarable<ObjCProtocolDecl> redeclarable_base; + using redeclarable_base = Redeclarable<ObjCProtocolDecl>; + ObjCProtocolDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + ObjCProtocolDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + ObjCProtocolDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; + static ObjCProtocolDecl *Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, SourceLocation nameLoc, @@ -2036,42 +2141,49 @@ public: assert(hasDefinition() && "No definition available!"); return data().ReferencedProtocols; } - typedef ObjCProtocolList::iterator protocol_iterator; - typedef llvm::iterator_range<protocol_iterator> protocol_range; + + using protocol_iterator = ObjCProtocolList::iterator; + using protocol_range = llvm::iterator_range<protocol_iterator>; protocol_range protocols() const { return protocol_range(protocol_begin(), protocol_end()); } + protocol_iterator protocol_begin() const { if (!hasDefinition()) return protocol_iterator(); return data().ReferencedProtocols.begin(); } + protocol_iterator protocol_end() const { if (!hasDefinition()) return protocol_iterator(); return data().ReferencedProtocols.end(); } - typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; - typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range; + + using protocol_loc_iterator = ObjCProtocolList::loc_iterator; + using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>; protocol_loc_range protocol_locs() const { return protocol_loc_range(protocol_loc_begin(), protocol_loc_end()); } + protocol_loc_iterator protocol_loc_begin() const { if (!hasDefinition()) return protocol_loc_iterator(); return data().ReferencedProtocols.loc_begin(); } + protocol_loc_iterator protocol_loc_end() const { if (!hasDefinition()) return protocol_loc_iterator(); return data().ReferencedProtocols.loc_end(); } + unsigned protocol_size() const { if (!hasDefinition()) return 0; @@ -2092,9 +2204,11 @@ public: // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance) const; + ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const { return lookupMethod(Sel, true/*isInstance*/); } + ObjCMethodDecl *lookupClassMethod(Selector Sel) const { return lookupMethod(Sel, false/*isInstance*/); } @@ -2141,8 +2255,9 @@ public: return SourceRange(getAtStartLoc(), getLocation()); } - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -2163,10 +2278,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCProtocol; } - - friend class ASTReader; - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// ObjCCategoryDecl - Represents a category declaration. A category allows @@ -2185,22 +2296,19 @@ public: /// Categories were originally inspired by dynamic languages such as Common /// Lisp and Smalltalk. More traditional class-based languages (C++, Java) /// don't support this level of dynamism, which is both powerful and dangerous. -/// class ObjCCategoryDecl : public ObjCContainerDecl { - void anchor() override; - /// Interface belonging to this category ObjCInterfaceDecl *ClassInterface; /// The type parameters associated with this category, if any. - ObjCTypeParamList *TypeParamList; + ObjCTypeParamList *TypeParamList = nullptr; /// referenced protocols in this category. ObjCProtocolList ReferencedProtocols; /// Next category belonging to this class. /// FIXME: this should not be a singly-linked list. Move storage elsewhere. - ObjCCategoryDecl *NextClassCategory; + ObjCCategoryDecl *NextClassCategory = nullptr; /// \brief The location of the category name in this declaration. SourceLocation CategoryNameLoc; @@ -2213,10 +2321,14 @@ class ObjCCategoryDecl : public ObjCContainerDecl { SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, ObjCTypeParamList *typeParamList, - SourceLocation IvarLBraceLoc=SourceLocation(), - SourceLocation IvarRBraceLoc=SourceLocation()); + SourceLocation IvarLBraceLoc = SourceLocation(), + SourceLocation IvarRBraceLoc = SourceLocation()); + + void anchor() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; static ObjCCategoryDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation AtLoc, @@ -2257,26 +2369,31 @@ public: return ReferencedProtocols; } - typedef ObjCProtocolList::iterator protocol_iterator; - typedef llvm::iterator_range<protocol_iterator> protocol_range; + using protocol_iterator = ObjCProtocolList::iterator; + using protocol_range = llvm::iterator_range<protocol_iterator>; protocol_range protocols() const { return protocol_range(protocol_begin(), protocol_end()); } + protocol_iterator protocol_begin() const { return ReferencedProtocols.begin(); } + protocol_iterator protocol_end() const { return ReferencedProtocols.end(); } unsigned protocol_size() const { return ReferencedProtocols.size(); } - typedef ObjCProtocolList::loc_iterator protocol_loc_iterator; - typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range; + + using protocol_loc_iterator = ObjCProtocolList::loc_iterator; + using protocol_loc_range = llvm::iterator_range<protocol_loc_iterator>; protocol_loc_range protocol_locs() const { return protocol_loc_range(protocol_loc_begin(), protocol_loc_end()); } + protocol_loc_iterator protocol_loc_begin() const { return ReferencedProtocols.loc_begin(); } + protocol_loc_iterator protocol_loc_end() const { return ReferencedProtocols.loc_end(); } @@ -2291,19 +2408,23 @@ public: bool IsClassExtension() const { return getIdentifier() == nullptr; } - typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; - typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range; + using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>; + using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>; ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); } + ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); } + ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); } + unsigned ivar_size() const { return std::distance(ivar_begin(), ivar_end()); } + bool ivar_empty() const { return ivar_begin() == ivar_end(); } @@ -2318,24 +2439,21 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCCategory; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; class ObjCImplDecl : public ObjCContainerDecl { - void anchor() override; - /// Class interface for this class/category implementation ObjCInterfaceDecl *ClassInterface; + void anchor() override; + protected: ObjCImplDecl(Kind DK, DeclContext *DC, ObjCInterfaceDecl *classInterface, IdentifierInfo *Id, SourceLocation nameLoc, SourceLocation atStartLoc) - : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc), - ClassInterface(classInterface) {} + : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc), + ClassInterface(classInterface) {} public: const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2347,6 +2465,7 @@ public: method->setLexicalDeclContext(this); addDecl(method); } + void addClassMethod(ObjCMethodDecl *method) { // FIXME: Context should be set correctly before we get here. method->setLexicalDeclContext(this); @@ -2360,21 +2479,24 @@ public: ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; // Iterator access to properties. - typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator; - typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>> - propimpl_range; + using propimpl_iterator = specific_decl_iterator<ObjCPropertyImplDecl>; + using propimpl_range = + llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>; propimpl_range property_impls() const { return propimpl_range(propimpl_begin(), propimpl_end()); } + propimpl_iterator propimpl_begin() const { return propimpl_iterator(decls_begin()); } + propimpl_iterator propimpl_end() const { return propimpl_iterator(decls_end()); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K >= firstObjCImpl && K <= lastObjCImpl; } @@ -2394,8 +2516,6 @@ public: /// /// ObjCCategoryImplDecl class ObjCCategoryImplDecl : public ObjCImplDecl { - void anchor() override; - // Category name location SourceLocation CategoryNameLoc; @@ -2403,10 +2523,16 @@ class ObjCCategoryImplDecl : public ObjCImplDecl { ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc) - : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, - nameLoc, atStartLoc), - CategoryNameLoc(CategoryNameLoc) {} + : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id, + nameLoc, atStartLoc), + CategoryNameLoc(CategoryNameLoc) {} + + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, @@ -2421,9 +2547,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCCategoryImpl;} - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID); @@ -2446,7 +2569,6 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID); /// we allow instance variables to be specified in the implementation. When /// specified, they need to be \em identical to the interface. class ObjCImplementationDecl : public ObjCImplDecl { - void anchor() override; /// Implementation Class's super class. ObjCInterfaceDecl *SuperClass; SourceLocation SuperLoc; @@ -2458,7 +2580,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { /// Support for ivar initialization. /// \brief The arguments used to initialize the ivars LazyCXXCtorInitializersPtr IvarInitializers; - unsigned NumIvarInitializers; + unsigned NumIvarInitializers = 0; /// Do the ivars of this class require initialization other than /// zero-initialization? @@ -2474,15 +2596,20 @@ class ObjCImplementationDecl : public ObjCImplDecl { SourceLocation superLoc = SourceLocation(), SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()) - : ObjCImplDecl(ObjCImplementation, DC, classInterface, - classInterface ? classInterface->getIdentifier() - : nullptr, - nameLoc, atStartLoc), - SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc), - IvarRBraceLoc(IvarRBraceLoc), - IvarInitializers(nullptr), NumIvarInitializers(0), - HasNonZeroConstructors(false), HasDestructors(false) {} + : ObjCImplDecl(ObjCImplementation, DC, classInterface, + classInterface ? classInterface->getIdentifier() + : nullptr, + nameLoc, atStartLoc), + SuperClass(superDecl), SuperLoc(superLoc), + IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc), + HasNonZeroConstructors(false), HasDestructors(false) {} + + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC, ObjCInterfaceDecl *classInterface, ObjCInterfaceDecl *superDecl, @@ -2495,15 +2622,16 @@ public: static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); /// init_iterator - Iterates through the ivar initializer list. - typedef CXXCtorInitializer **init_iterator; + using init_iterator = CXXCtorInitializer **; /// init_const_iterator - Iterates through the ivar initializer list. - typedef CXXCtorInitializer * const * init_const_iterator; + using init_const_iterator = CXXCtorInitializer * const *; - typedef llvm::iterator_range<init_iterator> init_range; - typedef llvm::iterator_range<init_const_iterator> init_const_range; + using init_range = llvm::iterator_range<init_iterator>; + using init_const_range = llvm::iterator_range<init_const_iterator>; init_range inits() { return init_range(init_begin(), init_end()); } + init_const_range inits() const { return init_const_range(init_begin(), init_end()); } @@ -2513,6 +2641,7 @@ public: 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; @@ -2520,10 +2649,12 @@ public: init_iterator init_end() { return init_begin() + NumIvarInitializers; } + /// end() - Retrieve an iterator past the last initializer. init_const_iterator init_end() const { return init_begin() + NumIvarInitializers; } + /// getNumArgs - Number of ivars which must be initialized. unsigned getNumIvarInitializers() const { return NumIvarInitializers; @@ -2585,28 +2716,29 @@ public: void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } - typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator; - typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range; + using ivar_iterator = specific_decl_iterator<ObjCIvarDecl>; + using ivar_range = llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>>; ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); } + ivar_iterator ivar_begin() const { return ivar_iterator(decls_begin()); } + ivar_iterator ivar_end() const { return ivar_iterator(decls_end()); } + unsigned ivar_size() const { return std::distance(ivar_begin(), ivar_end()); } + bool ivar_empty() const { return ivar_begin() == ivar_end(); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCImplementation; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID); @@ -2614,13 +2746,15 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID); /// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is /// declared as \@compatibility_alias alias class. class ObjCCompatibleAliasDecl : public NamedDecl { - void anchor() override; /// Class that this is an alias of. ObjCInterfaceDecl *AliasedClass; ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl* aliasedClass) - : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} + : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {} + + void anchor() override; + public: static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, @@ -2635,7 +2769,6 @@ public: static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; } - }; /// ObjCPropertyImplDecl - Represents implementation declaration of a property @@ -2648,6 +2781,7 @@ public: Synthesize, Dynamic }; + private: SourceLocation AtLoc; // location of \@synthesize or \@dynamic @@ -2667,24 +2801,25 @@ private: /// Null for \@dynamic. Non-null if property must be copy-constructed in /// getter. - Expr *GetterCXXConstructor; + Expr *GetterCXXConstructor = nullptr; /// Null for \@dynamic. Non-null if property has assignment operator to call /// in Setter synthesis. - Expr *SetterCXXAssignment; + Expr *SetterCXXAssignment = nullptr; ObjCPropertyImplDecl(DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc) - : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), - IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl), - GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) { - assert (PK == Dynamic || PropertyIvarDecl); + : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), + IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl) { + assert(PK == Dynamic || PropertyIvarDecl); } public: + friend class ASTDeclReader; + static ObjCPropertyImplDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation atLoc, SourceLocation L, ObjCPropertyDecl *property, @@ -2733,6 +2868,7 @@ public: Expr *getGetterCXXConstructor() const { return GetterCXXConstructor; } + void setGetterCXXConstructor(Expr *getterCXXConstructor) { GetterCXXConstructor = getterCXXConstructor; } @@ -2740,14 +2876,13 @@ public: Expr *getSetterCXXAssignment() const { return SetterCXXAssignment; } + void setSetterCXXAssignment(Expr *setterCXXAssignment) { SetterCXXAssignment = setterCXXAssignment; } static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Decl::Kind K) { return K == ObjCPropertyImpl; } - - friend class ASTDeclReader; }; template<bool (*Filter)(ObjCCategoryDecl *)> @@ -2778,5 +2913,6 @@ inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { return Cat->IsClassExtension(); } -} // end namespace clang -#endif +} // namespace clang + +#endif // LLVM_CLANG_AST_DECLOBJC_H diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h index 30ca79e9d005..2a329c3732cb 100644 --- a/include/clang/AST/DeclOpenMP.h +++ b/include/clang/AST/DeclOpenMP.h @@ -100,12 +100,22 @@ public: /// /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer. class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext { +public: + enum InitKind { + CallInit, // Initialized by function call. + DirectInit, // omp_priv(<expr>) + CopyInit // omp_priv = <expr> + }; + private: friend class ASTDeclReader; /// \brief Combiner for declare reduction construct. Expr *Combiner; /// \brief Initializer for declare reduction construct. Expr *Initializer; + /// Kind of initializer - function call or omp_priv<init_expr> initializtion. + InitKind InitializerKind = CallInit; + /// \brief Reference to the previous declare reduction construct in the same /// scope with the same name. Required for proper templates instantiation if /// the declare reduction construct is declared inside compound statement. @@ -117,7 +127,8 @@ private: DeclarationName Name, QualType Ty, OMPDeclareReductionDecl *PrevDeclInScope) : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr), - Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {} + Initializer(nullptr), InitializerKind(CallInit), + PrevDeclInScope(PrevDeclInScope) {} void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) { PrevDeclInScope = Prev; @@ -142,8 +153,13 @@ public: /// construct. Expr *getInitializer() { return Initializer; } const Expr *getInitializer() const { return Initializer; } + /// Get initializer kind. + InitKind getInitializerKind() const { return InitializerKind; } /// \brief Set initializer expression for the declare reduction construct. - void setInitializer(Expr *E) { Initializer = E; } + void setInitializer(Expr *E, InitKind IK) { + Initializer = E; + InitializerKind = IK; + } /// \brief Get reference to previous declare reduction construct in the same /// scope with the same name. diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 2879452f2404..7842d7097174 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -1,4 +1,4 @@ -//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===// +//===- DeclTemplate.h - Classes for representing C++ templates --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,42 +6,60 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the C++ template declaration subclasses. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLTEMPLATE_H #define LLVM_CLANG_AST_DECLTEMPLATE_H +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> #include <utility> namespace clang { enum BuiltinTemplateKind : int; -class TemplateParameterList; -class TemplateDecl; -class RedeclarableTemplateDecl; -class FunctionTemplateDecl; class ClassTemplateDecl; class ClassTemplatePartialSpecializationDecl; -class TemplateTypeParmDecl; +class Expr; +class FunctionTemplateDecl; +class IdentifierInfo; class NonTypeTemplateParmDecl; +class TemplateDecl; class TemplateTemplateParmDecl; -class TypeAliasTemplateDecl; +class TemplateTypeParmDecl; +class UnresolvedSetImpl; class VarTemplateDecl; class VarTemplatePartialSpecializationDecl; /// \brief Stores a template parameter of any kind. -typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, - TemplateTemplateParmDecl*> TemplateParameter; +using TemplateParameter = + llvm::PointerUnion3<TemplateTypeParmDecl *, NonTypeTemplateParmDecl *, + TemplateTemplateParmDecl *>; NamedDecl *getAsNamedDecl(TemplateParameter P); @@ -50,7 +68,6 @@ NamedDecl *getAsNamedDecl(TemplateParameter P); class TemplateParameterList final : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *, Expr *> { - /// The location of the 'template' keyword. SourceLocation TemplateLoc; @@ -69,6 +86,10 @@ class TemplateParameterList final unsigned HasRequiresClause : 1; protected: + TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, + ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc, + Expr *RequiresClause); + size_t numTrailingObjects(OverloadToken<NamedDecl *>) const { return NumParams; } @@ -77,11 +98,11 @@ protected: return HasRequiresClause; } - TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, - ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc, - Expr *RequiresClause); - public: + template <size_t N, bool HasRequiresClause> + friend class FixedSizeTemplateParameterListStorage; + friend TrailingObjects; + static TemplateParameterList *Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, @@ -90,10 +111,10 @@ public: Expr *RequiresClause); /// \brief Iterates through the template parameters in this list. - typedef NamedDecl** iterator; + using iterator = NamedDecl **; /// \brief Iterates through the template parameters in this list. - typedef NamedDecl* const* const_iterator; + using const_iterator = NamedDecl * const *; iterator begin() { return getTrailingObjects<NamedDecl *>(); } const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); } @@ -113,7 +134,6 @@ public: assert(Idx < size() && "Template parameter index out-of-range"); return begin()[Idx]; } - const NamedDecl* getParam(unsigned Idx) const { assert(Idx < size() && "Template parameter index out-of-range"); return begin()[Idx]; @@ -157,11 +177,6 @@ public: return SourceRange(TemplateLoc, RAngleLoc); } - friend TrailingObjects; - - template <size_t N, bool HasRequiresClause> - friend class FixedSizeTemplateParameterListStorage; - public: // FIXME: workaround for MSVC 2013; remove when no longer needed using FixedSizeStorageOwner = TrailingObjects::FixedSizeStorageOwner; @@ -201,14 +216,16 @@ class TemplateArgumentList final /// argument list. unsigned NumArguments; - TemplateArgumentList(const TemplateArgumentList &Other) = delete; - void operator=(const TemplateArgumentList &Other) = delete; - // Constructs an instance with an internal Argument list, containing // a copy of the Args array. (Called by CreateCopy) TemplateArgumentList(ArrayRef<TemplateArgument> Args); public: + friend TrailingObjects; + + TemplateArgumentList(const TemplateArgumentList &) = delete; + TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// \brief Type used to indicate that the template argument list itself is a /// stack object. It does not own its template arguments. enum OnStackType { OnStack }; @@ -254,8 +271,6 @@ public: /// \brief Retrieve a pointer to the template argument list. const TemplateArgument *data() const { return Arguments; } - - friend TrailingObjects; }; void *allocateDefaultArgStorageChain(const ASTContext &C); @@ -297,9 +312,11 @@ public: /// Determine whether there is a default argument for this parameter. bool isSet() const { return !ValueOrInherited.isNull(); } + /// Determine whether the default argument for this parameter was inherited /// from a previous declaration of the same entity. bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); } + /// Get the default argument's value. This does not consider whether the /// default argument is visible. ArgType get() const { @@ -310,6 +327,7 @@ public: return C->Value; return Storage->ValueOrInherited.template get<ArgType>(); } + /// Get the parameter from which we inherit the default argument, if any. /// This is the parameter on which the default argument was actually written. const ParmDecl *getInheritedFrom() const { @@ -319,11 +337,13 @@ public: return C->PrevDeclWithDefaultArg; return nullptr; } + /// Set the default argument. void set(ArgType Arg) { assert(!isSet() && "default argument already set"); ValueOrInherited = Arg; } + /// Set that the default argument was inherited from another parameter. void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) { assert(!isInherited() && "default argument already inherited"); @@ -334,6 +354,7 @@ public: ValueOrInherited = new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()}; } + /// Remove the default argument, even if it was inherited. void clear() { ValueOrInherited = ArgType(); @@ -350,7 +371,7 @@ class ConstrainedTemplateDeclInfo { friend TemplateDecl; public: - ConstrainedTemplateDeclInfo() : TemplateParams(), AssociatedConstraints() {} + ConstrainedTemplateDeclInfo() = default; TemplateParameterList *getTemplateParameters() const { return TemplateParams; @@ -365,8 +386,8 @@ protected: void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; } - TemplateParameterList *TemplateParams; - Expr *AssociatedConstraints; + TemplateParameterList *TemplateParams = nullptr; + Expr *AssociatedConstraints = nullptr; }; @@ -377,13 +398,14 @@ protected: /// reference to the templated scoped declaration: the underlying AST node. class TemplateDecl : public NamedDecl { void anchor() override; + protected: // Construct a template decl with the given name and parameters. // Used when there is no templated element (e.g., for tt-params). TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false), + : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr), TemplateParams(CTDI) { this->setTemplateParameters(Params); } @@ -396,7 +418,7 @@ protected: TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false), + : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), TemplateParams(CTDI) { this->setTemplateParameters(Params); } @@ -428,31 +450,22 @@ public: } /// Get the underlying, templated declaration. - NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); } + NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K >= firstTemplate && K <= lastTemplate; } SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getTemplateParameters()->getTemplateLoc(), - TemplatedDecl.getPointer()->getSourceRange().getEnd()); + TemplatedDecl->getSourceRange().getEnd()); } - /// Whether this is a (C++ Concepts TS) function or variable concept. - bool isConcept() const { return TemplatedDecl.getInt(); } - void setConcept() { TemplatedDecl.setInt(true); } - protected: - /// \brief The named declaration from which this template was instantiated. - /// (or null). - /// - /// The boolean value will be true to indicate that this template - /// (function or variable) is a concept. - llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl; - + NamedDecl *TemplatedDecl; /// \brief The template parameter list and optional requires-clause /// associated with this declaration; alternatively, a /// \c ConstrainedTemplateDeclInfo if the associated constraints of the @@ -481,9 +494,9 @@ public: /// \brief Initialize the underlying templated declaration and /// template parameters. void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { - assert(!TemplatedDecl.getPointer() && "TemplatedDecl already set!"); + assert(!TemplatedDecl && "TemplatedDecl already set!"); assert(!TemplateParams && "TemplateParams already set!"); - TemplatedDecl.setPointer(templatedDecl); + TemplatedDecl = templatedDecl; TemplateParams = templateParams; } }; @@ -498,11 +511,10 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode { const TemplateArgumentList *TemplateArgs, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI) - : Function(FD), - Template(Template, TSK - 1), - TemplateArguments(TemplateArgs), - TemplateArgumentsAsWritten(TemplateArgsAsWritten), - PointOfInstantiation(POI) { } + : Function(FD), Template(Template, TSK - 1), + TemplateArguments(TemplateArgs), + TemplateArgumentsAsWritten(TemplateArgsAsWritten), + PointOfInstantiation(POI) {} public: static FunctionTemplateSpecializationInfo * @@ -604,7 +616,7 @@ public: explicit MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK, SourceLocation POI = SourceLocation()) - : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) { + : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) { assert(TSK != TSK_Undeclared && "Cannot encode undeclared template specializations for members"); } @@ -681,6 +693,8 @@ class DependentFunctionTemplateSpecializationInfo final const TemplateArgumentListInfo &TemplateArgs); public: + friend TrailingObjects; + static DependentFunctionTemplateSpecializationInfo * Create(ASTContext &Context, const UnresolvedSetImpl &Templates, const TemplateArgumentListInfo &TemplateArgs); @@ -716,32 +730,34 @@ public: SourceLocation getRAngleLoc() const { return AngleLocs.getEnd(); } - - friend TrailingObjects; }; /// Declaration of a redeclarable template. class RedeclarableTemplateDecl : public TemplateDecl, public Redeclarable<RedeclarableTemplateDecl> { - typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base; + using redeclarable_base = Redeclarable<RedeclarableTemplateDecl>; + RedeclarableTemplateDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); } + RedeclarableTemplateDecl *getPreviousDeclImpl() override { return getPreviousDecl(); } + RedeclarableTemplateDecl *getMostRecentDeclImpl() override { return getMostRecentDecl(); } protected: template <typename EntryType> struct SpecEntryTraits { - typedef EntryType DeclType; + using DeclType = EntryType; static DeclType *getDecl(EntryType *D) { return D; } + static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) { return D->getTemplateArgs().asArray(); } @@ -756,7 +772,7 @@ protected: typename std::iterator_traits<typename llvm::FoldingSetVector< EntryType>::iterator>::iterator_category, DeclType *, ptrdiff_t, DeclType *, DeclType *> { - SpecIterator() {} + SpecIterator() = default; explicit SpecIterator( typename llvm::FoldingSetVector<EntryType>::iterator SetIter) : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {} @@ -764,6 +780,7 @@ protected: DeclType *operator*() const { return SETraits::getDecl(&*this->I)->getMostRecentDecl(); } + DeclType *operator->() const { return **this; } }; @@ -773,6 +790,8 @@ protected: return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin()); } + void loadLazySpecializationsImpl() const; + template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType* findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args, void *&InsertPos); @@ -782,7 +801,7 @@ protected: EntryType *Entry, void *InsertPos); struct CommonBase { - CommonBase() : InstantiatedFromMember(nullptr, false) { } + CommonBase() : InstantiatedFromMember(nullptr, false) {} /// \brief The template from which this was most /// directly instantiated (or null). @@ -791,11 +810,18 @@ protected: /// was explicitly specialized. llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool> InstantiatedFromMember; + + /// \brief If non-null, points to an array of specializations (including + /// partial specializations) known only by their external declaration IDs. + /// + /// The first value in the array is the number of specializations/partial + /// specializations that follow. + uint32_t *LazySpecializations = nullptr; }; /// \brief Pointer to the common data shared by all declarations of this /// template. - mutable CommonBase *Common; + mutable CommonBase *Common = nullptr; /// \brief Retrieves the "common" pointer shared by all (re-)declarations of /// the same template. Calling this routine may implicitly allocate memory @@ -809,8 +835,8 @@ protected: ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl) - : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C), - Common() {} + : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C) + {} RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, @@ -818,6 +844,9 @@ protected: : RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {} public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; template <class decl_type> friend class RedeclarableTemplate; /// \brief Retrieves the canonical declaration of this template. @@ -858,7 +887,7 @@ public: } /// \brief Retrieve the member template from which this template was - /// instantiated, or NULL if this template was not instantiated from a + /// instantiated, or nullptr if this template was not instantiated from a /// member template. /// /// A template is instantiated from a member template when the member @@ -902,8 +931,9 @@ public: getCommonPtr()->InstantiatedFromMember.setPointer(TD); } - typedef redeclarable_base::redecl_range redecl_range; - typedef redeclarable_base::redecl_iterator redecl_iterator; + using redecl_range = redeclarable_base::redecl_range; + using redecl_iterator = redeclarable_base::redecl_iterator; + using redeclarable_base::redecls_begin; using redeclarable_base::redecls_end; using redeclarable_base::redecls; @@ -913,22 +943,20 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate; } - - friend class ASTReader; - friend class ASTDeclReader; - friend class ASTDeclWriter; }; template <> struct RedeclarableTemplateDecl:: SpecEntryTraits<FunctionTemplateSpecializationInfo> { - typedef FunctionDecl DeclType; + using DeclType = FunctionDecl; static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) { return I->Function; } + static ArrayRef<TemplateArgument> getTemplateArgs(FunctionTemplateSpecializationInfo *I) { return I->TemplateArguments->asArray(); @@ -938,11 +966,11 @@ SpecEntryTraits<FunctionTemplateSpecializationInfo> { /// Declaration of a template function. class FunctionTemplateDecl : public RedeclarableTemplateDecl { protected: + friend class FunctionDecl; + /// \brief Data that is common to all of the declarations of a given /// function template. struct Common : CommonBase { - Common() : InjectedArgs(), LazySpecializations() { } - /// \brief The function template specializations for this function /// template, including explicit specializations and instantiations. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations; @@ -954,14 +982,9 @@ protected: /// many template arguments as template parameaters) for the function /// template, and is allocated lazily, since most function templates do not /// require the use of this information. - TemplateArgument *InjectedArgs; + TemplateArgument *InjectedArgs = nullptr; - /// \brief If non-null, points to an array of specializations known only - /// by their external declaration IDs. - /// - /// The first value in the array is the number of of specializations - /// that follow. - uint32_t *LazySpecializations; + Common() = default; }; FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -976,8 +999,6 @@ protected: return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); } - friend class FunctionDecl; - /// \brief Retrieve the set of function template specializations of this /// function template. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> & @@ -991,12 +1012,15 @@ protected: void *InsertPos); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + /// \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.getPointer()); + return static_cast<FunctionDecl *>(TemplatedDecl); } /// Returns whether this template declaration defines the primary @@ -1020,14 +1044,11 @@ public: } /// \brief Retrieve the previous declaration of this function template, or - /// NULL if no such declaration exists. + /// nullptr if no such declaration exists. FunctionTemplateDecl *getPreviousDecl() { return cast_or_null<FunctionTemplateDecl>( static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } - - /// \brief Retrieve the previous declaration of this function template, or - /// NULL if no such declaration exists. const FunctionTemplateDecl *getPreviousDecl() const { return cast_or_null<FunctionTemplateDecl>( static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl()); @@ -1047,12 +1068,13 @@ public: RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } - typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator; - typedef llvm::iterator_range<spec_iterator> spec_range; + using spec_iterator = SpecIterator<FunctionTemplateSpecializationInfo>; + using spec_range = llvm::iterator_range<spec_iterator>; spec_range specializations() const { return spec_range(spec_begin(), spec_end()); } + spec_iterator spec_begin() const { return makeSpecIterator(getSpecializations(), false); } @@ -1083,9 +1105,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == FunctionTemplate; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; //===----------------------------------------------------------------------===// @@ -1102,19 +1121,17 @@ 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() = delete; - protected: - TemplateParmPosition(unsigned D, unsigned P) - : Depth(D), Position(P) - { } - // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for // position? Maybe? unsigned Depth; unsigned Position; + TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {} + public: + TemplateParmPosition() = delete; + /// Get the nesting depth of the template parameter. unsigned getDepth() const { return Depth; } void setDepth(unsigned D) { Depth = D; } @@ -1134,6 +1151,9 @@ public: /// template<typename T> class vector; /// \endcode class TemplateTypeParmDecl : public TypeDecl { + /// Sema creates these on the stack during auto type deduction. + friend class Sema; + /// \brief Whether this template type parameter was declaration with /// the 'typename' keyword. /// @@ -1141,18 +1161,14 @@ class TemplateTypeParmDecl : public TypeDecl { bool Typename : 1; /// \brief The default template argument, if any. - typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *> - DefArgStorage; + using DefArgStorage = + DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>; DefArgStorage DefaultArgument; TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, SourceLocation IdLoc, IdentifierInfo *Id, bool Typename) - : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename), - DefaultArgument() { } - - /// Sema creates these on the stack during auto type deduction. - friend class Sema; + : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename) {} public: static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC, @@ -1199,6 +1215,7 @@ public: void setDefaultArgument(TypeSourceInfo *DefArg) { DefaultArgument.set(DefArg); } + /// \brief Set that this default argument was inherited from another /// parameter. void setInheritedDefaultArgument(const ASTContext &C, @@ -1241,9 +1258,12 @@ class NonTypeTemplateParmDecl final protected TemplateParmPosition, private llvm::TrailingObjects<NonTypeTemplateParmDecl, std::pair<QualType, TypeSourceInfo *>> { + friend class ASTDeclReader; + friend TrailingObjects; + /// \brief The default template argument, if any, and whether or not /// it was inherited. - typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage; + using DefArgStorage = DefaultArgStorage<NonTypeTemplateParmDecl, Expr *>; DefArgStorage DefaultArgument; // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index @@ -1255,10 +1275,10 @@ class NonTypeTemplateParmDecl final /// \brief Whether this non-type template parameter is an "expanded" /// parameter pack, meaning that its type is a pack expansion and we /// already know the set of types that expansion expands to. - bool ExpandedParameterPack; + bool ExpandedParameterPack = false; /// \brief The number of types in an expanded parameter pack. - unsigned NumExpandedTypes; + unsigned NumExpandedTypes = 0; size_t numTrailingObjects( OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const { @@ -1269,10 +1289,8 @@ class NonTypeTemplateParmDecl final SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack, TypeSourceInfo *TInfo) - : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), - TemplateParmPosition(D, P), ParameterPack(ParameterPack), - ExpandedParameterPack(false), NumExpandedTypes(0) - { } + : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc), + TemplateParmPosition(D, P), ParameterPack(ParameterPack) {} NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, @@ -1281,9 +1299,6 @@ class NonTypeTemplateParmDecl final ArrayRef<QualType> ExpandedTypes, ArrayRef<TypeSourceInfo *> ExpandedTInfos); - friend class ASTDeclReader; - friend TrailingObjects; - public: static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, @@ -1428,11 +1443,9 @@ class TemplateTemplateParmDecl final protected TemplateParmPosition, private llvm::TrailingObjects<TemplateTemplateParmDecl, TemplateParameterList *> { - void anchor() override; - /// \brief The default template argument, if any. - typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *> - DefArgStorage; + using DefArgStorage = + DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>; DefArgStorage DefaultArgument; /// \brief Whether this parameter is a parameter pack. @@ -1441,25 +1454,29 @@ class TemplateTemplateParmDecl final /// \brief Whether this template template parameter is an "expanded" /// parameter pack, meaning that it is a pack expansion and we /// already know the set of template parameters that expansion expands to. - bool ExpandedParameterPack; + bool ExpandedParameterPack = false; /// \brief The number of parameters in an expanded parameter pack. - unsigned NumExpandedParams; + unsigned NumExpandedParams = 0; TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, IdentifierInfo *Id, TemplateParameterList *Params) - : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), - TemplateParmPosition(D, P), ParameterPack(ParameterPack), - ExpandedParameterPack(false), NumExpandedParams(0) - { } + : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params), + TemplateParmPosition(D, P), ParameterPack(ParameterPack) {} TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, TemplateParameterList *Params, ArrayRef<TemplateParameterList *> Expansions); + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend TrailingObjects; + static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D, unsigned P, bool ParameterPack, @@ -1579,22 +1596,18 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == TemplateTemplateParm; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; - friend TrailingObjects; }; /// \brief Represents the builtin template declaration which is used to /// implement __make_integer_seq and other builtin templates. It serves /// no real purpose beyond existing as a place to hold template parameters. class BuiltinTemplateDecl : public TemplateDecl { - void anchor() override; + BuiltinTemplateKind BTK; BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, DeclarationName Name, BuiltinTemplateKind BTK); - BuiltinTemplateKind BTK; + void anchor() override; public: // Implement isa/cast/dyncast support @@ -1629,7 +1642,6 @@ public: /// \endcode class ClassTemplateSpecializationDecl : public CXXRecordDecl, public llvm::FoldingSetNode { - /// \brief Structure that stores information about a class template /// specialization that was instantiated from a class template partial /// specialization. @@ -1650,19 +1662,20 @@ class ClassTemplateSpecializationDecl /// \brief Further info for explicit template specialization/instantiation. struct ExplicitSpecializationInfo { /// \brief The type-as-written. - TypeSourceInfo *TypeAsWritten; + TypeSourceInfo *TypeAsWritten = nullptr; + /// \brief The location of the extern keyword. SourceLocation ExternLoc; + /// \brief The location of the template keyword. SourceLocation TemplateKeywordLoc; - ExplicitSpecializationInfo() - : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {} + ExplicitSpecializationInfo() = default; }; /// \brief Further info for explicit template specialization/instantiation. /// Does not apply to implicit specializations. - ExplicitSpecializationInfo *ExplicitInfo; + ExplicitSpecializationInfo *ExplicitInfo = nullptr; /// \brief The template arguments used to describe this specialization. const TemplateArgumentList *TemplateArgs; @@ -1685,6 +1698,9 @@ protected: explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ClassTemplateSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -1828,6 +1844,7 @@ public: ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; ExplicitInfo->TypeAsWritten = T; } + /// \brief Gets the type of this specialization as it was written by /// the user, if it was so written. TypeSourceInfo *getTypeAsWritten() const { @@ -1838,6 +1855,7 @@ public: SourceLocation getExternLoc() const { return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); } + /// \brief Sets the location of the extern keyword. void setExternLoc(SourceLocation Loc) { if (!ExplicitInfo) @@ -1851,6 +1869,7 @@ public: ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; ExplicitInfo->TemplateKeywordLoc = Loc; } + /// \brief Gets the location of the template keyword, if present. SourceLocation getTemplateKeywordLoc() const { return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); @@ -1871,25 +1890,21 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K >= firstClassTemplateSpecialization && K <= lastClassTemplateSpecialization; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; class ClassTemplatePartialSpecializationDecl : public ClassTemplateSpecializationDecl { - void anchor() override; - /// \brief The list of template parameters - TemplateParameterList* TemplateParams; + TemplateParameterList* TemplateParams = nullptr; /// \brief The source info for the template arguments as written. /// FIXME: redundant with TypeAsWritten? - const ASTTemplateArgumentListInfo *ArgsAsWritten; + const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; /// \brief The class template partial specialization from which this /// class template partial specialization was instantiated. @@ -1911,10 +1926,14 @@ class ClassTemplatePartialSpecializationDecl ClassTemplatePartialSpecializationDecl(ASTContext &C) : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization), - TemplateParams(nullptr), ArgsAsWritten(nullptr), InstantiatedFromMember(nullptr, false) {} + void anchor() override; + public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static ClassTemplatePartialSpecializationDecl * Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -2024,12 +2043,10 @@ public: // FIXME: Add Profile support! static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ClassTemplatePartialSpecialization; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// Declaration of a class template. @@ -2038,8 +2055,6 @@ protected: /// \brief Data that is common to all of the declarations of a given /// class template. struct Common : CommonBase { - Common() : LazySpecializations() { } - /// \brief The class template specializations for this class /// template, including explicit specializations and instantiations. llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations; @@ -2052,12 +2067,7 @@ protected: /// \brief The injected-class-name type for this class template. QualType InjectedClassNameType; - /// \brief If non-null, points to an array of specializations (including - /// partial specializations) known only by their external declaration IDs. - /// - /// The first value in the array is the number of of specializations/ - /// partial specializations that follow. - uint32_t *LazySpecializations; + Common() = default; }; /// \brief Retrieve the set of specializations of this class template. @@ -2087,12 +2097,15 @@ protected: } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + /// \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.getPointer()); + return static_cast<CXXRecordDecl *>(TemplatedDecl); } /// \brief Returns whether this template declaration defines the primary @@ -2132,14 +2145,11 @@ public: } /// \brief Retrieve the previous declaration of this class template, or - /// NULL if no such declaration exists. + /// nullptr if no such declaration exists. ClassTemplateDecl *getPreviousDecl() { return cast_or_null<ClassTemplateDecl>( static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } - - /// \brief Retrieve the previous declaration of this class template, or - /// NULL if no such declaration exists. const ClassTemplateDecl *getPreviousDecl() const { return cast_or_null<ClassTemplateDecl>( static_cast<const RedeclarableTemplateDecl *>( @@ -2180,7 +2190,7 @@ public: /// template. /// /// \returns the class template partial specialization that exactly matches - /// the type \p T, or NULL if no such partial specialization exists. + /// the type \p T, or nullptr if no such partial specialization exists. ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T); /// \brief Find a class template partial specialization which was instantiated @@ -2189,8 +2199,8 @@ public: /// \param D a member class template partial specialization. /// /// \returns the class template partial specialization which was instantiated - /// from the given member partial specialization, or NULL if no such partial - /// specialization exists. + /// from the given member partial specialization, or nullptr if no such + /// partial specialization exists. ClassTemplatePartialSpecializationDecl * findPartialSpecInstantiatedFromMember( ClassTemplatePartialSpecializationDecl *D); @@ -2211,8 +2221,8 @@ public: /// \endcode QualType getInjectedClassNameSpecialization(); - typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator; - typedef llvm::iterator_range<spec_iterator> spec_range; + using spec_iterator = SpecIterator<ClassTemplateSpecializationDecl>; + using spec_range = llvm::iterator_range<spec_iterator>; spec_range specializations() const { return spec_range(spec_begin(), spec_end()); @@ -2229,9 +2239,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ClassTemplate; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Declaration of a friend template. @@ -2249,15 +2256,16 @@ public: /// will yield a FriendDecl, not a FriendTemplateDecl. class FriendTemplateDecl : public Decl { virtual void anchor(); + public: - typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; + using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>; private: // The number of template parameters; always non-zero. - unsigned NumParams; + unsigned NumParams = 0; // The parameter list. - TemplateParameterList **Params; + TemplateParameterList **Params = nullptr; // The declaration that's a friend of this class. FriendUnion Friend; @@ -2271,13 +2279,11 @@ private: : Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()), Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {} - FriendTemplateDecl(EmptyShell Empty) - : Decl(Decl::FriendTemplate, Empty), - NumParams(0), - Params(nullptr) - {} + FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {} public: + friend class ASTDeclReader; + static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend, @@ -2316,8 +2322,6 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::FriendTemplate; } - - friend class ASTDeclReader; }; /// \brief Declaration of an alias template. @@ -2328,7 +2332,7 @@ public: /// \endcode class TypeAliasTemplateDecl : public RedeclarableTemplateDecl { protected: - typedef CommonBase Common; + using Common = CommonBase; TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, @@ -2343,9 +2347,12 @@ protected: } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + /// Get the underlying function declaration of the template. TypeAliasDecl *getTemplatedDecl() const { - return static_cast<TypeAliasDecl *>(TemplatedDecl.getPointer()); + return static_cast<TypeAliasDecl *>(TemplatedDecl); } @@ -2359,14 +2366,11 @@ public: } /// \brief Retrieve the previous declaration of this function template, or - /// NULL if no such declaration exists. + /// nullptr if no such declaration exists. TypeAliasTemplateDecl *getPreviousDecl() { return cast_or_null<TypeAliasTemplateDecl>( static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } - - /// \brief Retrieve the previous declaration of this function template, or - /// NULL if no such declaration exists. const TypeAliasTemplateDecl *getPreviousDecl() const { return cast_or_null<TypeAliasTemplateDecl>( static_cast<const RedeclarableTemplateDecl *>( @@ -2378,7 +2382,6 @@ public: RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } - /// \brief Create a function template node. static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -2392,9 +2395,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == TypeAliasTemplate; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// \brief Declaration of a function specialization at template class scope. @@ -2414,7 +2414,9 @@ public: /// CXXMethodDecl. Then during an instantiation of class A, it will be /// transformed into an actual function specialization. class ClassScopeFunctionSpecializationDecl : public Decl { - virtual void anchor(); + CXXMethodDecl *Specialization; + bool HasExplicitTemplateArgs; + TemplateArgumentListInfo TemplateArgs; ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, bool Args, @@ -2424,13 +2426,14 @@ class ClassScopeFunctionSpecializationDecl : public Decl { TemplateArgs(std::move(TemplArgs)) {} ClassScopeFunctionSpecializationDecl(EmptyShell Empty) - : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} + : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} - CXXMethodDecl *Specialization; - bool HasExplicitTemplateArgs; - TemplateArgumentListInfo TemplateArgs; + virtual void anchor(); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + CXXMethodDecl *getSpecialization() const { return Specialization; } bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; } const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; } @@ -2450,17 +2453,15 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Decl::ClassScopeFunctionSpecialization; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// Implementation of inline functions that require the template declarations inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD) - : Function(FTD) { } + : Function(FTD) {} /// \brief Represents a variable template specialization, which refers to /// a variable template with a given set of template arguments. @@ -2498,19 +2499,20 @@ class VarTemplateSpecializationDecl : public VarDecl, /// \brief Further info for explicit template specialization/instantiation. struct ExplicitSpecializationInfo { /// \brief The type-as-written. - TypeSourceInfo *TypeAsWritten; + TypeSourceInfo *TypeAsWritten = nullptr; + /// \brief The location of the extern keyword. SourceLocation ExternLoc; + /// \brief The location of the template keyword. SourceLocation TemplateKeywordLoc; - ExplicitSpecializationInfo() - : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {} + ExplicitSpecializationInfo() = default; }; /// \brief Further info for explicit template specialization/instantiation. /// Does not apply to implicit specializations. - ExplicitSpecializationInfo *ExplicitInfo; + ExplicitSpecializationInfo *ExplicitInfo = nullptr; /// \brief The template arguments used to describe this specialization. const TemplateArgumentList *TemplateArgs; @@ -2523,6 +2525,12 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Really a value of type TemplateSpecializationKind. unsigned SpecializationKind : 3; + /// \brief Whether this declaration is a complete definition of the + /// variable template specialization. We can't otherwise tell apart + /// an instantiated declaration from an instantiated definition with + /// no initializer. + unsigned IsCompleteDefinition : 1; + protected: VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -2534,6 +2542,10 @@ protected: explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context); public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class VarDecl; + static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, @@ -2596,6 +2608,8 @@ public: PointOfInstantiation = Loc; } + void setCompleteDefinition() { IsCompleteDefinition = true; } + /// \brief If this variable template specialization is an instantiation of /// a template (rather than an explicit specialization), return the /// variable template or variable template partial specialization from which @@ -2668,6 +2682,7 @@ public: ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; ExplicitInfo->TypeAsWritten = T; } + /// \brief Gets the type of this specialization as it was written by /// the user, if it was so written. TypeSourceInfo *getTypeAsWritten() const { @@ -2678,6 +2693,7 @@ public: SourceLocation getExternLoc() const { return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation(); } + /// \brief Sets the location of the extern keyword. void setExternLoc(SourceLocation Loc) { if (!ExplicitInfo) @@ -2691,6 +2707,7 @@ public: ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo; ExplicitInfo->TemplateKeywordLoc = Loc; } + /// \brief Gets the location of the template keyword, if present. SourceLocation getTemplateKeywordLoc() const { return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); @@ -2709,25 +2726,21 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K >= firstVarTemplateSpecialization && K <= lastVarTemplateSpecialization; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; class VarTemplatePartialSpecializationDecl : public VarTemplateSpecializationDecl { - void anchor() override; - /// \brief The list of template parameters - TemplateParameterList *TemplateParams; + TemplateParameterList *TemplateParams = nullptr; /// \brief The source info for the template arguments as written. /// FIXME: redundant with TypeAsWritten? - const ASTTemplateArgumentListInfo *ArgsAsWritten; + const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr; /// \brief The variable template partial specialization from which this /// variable template partial specialization was instantiated. @@ -2745,11 +2758,16 @@ class VarTemplatePartialSpecializationDecl const ASTTemplateArgumentListInfo *ArgInfos); VarTemplatePartialSpecializationDecl(ASTContext &Context) - : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context), - TemplateParams(nullptr), ArgsAsWritten(nullptr), - InstantiatedFromMember(nullptr, false) {} + : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, + Context), + InstantiatedFromMember(nullptr, false) {} + + void anchor() override; public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + static VarTemplatePartialSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, @@ -2841,12 +2859,10 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == VarTemplatePartialSpecialization; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; /// Declaration of a variable template. @@ -2855,8 +2871,6 @@ protected: /// \brief Data that is common to all of the declarations of a given /// variable template. struct Common : CommonBase { - Common() : LazySpecializations() {} - /// \brief The variable template specializations for this variable /// template, including explicit specializations and instantiations. llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations; @@ -2866,12 +2880,7 @@ protected: llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> PartialSpecializations; - /// \brief If non-null, points to an array of specializations (including - /// partial specializations) known ownly by their external declaration IDs. - /// - /// The first value in the array is the number of of specializations/ - /// partial specializations that follow. - uint32_t *LazySpecializations; + Common() = default; }; /// \brief Retrieve the set of specializations of this variable template. @@ -2895,12 +2904,15 @@ protected: } public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + /// \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.getPointer()); + return static_cast<VarDecl *>(TemplatedDecl); } /// \brief Returns whether this template declaration defines the primary @@ -2937,14 +2949,11 @@ public: } /// \brief Retrieve the previous declaration of this variable template, or - /// NULL if no such declaration exists. + /// nullptr if no such declaration exists. VarTemplateDecl *getPreviousDecl() { return cast_or_null<VarTemplateDecl>( static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl()); } - - /// \brief Retrieve the previous declaration of this variable template, or - /// NULL if no such declaration exists. const VarTemplateDecl *getPreviousDecl() const { return cast_or_null<VarTemplateDecl>( static_cast<const RedeclarableTemplateDecl *>( @@ -2986,13 +2995,13 @@ public: /// /// \returns the variable template partial specialization which was /// instantiated - /// from the given member partial specialization, or NULL if no such partial - /// specialization exists. + /// from the given member partial specialization, or nullptr if no such + /// partial specialization exists. VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember( VarTemplatePartialSpecializationDecl *D); - typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator; - typedef llvm::iterator_range<spec_iterator> spec_range; + using spec_iterator = SpecIterator<VarTemplateSpecializationDecl>; + using spec_range = llvm::iterator_range<spec_iterator>; spec_range specializations() const { return spec_range(spec_begin(), spec_end()); @@ -3009,9 +3018,6 @@ public: // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == VarTemplate; } - - friend class ASTDeclReader; - friend class ASTDeclWriter; }; inline NamedDecl *getAsNamedDecl(TemplateParameter P) { @@ -3032,6 +3038,6 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) { : nullptr; } -} /* end of namespace clang */ +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DECLTEMPLATE_H diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h index 4eaae35778b9..3ff274bd6a7a 100644 --- a/include/clang/AST/DeclVisitor.h +++ b/include/clang/AST/DeclVisitor.h @@ -1,4 +1,4 @@ -//===--- DeclVisitor.h - Visitor for Decl subclasses ------------*- C++ -*-===// +//===- DeclVisitor.h - Visitor for Decl subclasses --------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,27 +10,30 @@ // This file defines the DeclVisitor interface. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_DECLVISITOR_H #define LLVM_CLANG_AST_DECLVISITOR_H #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { + namespace declvisitor { -template <typename T> struct make_ptr { typedef T *type; }; -template <typename T> struct make_const_ptr { typedef const T *type; }; +template <typename T> struct make_ptr { using type = T *; }; +template <typename T> struct make_const_ptr { using type = const T *; }; /// \brief A simple visitor class that helps create declaration visitors. template<template <typename> class Ptr, typename ImplClass, typename RetTy=void> class Base { public: - #define PTR(CLASS) typename Ptr<CLASS>::type #define DISPATCH(NAME, CLASS) \ return static_cast<ImplClass*>(this)->Visit##NAME(static_cast<PTR(CLASS)>(D)) @@ -57,23 +60,23 @@ public: #undef DISPATCH }; -} // end namespace declvisitor +} // namespace declvisitor /// \brief A simple visitor class that helps create declaration visitors. /// /// This class does not preserve constness of Decl pointers (see also /// ConstDeclVisitor). -template<typename ImplClass, typename RetTy=void> +template<typename ImplClass, typename RetTy = void> class DeclVisitor : public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {}; /// \brief A simple visitor class that helps create declaration visitors. /// /// This class preserves constness of Decl pointers (see also DeclVisitor). -template<typename ImplClass, typename RetTy=void> +template<typename ImplClass, typename RetTy = void> class ConstDeclVisitor : public declvisitor::Base<declvisitor::make_const_ptr, ImplClass, RetTy> {}; -} // end namespace clang +} // namespace clang #endif // LLVM_CLANG_AST_DECLVISITOR_H diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 5e773c968384..467b02c52b0c 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -1,4 +1,4 @@ -//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===// +//===- DeclarationName.h - Representation of declaration names --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -10,36 +10,42 @@ // This file declares the DeclarationName and DeclarationNameTable classes. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_DECLARATIONNAME_H #define LLVM_CLANG_AST_DECLARATIONNAME_H +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/Compiler.h" - -namespace llvm { - template <typename T> struct DenseMapInfo; -} +#include "llvm/Support/type_traits.h" +#include <cassert> +#include <cstdint> +#include <cstring> +#include <string> namespace clang { - class ASTContext; - class CXXDeductionGuideNameExtra; - class CXXLiteralOperatorIdName; - class CXXOperatorIdName; - class CXXSpecialName; - class DeclarationNameExtra; - class IdentifierInfo; - class MultiKeywordSelector; - enum OverloadedOperatorKind : int; - struct PrintingPolicy; - class QualType; - class TemplateDecl; - class Type; - class TypeSourceInfo; - class UsingDirectiveDecl; - - template <typename> class CanQual; - typedef CanQual<Type> CanQualType; + +class ASTContext; +template <typename> class CanQual; +class CXXDeductionGuideNameExtra; +class CXXLiteralOperatorIdName; +class CXXOperatorIdName; +class CXXSpecialName; +class DeclarationNameExtra; +class IdentifierInfo; +class MultiKeywordSelector; +enum OverloadedOperatorKind : int; +struct PrintingPolicy; +class QualType; +class TemplateDecl; +class Type; +class TypeSourceInfo; +class UsingDirectiveDecl; + +using CanQualType = CanQual<Type>; /// DeclarationName - The name of a declaration. In the common case, /// this just stores an IdentifierInfo pointer to a normal @@ -63,9 +69,13 @@ public: CXXLiteralOperatorName, CXXUsingDirective }; + static const unsigned NumNameKinds = CXXUsingDirective + 1; private: + friend class DeclarationNameTable; + friend class NamedDecl; + /// StoredNameKind - The kind of name that is actually stored in the /// upper bits of the Ptr field. This is only used internally. /// @@ -99,7 +109,18 @@ private: /// DeclarationNameExtra structure, whose first value will tell us /// whether this is an Objective-C selector, C++ operator-id name, /// or special C++ name. - uintptr_t Ptr; + uintptr_t Ptr = 0; + + // Construct a declaration name from the name of a C++ constructor, + // destructor, or conversion function. + DeclarationName(DeclarationNameExtra *Name) + : Ptr(reinterpret_cast<uintptr_t>(Name)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra"); + Ptr |= StoredDeclarationNameExtra; + } + + /// Construct a declaration name from a raw pointer. + DeclarationName(uintptr_t Ptr) : Ptr(Ptr) {} /// getStoredNameKind - Return the kind of object that is stored in /// Ptr. @@ -146,36 +167,22 @@ private: return nullptr; } - // Construct a declaration name from the name of a C++ constructor, - // destructor, or conversion function. - DeclarationName(DeclarationNameExtra *Name) - : Ptr(reinterpret_cast<uintptr_t>(Name)) { - assert((Ptr & PtrMask) == 0 && "Improperly aligned DeclarationNameExtra"); - Ptr |= StoredDeclarationNameExtra; - } - - /// Construct a declaration name from a raw pointer. - DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { } - - friend class DeclarationNameTable; - friend class NamedDecl; - /// getFETokenInfoAsVoidSlow - Retrieves the front end-specified pointer /// for this name as a void pointer if it's not an identifier. void *getFETokenInfoAsVoidSlow() const; public: /// DeclarationName - Used to create an empty selector. - DeclarationName() : Ptr(0) { } + DeclarationName() = default; // Construct a declaration name from an IdentifierInfo *. DeclarationName(const IdentifierInfo *II) - : Ptr(reinterpret_cast<uintptr_t>(II)) { + : Ptr(reinterpret_cast<uintptr_t>(II)) { assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo"); } // Construct a declaration name from an Objective-C selector. - DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { } + DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) {} /// getUsingDirectiveName - Return name for all using-directives. static DeclarationName getUsingDirectiveName(); @@ -344,16 +351,24 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) { /// getCXXConstructorName). class DeclarationNameTable { const ASTContext &Ctx; - void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> * - CXXOperatorIdName *CXXOperatorNames; // Operator names - void *CXXLiteralOperatorNames; // Actually a CXXOperatorIdName* - void *CXXDeductionGuideNames; // FoldingSet<CXXDeductionGuideNameExtra> * - DeclarationNameTable(const DeclarationNameTable&) = delete; - void operator=(const DeclarationNameTable&) = delete; + // Actually a FoldingSet<CXXSpecialName> * + void *CXXSpecialNamesImpl; + + // Operator names + CXXOperatorIdName *CXXOperatorNames; + + // Actually a CXXOperatorIdName* + void *CXXLiteralOperatorNames; + + // FoldingSet<CXXDeductionGuideNameExtra> * + void *CXXDeductionGuideNames; public: DeclarationNameTable(const ASTContext &C); + DeclarationNameTable(const DeclarationNameTable &) = delete; + DeclarationNameTable &operator=(const DeclarationNameTable &) = delete; + ~DeclarationNameTable(); /// getIdentifier - Create a declaration name that is a simple @@ -428,10 +443,10 @@ struct DeclarationNameLoc { }; DeclarationNameLoc(DeclarationName Name); + // FIXME: this should go away once all DNLocs are properly initialized. DeclarationNameLoc() { memset((void*) this, 0, sizeof(*this)); } -}; // struct DeclarationNameLoc - +}; /// DeclarationNameInfo - A collector data type for bundling together /// a DeclarationName and the correspnding source/type location info. @@ -439,29 +454,33 @@ struct DeclarationNameInfo { private: /// Name - The declaration name, also encoding name kind. DeclarationName Name; + /// Loc - The main source location for the declaration name. SourceLocation NameLoc; + /// Info - Further source/type location info for special kinds of names. DeclarationNameLoc LocInfo; public: // FIXME: remove it. - DeclarationNameInfo() {} + DeclarationNameInfo() = default; DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc) - : Name(Name), NameLoc(NameLoc), LocInfo(Name) {} + : Name(Name), NameLoc(NameLoc), LocInfo(Name) {} DeclarationNameInfo(DeclarationName Name, SourceLocation NameLoc, DeclarationNameLoc LocInfo) - : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {} + : Name(Name), NameLoc(NameLoc), LocInfo(LocInfo) {} /// getName - Returns the embedded declaration name. DeclarationName getName() const { return Name; } + /// setName - Sets the embedded declaration name. void setName(DeclarationName N) { Name = N; } /// getLoc - Returns the main location of the declaration name. SourceLocation getLoc() const { return NameLoc; } + /// setLoc - Sets the main location of the declaration name. void setLoc(SourceLocation L) { NameLoc = L; } @@ -477,6 +496,7 @@ public: Name.getNameKind() == DeclarationName::CXXConversionFunctionName); return LocInfo.NamedType.TInfo; } + /// setNamedTypeInfo - Sets the source type info associated to /// the name. Assumes it is a constructor, destructor or conversion. void setNamedTypeInfo(TypeSourceInfo *TInfo) { @@ -495,6 +515,7 @@ public: SourceLocation::getFromRawEncoding(LocInfo.CXXOperatorName.EndOpNameLoc) ); } + /// setCXXOperatorNameRange - Sets the range of the operator name /// (without the operator keyword). Assumes it is a C++ operator. void setCXXOperatorNameRange(SourceRange R) { @@ -511,6 +532,7 @@ public: return SourceLocation:: getFromRawEncoding(LocInfo.CXXLiteralOperatorName.OpNameLoc); } + /// setCXXLiteralOperatorNameLoc - Sets the location of the literal /// operator name (not the operator keyword). /// Assumes it is a literal operator. @@ -534,15 +556,19 @@ public: /// getBeginLoc - Retrieve the location of the first token. SourceLocation getBeginLoc() const { return NameLoc; } + /// getEndLoc - Retrieve the location of the last token. SourceLocation getEndLoc() const; + /// getSourceRange - The range of the declaration name. SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocStart(), getLocEnd()); } + SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { SourceLocation EndLoc = getEndLoc(); return EndLoc.isValid() ? EndLoc : getLocStart(); @@ -573,9 +599,10 @@ inline raw_ostream &operator<<(raw_ostream &OS, return OS; } -} // end namespace clang +} // namespace clang namespace llvm { + /// Define DenseMapInfo so that DeclarationNames can be used as keys /// in DenseMap and DenseSets. template<> @@ -601,6 +628,6 @@ struct DenseMapInfo<clang::DeclarationName> { template <> struct isPodLike<clang::DeclarationName> { static const bool value = true; }; -} // end namespace llvm +} // namespace llvm -#endif +#endif // LLVM_CLANG_AST_DECLARATIONNAME_H diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h index 8e038c83c989..a514326c6cb1 100644 --- a/include/clang/AST/DependentDiagnostic.h +++ b/include/clang/AST/DependentDiagnostic.h @@ -1,4 +1,4 @@ -//===-- DependentDiagnostic.h - Dependently-generated diagnostics -*- C++ -*-=// +//==- DependentDiagnostic.h - Dependently-generated diagnostics --*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -23,6 +23,9 @@ #include "clang/AST/Type.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include <cassert> +#include <iterator> namespace clang { @@ -94,6 +97,9 @@ public: } private: + friend class DeclContext::ddiag_iterator; + friend class DependentStoredDeclsMap; + DependentDiagnostic(const PartialDiagnostic &PDiag, PartialDiagnostic::Storage *Storage) : Diag(PDiag, Storage) {} @@ -102,8 +108,6 @@ private: DeclContext *Parent, const PartialDiagnostic &PDiag); - friend class DependentStoredDeclsMap; - friend class DeclContext::ddiag_iterator; DependentDiagnostic *NextDiagnostic; PartialDiagnostic Diag; @@ -118,19 +122,17 @@ private: } AccessData; }; -/// - /// An iterator over the dependent diagnostics in a dependent context. class DeclContext::ddiag_iterator { public: - ddiag_iterator() : Ptr(nullptr) {} + ddiag_iterator() = default; explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {} - typedef DependentDiagnostic *value_type; - typedef DependentDiagnostic *reference; - typedef DependentDiagnostic *pointer; - typedef int difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = DependentDiagnostic *; + using reference = DependentDiagnostic *; + using pointer = DependentDiagnostic *; + using difference_type = int; + using iterator_category = std::forward_iterator_tag; reference operator*() const { return Ptr; } @@ -168,7 +170,7 @@ public: } private: - DependentDiagnostic *Ptr; + DependentDiagnostic *Ptr = nullptr; }; inline DeclContext::ddiag_range DeclContext::ddiags() const { @@ -184,6 +186,6 @@ inline DeclContext::ddiag_range DeclContext::ddiags() const { return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator()); } -} +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_DEPENDENTDIAGNOSTIC_H diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 0cdbd2a97ee4..f2770940372f 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -24,6 +24,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/SyncScope.h" #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" @@ -274,6 +275,7 @@ public: MLV_LValueCast, // Specialized form of MLV_InvalidExpression. MLV_IncompleteType, MLV_ConstQualified, + MLV_ConstQualifiedField, MLV_ConstAddrSpace, MLV_ArrayType, MLV_NoSetterProperty, @@ -323,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_ConstQualifiedField, CM_ConstAddrSpace, CM_ArrayType, CM_IncompleteType @@ -2345,6 +2348,12 @@ public: SourceLocation getLocStart() const LLVM_READONLY; SourceLocation getLocEnd() const LLVM_READONLY; + bool isCallToStdMove() const { + const FunctionDecl* FD = getDirectCallee(); + return getNumArgs() == 1 && FD && FD->isInStdNamespace() && + FD->getIdentifier() && FD->getIdentifier()->isStr("move"); + } + static bool classof(const Stmt *T) { return T->getStmtClass() >= firstCallExprConstant && T->getStmtClass() <= lastCallExprConstant; @@ -2733,7 +2742,6 @@ protected: ty->containsUnexpandedParameterPack()) || (op && op->containsUnexpandedParameterPack()))), Op(op) { - assert(kind != CK_Invalid && "creating cast with invalid cast kind"); CastExprBits.Kind = kind; setBasePathSize(BasePathSize); assert(CastConsistency()); @@ -2771,6 +2779,16 @@ public: path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_end() const { return path_buffer() + path_size(); } + const FieldDecl *getTargetUnionField() const { + assert(getCastKind() == CK_ToUnion); + return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType()); + } + + static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType, + QualType opType); + static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD, + QualType opType); + static bool classof(const Stmt *T) { return T->getStmtClass() >= firstCastExprConstant && T->getStmtClass() <= lastCastExprConstant; @@ -3054,7 +3072,7 @@ public: static bool isEqualityOp(Opcode Opc) { return Opc == BO_EQ || Opc == BO_NE; } bool isEqualityOp() const { return isEqualityOp(getOpcode()); } - static bool isComparisonOp(Opcode Opc) { return Opc >= BO_LT && Opc<=BO_NE; } + static bool isComparisonOp(Opcode Opc) { return Opc >= BO_Cmp && Opc<=BO_NE; } bool isComparisonOp() const { return isComparisonOp(getOpcode()); } static Opcode negateComparisonOp(Opcode Opc) { @@ -3113,6 +3131,12 @@ public: return isShiftAssignOp(getOpcode()); } + // Return true if a binary operator using the specified opcode and operands + // would match the 'p = (i8*)nullptr + n' idiom for casting a pointer-sized + // integer to a pointer. + static bool isNullPointerArithmeticExtension(ASTContext &Ctx, Opcode Opc, + Expr *LHS, Expr *RHS); + static bool classof(const Stmt *S) { return S->getStmtClass() >= firstBinaryOperatorConstant && S->getStmtClass() <= lastBinaryOperatorConstant; @@ -3986,6 +4010,10 @@ public: /// initializer)? bool isTransparent() const; + /// Is this the zero initializer {0} in a language which considers it + /// idiomatic? + bool isIdiomaticZeroInitializer(const LangOptions &LangOpts) const; + SourceLocation getLBraceLoc() const { return LBraceLoc; } void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -3995,6 +4023,9 @@ public: InitListExpr *getSemanticForm() const { return isSemanticForm() ? nullptr : AltForm.getPointer(); } + bool isSyntacticForm() const { + return !AltForm.getInt() || !AltForm.getPointer(); + } InitListExpr *getSyntacticForm() const { return isSemanticForm() ? AltForm.getPointer() : nullptr; } @@ -5064,9 +5095,11 @@ public: /// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, /// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the -/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>. -/// All of these instructions take one primary pointer and at least one memory -/// order. +/// similarly-named C++11 instructions, and __c11 variants for <stdatomic.h>, +/// and corresponding __opencl_atomic_* for OpenCL 2.0. +/// All of these instructions take one primary pointer, at least one memory +/// order. The instructions for which getScopeModel returns non-null value +/// take one synch scope. class AtomicExpr : public Expr { public: enum AtomicOp { @@ -5078,14 +5111,16 @@ public: }; private: + /// \brief Location of sub-expressions. + /// The location of Scope sub-expression is NumSubExprs - 1, which is + /// not fixed, therefore is not defined in enum. enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR }; - Stmt* SubExprs[END_EXPR]; + Stmt *SubExprs[END_EXPR + 1]; unsigned NumSubExprs; SourceLocation BuiltinLoc, RParenLoc; AtomicOp Op; friend class ASTStmtReader; - public: AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args, QualType t, AtomicOp op, SourceLocation RP); @@ -5103,8 +5138,12 @@ public: Expr *getOrder() const { return cast<Expr>(SubExprs[ORDER]); } + Expr *getScope() const { + assert(getScopeModel() && "No scope"); + return cast<Expr>(SubExprs[NumSubExprs - 1]); + } Expr *getVal1() const { - if (Op == AO__c11_atomic_init) + if (Op == AO__c11_atomic_init || Op == AO__opencl_atomic_init) return cast<Expr>(SubExprs[ORDER]); assert(NumSubExprs > VAL1); return cast<Expr>(SubExprs[VAL1]); @@ -5123,6 +5162,7 @@ public: assert(NumSubExprs > WEAK); return cast<Expr>(SubExprs[WEAK]); } + QualType getValueType() const; AtomicOp getOp() const { return Op; } unsigned getNumSubExprs() const { return NumSubExprs; } @@ -5139,10 +5179,17 @@ public: bool isCmpXChg() const { return getOp() == AO__c11_atomic_compare_exchange_strong || getOp() == AO__c11_atomic_compare_exchange_weak || + getOp() == AO__opencl_atomic_compare_exchange_strong || + getOp() == AO__opencl_atomic_compare_exchange_weak || getOp() == AO__atomic_compare_exchange || getOp() == AO__atomic_compare_exchange_n; } + bool isOpenCL() const { + return getOp() >= AO__opencl_atomic_init && + getOp() <= AO__opencl_atomic_fetch_max; + } + SourceLocation getBuiltinLoc() const { return BuiltinLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -5160,6 +5207,24 @@ public: const_child_range children() const { return const_child_range(SubExprs, SubExprs + NumSubExprs); } + + /// \brief Get atomic scope model for the atomic op code. + /// \return empty atomic scope model if the atomic op code does not have + /// scope operand. + static std::unique_ptr<AtomicScopeModel> getScopeModel(AtomicOp Op) { + auto Kind = + (Op >= AO__opencl_atomic_load && Op <= AO__opencl_atomic_fetch_max) + ? AtomicScopeModelKind::OpenCL + : AtomicScopeModelKind::None; + return AtomicScopeModel::create(Kind); + } + + /// \brief Get atomic scope model. + /// \return empty atomic scope model if this atomic expression does not have + /// scope operand. + std::unique_ptr<AtomicScopeModel> getScopeModel() const { + return getScopeModel(getOp()); + } }; /// TypoExpr - Internal placeholder for expressions where typo correction diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 79d2c58099c4..58054dda31aa 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1,4 +1,4 @@ -//===--- ExprCXX.h - Classes for representing expressions -------*- C++ -*-===// +//===- ExprCXX.h - Classes for representing expressions ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,31 +6,57 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the clang::Expr interface and subclasses for C++ expressions. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_EXPRCXX_H #define LLVM_CLANG_AST_EXPRCXX_H #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" -#include "clang/AST/LambdaCapture.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/OperationKinds.h" +#include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" #include "clang/AST/UnresolvedSet.h" +#include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/ExpressionTraits.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/Lambda.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" #include "clang/Basic/TypeTraits.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> namespace clang { -class CXXTemporary; -class MSPropertyDecl; -class TemplateArgumentListInfo; -class UuidAttr; +class ASTContext; +class DeclAccessPair; +class IdentifierInfo; +class LambdaCapture; +class NonTypeTemplateParmDecl; +class TemplateParameterList; //===--------------------------------------------------------------------===// // C++ Expressions. @@ -52,23 +78,28 @@ class UuidAttr; class CXXOperatorCallExpr : public CallExpr { /// \brief The overloaded operator. OverloadedOperatorKind Operator; + SourceRange Range; // Only meaningful for floating point types. FPOptions FPFeatures; SourceRange getSourceRangeImpl() const LLVM_READONLY; + public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation operatorloc, FPOptions FPFeatures) - : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc), - Operator(Op), FPFeatures(FPFeatures) { + : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc), + Operator(Op), FPFeatures(FPFeatures) { Range = getSourceRangeImpl(); } - explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) : - CallExpr(C, CXXOperatorCallExprClass, Empty) { } + explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) + : CallExpr(C, CXXOperatorCallExprClass, Empty) {} /// \brief Returns the kind of overloaded operator that this /// expression refers to. @@ -120,9 +151,6 @@ public: bool isFPContractableWithinStatement() const { return FPFeatures.allowFPContractWithinStatement(); } - - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// Represents a call to a member function that @@ -137,10 +165,10 @@ class CXXMemberCallExpr : public CallExpr { public: CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {} + : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) - : CallExpr(C, CXXMemberCallExprClass, Empty) { } + : CallExpr(C, CXXMemberCallExprClass, Empty) {} /// \brief Retrieves the implicit object argument for the member call. /// @@ -183,7 +211,7 @@ public: : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {} CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty) - : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { } + : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) {} const CallExpr *getConfig() const { return cast_or_null<CallExpr>(getPreArg(CONFIG)); @@ -217,23 +245,28 @@ public: /// reinterpret_cast, and CXXConstCastExpr for \c const_cast. class CXXNamedCastExpr : public ExplicitCastExpr { private: - SourceLocation Loc; // the location of the casting op - SourceLocation RParenLoc; // the location of the right parenthesis - SourceRange AngleBrackets; // range for '<' '>' + // the location of the casting op + SourceLocation Loc; + + // the location of the right parenthesis + SourceLocation RParenLoc; + + // range for '<' '>' + SourceRange AngleBrackets; protected: + friend class ASTStmtReader; + CXXNamedCastExpr(StmtClass SC, QualType ty, ExprValueKind VK, CastKind kind, Expr *op, unsigned PathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, SourceRange AngleBrackets) - : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l), - RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {} + : ExplicitCastExpr(SC, ty, VK, kind, op, PathSize, writtenTy), Loc(l), + RParenLoc(RParenLoc), AngleBrackets(AngleBrackets) {} explicit CXXNamedCastExpr(StmtClass SC, EmptyShell Shell, unsigned PathSize) - : ExplicitCastExpr(SC, Shell, PathSize) { } - - friend class ASTStmtReader; + : ExplicitCastExpr(SC, Shell, PathSize) {} public: const char *getCastName() const; @@ -273,13 +306,16 @@ class CXXStaticCastExpr final unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, SourceRange AngleBrackets) - : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, - writtenTy, l, RParenLoc, AngleBrackets) {} + : CXXNamedCastExpr(CXXStaticCastExprClass, ty, vk, kind, op, pathSize, + writtenTy, l, RParenLoc, AngleBrackets) {} explicit CXXStaticCastExpr(EmptyShell Empty, unsigned PathSize) - : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) { } + : CXXNamedCastExpr(CXXStaticCastExprClass, Empty, PathSize) {} public: + friend class CastExpr; + friend TrailingObjects; + static CXXStaticCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, @@ -292,9 +328,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXStaticCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; /// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). @@ -309,13 +342,16 @@ class CXXDynamicCastExpr final Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, SourceRange AngleBrackets) - : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, - writtenTy, l, RParenLoc, AngleBrackets) {} + : CXXNamedCastExpr(CXXDynamicCastExprClass, ty, VK, kind, op, pathSize, + writtenTy, l, RParenLoc, AngleBrackets) {} explicit CXXDynamicCastExpr(EmptyShell Empty, unsigned pathSize) - : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) { } + : CXXNamedCastExpr(CXXDynamicCastExprClass, Empty, pathSize) {} public: + friend class CastExpr; + friend TrailingObjects; + static CXXDynamicCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, @@ -331,9 +367,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; /// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). @@ -353,13 +386,16 @@ class CXXReinterpretCastExpr final TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, SourceRange AngleBrackets) - : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, - pathSize, writtenTy, l, RParenLoc, AngleBrackets) {} + : CXXNamedCastExpr(CXXReinterpretCastExprClass, ty, vk, kind, op, + pathSize, writtenTy, l, RParenLoc, AngleBrackets) {} CXXReinterpretCastExpr(EmptyShell Empty, unsigned pathSize) - : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) { } + : CXXNamedCastExpr(CXXReinterpretCastExprClass, Empty, pathSize) {} public: + friend class CastExpr; + friend TrailingObjects; + static CXXReinterpretCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, @@ -372,9 +408,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXReinterpretCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; /// \brief A C++ \c const_cast expression (C++ [expr.const.cast]). @@ -390,13 +423,16 @@ class CXXConstCastExpr final CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, SourceRange AngleBrackets) - : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, - 0, writtenTy, l, RParenLoc, AngleBrackets) {} + : CXXNamedCastExpr(CXXConstCastExprClass, ty, VK, CK_NoOp, op, + 0, writtenTy, l, RParenLoc, AngleBrackets) {} explicit CXXConstCastExpr(EmptyShell Empty) - : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) { } + : CXXNamedCastExpr(CXXConstCastExprClass, Empty, 0) {} public: + friend class CastExpr; + friend TrailingObjects; + static CXXConstCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, @@ -407,9 +443,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; /// \brief A call to a literal operator (C++11 [over.literal]) @@ -426,22 +459,37 @@ class UserDefinedLiteral : public CallExpr { SourceLocation UDSuffixLoc; public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) - : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc), - UDSuffixLoc(SuffixLoc) {} + : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc), + UDSuffixLoc(SuffixLoc) {} + explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) - : CallExpr(C, UserDefinedLiteralClass, Empty) {} + : CallExpr(C, UserDefinedLiteralClass, Empty) {} /// The kind of literal operator which is invoked. enum LiteralOperatorKind { - LOK_Raw, ///< Raw form: operator "" X (const char *) - LOK_Template, ///< Raw form: operator "" X<cs...> () - LOK_Integer, ///< operator "" X (unsigned long long) - LOK_Floating, ///< operator "" X (long double) - LOK_String, ///< operator "" X (const CharT *, size_t) - LOK_Character ///< operator "" X (CharT) + /// Raw form: operator "" X (const char *) + LOK_Raw, + + /// Raw form: operator "" X<cs...> () + LOK_Template, + + /// operator "" X (unsigned long long) + LOK_Integer, + + /// operator "" X (long double) + LOK_Floating, + + /// operator "" X (const CharT *, size_t) + LOK_String, + + /// operator "" X (CharT) + LOK_Character }; /// \brief Returns the kind of literal operator invocation @@ -461,8 +509,8 @@ public: return getRParenLoc(); return getArg(0)->getLocStart(); } - SourceLocation getLocEnd() const { return getRParenLoc(); } + SourceLocation getLocEnd() const { return getRParenLoc(); } /// \brief Returns the location of a ud-suffix in the expression. /// @@ -476,24 +524,21 @@ public: static bool classof(const Stmt *S) { return S->getStmtClass() == UserDefinedLiteralClass; } - - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief A boolean literal, per ([C++ lex.bool] Boolean literals). -/// class CXXBoolLiteralExpr : public Expr { bool Value; SourceLocation Loc; + public: - CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : - Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), - Value(val), Loc(l) {} + CXXBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) + : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + false, false), + Value(val), Loc(l) {} explicit CXXBoolLiteralExpr(EmptyShell Empty) - : Expr(CXXBoolLiteralExprClass, Empty) { } + : Expr(CXXBoolLiteralExprClass, Empty) {} bool getValue() const { return Value; } void setValue(bool V) { Value = V; } @@ -519,14 +564,15 @@ public: /// Introduced in C++11, the only literal of type \c nullptr_t is \c nullptr. class CXXNullPtrLiteralExpr : public Expr { SourceLocation Loc; + public: - CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) : - Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), - Loc(l) {} + CXXNullPtrLiteralExpr(QualType Ty, SourceLocation l) + : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, + false, false, false), + Loc(l) {} explicit CXXNullPtrLiteralExpr(EmptyShell Empty) - : Expr(CXXNullPtrLiteralExprClass, Empty) { } + : Expr(CXXNullPtrLiteralExprClass, Empty) {} SourceLocation getLocStart() const LLVM_READONLY { return Loc; } SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } @@ -546,18 +592,21 @@ public: /// \brief Implicit construction of a std::initializer_list<T> object from an /// array temporary within list-initialization (C++11 [dcl.init.list]p5). class CXXStdInitializerListExpr : public Expr { - Stmt *SubExpr; + Stmt *SubExpr = nullptr; CXXStdInitializerListExpr(EmptyShell Empty) - : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {} + : Expr(CXXStdInitializerListExprClass, Empty) {} public: + friend class ASTReader; + friend class ASTStmtReader; + CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) - : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, - Ty->isDependentType(), SubExpr->isValueDependent(), - SubExpr->isInstantiationDependent(), - SubExpr->containsUnexpandedParameterPack()), - SubExpr(SubExpr) {} + : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, + Ty->isDependentType(), SubExpr->isValueDependent(), + SubExpr->isInstantiationDependent(), + SubExpr->containsUnexpandedParameterPack()), + SubExpr(SubExpr) {} Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); } const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); } @@ -565,9 +614,11 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return SubExpr->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd(); } + SourceRange getSourceRange() const LLVM_READONLY { return SubExpr->getSourceRange(); } @@ -577,9 +628,6 @@ public: } child_range children() { return child_range(&SubExpr, &SubExpr + 1); } - - friend class ASTReader; - friend class ASTStmtReader; }; /// A C++ \c typeid expression (C++ [expr.typeid]), which gets @@ -594,27 +642,29 @@ private: public: CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, - // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, - // typeid is value-dependent if the type or expression are dependent - Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) { } + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, + // typeid is never type-dependent (C++ [temp.dep.expr]p4) + false, + // typeid is value-dependent if the type or expression are + // dependent + Operand->getType()->isDependentType(), + Operand->getType()->isInstantiationDependentType(), + Operand->getType()->containsUnexpandedParameterPack()), + Operand(Operand), Range(R) {} CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, - // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, - // typeid is value-dependent if the type or expression are dependent - Operand->isTypeDependent() || Operand->isValueDependent(), - Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) { } + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, + // typeid is never type-dependent (C++ [temp.dep.expr]p4) + false, + // typeid is value-dependent if the type or expression are + // dependent + Operand->isTypeDependent() || Operand->isValueDependent(), + Operand->isInstantiationDependent(), + Operand->containsUnexpandedParameterPack()), + Operand(Operand), Range(R) {} CXXTypeidExpr(EmptyShell Empty, bool isExpr) - : Expr(CXXTypeidExprClass, Empty) { + : Expr(CXXTypeidExprClass, Empty) { if (isExpr) Operand = (Expr*)nullptr; else @@ -683,26 +733,30 @@ class MSPropertyRefExpr : public Expr { NestedNameSpecifierLoc QualifierLoc; public: + friend class ASTStmtReader; + MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, QualType ty, ExprValueKind VK, NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc) - : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary, - /*type-dependent*/ false, baseExpr->isValueDependent(), - baseExpr->isInstantiationDependent(), - baseExpr->containsUnexpandedParameterPack()), - BaseExpr(baseExpr), TheDecl(decl), - MemberLoc(nameLoc), IsArrow(isArrow), - QualifierLoc(qualifierLoc) {} + : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary, + /*type-dependent*/ false, baseExpr->isValueDependent(), + baseExpr->isInstantiationDependent(), + baseExpr->containsUnexpandedParameterPack()), + BaseExpr(baseExpr), TheDecl(decl), + MemberLoc(nameLoc), IsArrow(isArrow), + QualifierLoc(qualifierLoc) {} MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocStart(), getLocEnd()); } + bool isImplicitAccess() const { return getBaseExpr() && getBaseExpr()->isImplicitCXXThis(); } + SourceLocation getLocStart() const { if (!isImplicitAccess()) return BaseExpr->getLocStart(); @@ -711,11 +765,13 @@ public: else return MemberLoc; } + SourceLocation getLocEnd() const { return getMemberLoc(); } child_range children() { return child_range((Stmt**)&BaseExpr, (Stmt**)&BaseExpr + 1); } + static bool classof(const Stmt *T) { return T->getStmtClass() == MSPropertyRefExprClass; } @@ -725,8 +781,6 @@ public: bool isArrow() const { return IsArrow; } SourceLocation getMemberLoc() const { return MemberLoc; } NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - - friend class ASTStmtReader; }; /// MS property subscript expression. @@ -742,7 +796,9 @@ public: /// This is a syntactic pseudo-object expression. class MSPropertySubscriptExpr : public Expr { friend class ASTStmtReader; + enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 }; + Stmt *SubExprs[NUM_SUBEXPRS]; SourceLocation RBracketLoc; @@ -773,6 +829,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getBase()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; } SourceLocation getRBracketLoc() const { return RBracketLoc; } @@ -891,13 +948,13 @@ class CXXThisExpr : public Expr { public: CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit) - : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary, - // 'this' is type-dependent if the class type of the enclosing - // member function is dependent (C++ [temp.dep.expr]p2) - Type->isDependentType(), Type->isDependentType(), - Type->isInstantiationDependentType(), - /*ContainsUnexpandedParameterPack=*/false), - Loc(L), Implicit(isImplicit) { } + : Expr(CXXThisExprClass, Type, VK_RValue, OK_Ordinary, + // 'this' is type-dependent if the class type of the enclosing + // member function is dependent (C++ [temp.dep.expr]p2) + Type->isDependentType(), Type->isDependentType(), + Type->isInstantiationDependentType(), + /*ContainsUnexpandedParameterPack=*/false), + Loc(L), Implicit(isImplicit) {} CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} @@ -926,23 +983,25 @@ public: /// 'throw' assignment-expression. When assignment-expression isn't /// present, Op will be null. class CXXThrowExpr : public Expr { + friend class ASTStmtReader; + Stmt *Op; SourceLocation ThrowLoc; + /// \brief Whether the thrown variable (if any) is in scope. unsigned IsThrownVariableInScope : 1; - friend class ASTStmtReader; - public: // \p Ty is the void type which is used as the result type of the // expression. The \p l is the location of the throw keyword. \p expr // can by null, if the optional expression to throw isn't present. CXXThrowExpr(Expr *expr, QualType Ty, SourceLocation l, - bool IsThrownVariableInScope) : - Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - expr && expr->isInstantiationDependent(), - expr && expr->containsUnexpandedParameterPack()), - Op(expr), ThrowLoc(l), IsThrownVariableInScope(IsThrownVariableInScope) {} + bool IsThrownVariableInScope) + : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + expr && expr->isInstantiationDependent(), + expr && expr->containsUnexpandedParameterPack()), + Op(expr), ThrowLoc(l), + IsThrownVariableInScope(IsThrownVariableInScope) {} CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} const Expr *getSubExpr() const { return cast_or_null<Expr>(Op); } @@ -958,6 +1017,7 @@ public: bool isThrownVariableInScope() const { return IsThrownVariableInScope; } SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { if (!getSubExpr()) return ThrowLoc; @@ -987,15 +1047,19 @@ class CXXDefaultArgExpr final : public Expr { SourceLocation Loc; CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param) - : Expr(SC, - param->hasUnparsedDefaultArg() - ? param->getType().getNonReferenceType() - : param->getDefaultArg()->getType(), - param->getDefaultArg()->getValueKind(), - param->getDefaultArg()->getObjectKind(), false, false, false, false), - Param(param), Loc(Loc) { } + : Expr(SC, + param->hasUnparsedDefaultArg() + ? param->getType().getNonReferenceType() + : param->getDefaultArg()->getType(), + param->getDefaultArg()->getValueKind(), + param->getDefaultArg()->getObjectKind(), false, false, false, + false), + Param(param), Loc(Loc) {} public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + CXXDefaultArgExpr(EmptyShell Empty) : Expr(CXXDefaultArgExprClass, Empty) {} // \p Param is the parameter whose default argument is used by this @@ -1036,9 +1100,6 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief A use of a default initializer in a constructor or in aggregate @@ -1062,6 +1123,9 @@ class CXXDefaultInitExpr : public Expr { CXXDefaultInitExpr(EmptyShell Empty) : Expr(CXXDefaultInitExprClass, Empty) {} public: + friend class ASTReader; + friend class ASTStmtReader; + /// \p Field is the non-static data member whose default initializer is used /// by this expression. static CXXDefaultInitExpr *Create(const ASTContext &C, SourceLocation Loc, @@ -1094,9 +1158,6 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend class ASTReader; - friend class ASTStmtReader; }; /// \brief Represents a C++ temporary. @@ -1105,13 +1166,14 @@ class CXXTemporary { const CXXDestructorDecl *Destructor; explicit CXXTemporary(const CXXDestructorDecl *destructor) - : Destructor(destructor) { } + : Destructor(destructor) {} public: static CXXTemporary *Create(const ASTContext &C, const CXXDestructorDecl *Destructor); const CXXDestructorDecl *getDestructor() const { return Destructor; } + void setDestructor(const CXXDestructorDecl *Dtor) { Destructor = Dtor; } @@ -1132,21 +1194,20 @@ public: /// } /// \endcode class CXXBindTemporaryExpr : public Expr { - CXXTemporary *Temp; - - Stmt *SubExpr; + CXXTemporary *Temp = nullptr; + Stmt *SubExpr = nullptr; CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr) - : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), - VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), - SubExpr->isValueDependent(), - SubExpr->isInstantiationDependent(), - SubExpr->containsUnexpandedParameterPack()), - Temp(temp), SubExpr(SubExpr) { } + : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), + VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), + SubExpr->isValueDependent(), + SubExpr->isInstantiationDependent(), + SubExpr->containsUnexpandedParameterPack()), + Temp(temp), SubExpr(SubExpr) {} public: CXXBindTemporaryExpr(EmptyShell Empty) - : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {} + : Expr(CXXBindTemporaryExprClass, Empty) {} static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp, Expr* SubExpr); @@ -1162,6 +1223,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return SubExpr->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();} // Implement isa/cast/dyncast/etc. @@ -1184,8 +1246,7 @@ public: }; private: - CXXConstructorDecl *Constructor; - + CXXConstructorDecl *Constructor = nullptr; SourceLocation Loc; SourceRange ParenOrBraceRange; unsigned NumArgs : 16; @@ -1195,7 +1256,7 @@ private: unsigned StdInitListInitialization : 1; unsigned ZeroInitialization : 1; unsigned ConstructKind : 2; - Stmt **Args; + Stmt **Args = nullptr; void setConstructor(CXXConstructorDecl *C) { Constructor = C; } @@ -1214,15 +1275,16 @@ protected: /// \brief Construct an empty C++ construction expression. CXXConstructExpr(StmtClass SC, EmptyShell Empty) - : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false), - HadMultipleCandidates(false), ListInitialization(false), - ZeroInitialization(false), ConstructKind(0), Args(nullptr) - { } + : Expr(SC, Empty), NumArgs(0), Elidable(false), + HadMultipleCandidates(false), ListInitialization(false), + ZeroInitialization(false), ConstructKind(0) {} public: + friend class ASTStmtReader; + /// \brief Construct an empty C++ construction expression. explicit CXXConstructExpr(EmptyShell Empty) - : CXXConstructExpr(CXXConstructExprClass, Empty) {} + : CXXConstructExpr(CXXConstructExprClass, Empty) {} static CXXConstructExpr *Create(const ASTContext &C, QualType T, SourceLocation Loc, @@ -1278,10 +1340,10 @@ public: ConstructKind = CK; } - typedef ExprIterator arg_iterator; - typedef ConstExprIterator const_arg_iterator; - typedef llvm::iterator_range<arg_iterator> arg_range; - typedef llvm::iterator_range<const_arg_iterator> arg_const_range; + using arg_iterator = ExprIterator; + using const_arg_iterator = ConstExprIterator; + using arg_range = llvm::iterator_range<arg_iterator>; + using arg_const_range = llvm::iterator_range<const_arg_iterator>; arg_range arguments() { return arg_range(arg_begin(), arg_end()); } arg_const_range arguments() const { @@ -1329,8 +1391,6 @@ public: child_range children() { return child_range(&Args[0], &Args[0]+NumArgs); } - - friend class ASTStmtReader; }; /// \brief Represents a call to an inherited base class constructor from an @@ -1339,7 +1399,7 @@ public: /// base class constructor. class CXXInheritedCtorInitExpr : public Expr { private: - CXXConstructorDecl *Constructor; + CXXConstructorDecl *Constructor = nullptr; /// The location of the using declaration. SourceLocation Loc; @@ -1352,6 +1412,8 @@ private: unsigned InheritedFromVirtualBase : 1; public: + friend class ASTStmtReader; + /// \brief Construct a C++ inheriting construction expression. CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, @@ -1366,7 +1428,7 @@ public: /// \brief Construct an empty C++ inheriting construction expression. explicit CXXInheritedCtorInitExpr(EmptyShell Empty) - : Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr), + : Expr(CXXInheritedCtorInitExprClass, Empty), ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {} /// \brief Get the constructor that this expression will call. @@ -1393,11 +1455,10 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXInheritedCtorInitExprClass; } + child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend class ASTStmtReader; }; /// \brief Represents an explicit C++ type conversion that uses "functional" @@ -1417,14 +1478,17 @@ class CXXFunctionalCastExpr final TypeSourceInfo *writtenTy, CastKind kind, Expr *castExpr, unsigned pathSize, SourceLocation lParenLoc, SourceLocation rParenLoc) - : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, - castExpr, pathSize, writtenTy), - LParenLoc(lParenLoc), RParenLoc(rParenLoc) {} + : ExplicitCastExpr(CXXFunctionalCastExprClass, ty, VK, kind, + castExpr, pathSize, writtenTy), + LParenLoc(lParenLoc), RParenLoc(rParenLoc) {} explicit CXXFunctionalCastExpr(EmptyShell Shell, unsigned PathSize) - : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) { } + : ExplicitCastExpr(CXXFunctionalCastExprClass, Shell, PathSize) {} public: + friend class CastExpr; + friend TrailingObjects; + static CXXFunctionalCastExpr *Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, @@ -1446,9 +1510,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; } - - friend TrailingObjects; - friend class CastExpr; }; /// @brief Represents a C++ functional cast expression that builds a @@ -1467,9 +1528,11 @@ public: /// }; /// \endcode class CXXTemporaryObjectExpr : public CXXConstructExpr { - TypeSourceInfo *Type; + TypeSourceInfo *Type = nullptr; public: + friend class ASTStmtReader; + CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, QualType Type, @@ -1481,7 +1544,7 @@ public: bool StdInitListInitialization, bool ZeroInitialization); explicit CXXTemporaryObjectExpr(EmptyShell Empty) - : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { } + : CXXConstructExpr(CXXTemporaryObjectExprClass, Empty) {} TypeSourceInfo *getTypeSourceInfo() const { return Type; } @@ -1491,8 +1554,6 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXTemporaryObjectExprClass; } - - friend class ASTStmtReader; }; /// \brief A C++ lambda expression, which produces a function object @@ -1558,9 +1619,9 @@ class LambdaExpr final : public Expr, /// \brief Construct an empty lambda expression. LambdaExpr(EmptyShell Empty, unsigned NumCaptures) - : Expr(LambdaExprClass, Empty), - NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false), - ExplicitResultType(false) { + : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures), + CaptureDefault(LCD_None), ExplicitParams(false), + ExplicitResultType(false) { getStoredStmts()[NumCaptures] = nullptr; } @@ -1569,6 +1630,10 @@ class LambdaExpr final : public Expr, Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); } public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + /// \brief Construct a new lambda expression. static LambdaExpr * Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, @@ -1597,10 +1662,10 @@ public: /// \brief An iterator that walks over the captures of the lambda, /// both implicit and explicit. - typedef const LambdaCapture *capture_iterator; + using capture_iterator = const LambdaCapture *; /// \brief An iterator over a range of lambda captures. - typedef llvm::iterator_range<capture_iterator> capture_range; + using capture_range = llvm::iterator_range<capture_iterator>; /// \brief Retrieve this lambda's captures. capture_range captures() const; @@ -1639,11 +1704,11 @@ public: /// \brief Iterator that walks over the capture initialization /// arguments. - typedef Expr **capture_init_iterator; + using capture_init_iterator = Expr **; /// \brief Const iterator that walks over the capture initialization /// arguments. - typedef Expr *const *const_capture_init_iterator; + using const_capture_init_iterator = Expr *const *; /// \brief Retrieve the initialization expressions for this lambda's captures. llvm::iterator_range<capture_init_iterator> capture_inits() { @@ -1723,26 +1788,23 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return IntroducerRange.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return ClosingBrace; } child_range children() { // Includes initialization exprs plus body stmt return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); } - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// An expression "T()" which creates a value-initialized rvalue of type /// T, which is a non-class type. See (C++98 [5.2.3p2]). class CXXScalarValueInitExpr : public Expr { + friend class ASTStmtReader; + SourceLocation RParenLoc; TypeSourceInfo *TypeInfo; - friend class ASTStmtReader; - public: /// \brief Create an explicitly-written scalar-value initialization /// expression. @@ -1754,7 +1816,7 @@ public: RParenLoc(rParenLoc), TypeInfo(TypeInfo) {} explicit CXXScalarValueInitExpr(EmptyShell Shell) - : Expr(CXXScalarValueInitExprClass, Shell) { } + : Expr(CXXScalarValueInitExprClass, Shell) {} TypeSourceInfo *getTypeSourceInfo() const { return TypeInfo; @@ -1778,11 +1840,16 @@ public: /// \brief Represents a new-expression for memory allocation and constructor /// calls, e.g: "new CXXNewExpr(foo)". class CXXNewExpr : public Expr { + friend class ASTStmtReader; + friend class ASTStmtWriter; + /// Contains an optional array size expression, an optional initialization /// expression, and any number of optional placement arguments, in that order. - Stmt **SubExprs; + Stmt **SubExprs = nullptr; + /// \brief Points to the allocation function used. FunctionDecl *OperatorNew; + /// \brief Points to the deallocation function used in case of error. May be /// null. FunctionDecl *OperatorDelete; @@ -1802,27 +1869,35 @@ class CXXNewExpr : public Expr { /// Was the usage ::new, i.e. is the global new to be used? unsigned GlobalNew : 1; + /// Do we allocate an array? If so, the first SubExpr is the size expression. unsigned Array : 1; + /// Should the alignment be passed to the allocation function? unsigned PassAlignment : 1; + /// If this is an array allocation, does the usual deallocation /// function for the allocated type want to know the allocated size? unsigned UsualArrayDeleteWantsSize : 1; + /// The number of placement new arguments. unsigned NumPlacementArgs : 26; + /// What kind of initializer do we have? Could be none, parens, or braces. /// In storage, we distinguish between "none, and no initializer expr", and /// "none, but an implicit initializer expr". unsigned StoredInitializationStyle : 2; - friend class ASTStmtReader; - friend class ASTStmtWriter; public: enum InitializationStyle { - NoInit, ///< New-expression has no initializer as written. - CallInit, ///< New-expression has a C++98 paren-delimited initializer. - ListInit ///< New-expression has a C++11 list-initializer. + /// New-expression has no initializer as written. + NoInit, + + /// New-expression has a C++98 paren-delimited initializer. + CallInit, + + /// New-expression has a C++11 list-initializer. + ListInit }; CXXNewExpr(const ASTContext &C, bool globalNew, FunctionDecl *operatorNew, @@ -1833,7 +1908,7 @@ public: QualType ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, SourceRange directInitRange); explicit CXXNewExpr(EmptyShell Shell) - : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { } + : Expr(CXXNewExprClass, Shell) {} void AllocateArgsArray(const ASTContext &C, bool isArray, unsigned numPlaceArgs, bool hasInitializer); @@ -1870,6 +1945,7 @@ public: void setOperatorDelete(FunctionDecl *D) { OperatorDelete = D; } bool isArray() const { return Array; } + Expr *getArraySize() { return Array ? cast<Expr>(SubExprs[0]) : nullptr; } @@ -1878,6 +1954,7 @@ public: } unsigned getNumPlacementArgs() const { return NumPlacementArgs; } + Expr **getPlacementArgs() { return reinterpret_cast<Expr **>(SubExprs + Array + hasInitializer()); } @@ -1932,8 +2009,8 @@ public: return UsualArrayDeleteWantsSize; } - typedef ExprIterator arg_iterator; - typedef ConstExprIterator const_arg_iterator; + using arg_iterator = ExprIterator; + using const_arg_iterator = ConstExprIterator; llvm::iterator_range<arg_iterator> placement_arguments() { return llvm::make_range(placement_arg_begin(), placement_arg_end()); @@ -1956,7 +2033,8 @@ public: return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); } - typedef Stmt **raw_arg_iterator; + using raw_arg_iterator = Stmt **; + raw_arg_iterator raw_arg_begin() { return SubExprs; } raw_arg_iterator raw_arg_end() { return SubExprs + Array + hasInitializer() + getNumPlacementArgs(); @@ -1974,6 +2052,7 @@ public: SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return getStartLoc(); } SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } @@ -1991,36 +2070,43 @@ public: /// destructor calls, e.g. "delete[] pArray". class CXXDeleteExpr : public Expr { /// Points to the operator delete overload that is used. Could be a member. - FunctionDecl *OperatorDelete; + FunctionDecl *OperatorDelete = nullptr; + /// The pointer expression to be deleted. - Stmt *Argument; + Stmt *Argument = nullptr; + /// Location of the expression. SourceLocation Loc; + /// Is this a forced global delete, i.e. "::delete"? bool GlobalDelete : 1; + /// Is this the array form of delete, i.e. "delete[]"? bool ArrayForm : 1; + /// ArrayFormAsWritten can be different from ArrayForm if 'delete' is applied /// to pointer-to-array type (ArrayFormAsWritten will be false while ArrayForm /// will be true). bool ArrayFormAsWritten : 1; + /// Does the usual deallocation function for the element type require /// a size_t argument? bool UsualArrayDeleteWantsSize : 1; + public: + friend class ASTStmtReader; + CXXDeleteExpr(QualType ty, bool globalDelete, bool arrayForm, bool arrayFormAsWritten, bool usualArrayDeleteWantsSize, FunctionDecl *operatorDelete, Expr *arg, SourceLocation loc) - : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, - arg->isInstantiationDependent(), - arg->containsUnexpandedParameterPack()), - OperatorDelete(operatorDelete), Argument(arg), Loc(loc), - GlobalDelete(globalDelete), - ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), - UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { } - explicit CXXDeleteExpr(EmptyShell Shell) - : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr), - Argument(nullptr) {} + : Expr(CXXDeleteExprClass, ty, VK_RValue, OK_Ordinary, false, false, + arg->isInstantiationDependent(), + arg->containsUnexpandedParameterPack()), + OperatorDelete(operatorDelete), Argument(arg), Loc(loc), + GlobalDelete(globalDelete), + ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten), + UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {} + explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} bool isGlobalDelete() const { return GlobalDelete; } bool isArrayForm() const { return ArrayForm; } @@ -2054,8 +2140,6 @@ public: // Iterators child_range children() { return child_range(&Argument, &Argument+1); } - - friend class ASTStmtReader; }; /// \brief Stores the type being destroyed by a pseudo-destructor expression. @@ -2068,10 +2152,10 @@ class PseudoDestructorTypeStorage { SourceLocation Location; public: - PseudoDestructorTypeStorage() { } + PseudoDestructorTypeStorage() = default; PseudoDestructorTypeStorage(IdentifierInfo *II, SourceLocation Loc) - : Type(II), Location(Loc) { } + : Type(II), Location(Loc) {} PseudoDestructorTypeStorage(TypeSourceInfo *Info); @@ -2111,8 +2195,10 @@ public: /// for scalar types. A pseudo-destructor expression has no run-time semantics /// beyond evaluating the base expression. class CXXPseudoDestructorExpr : public Expr { + friend class ASTStmtReader; + /// \brief The base expression (that is being destroyed). - Stmt *Base; + Stmt *Base = nullptr; /// \brief Whether the operator was an arrow ('->'); otherwise, it was a /// period ('.'). @@ -2126,7 +2212,7 @@ class CXXPseudoDestructorExpr : public Expr { /// \brief The type that precedes the '::' in a qualified pseudo-destructor /// expression. - TypeSourceInfo *ScopeType; + TypeSourceInfo *ScopeType = nullptr; /// \brief The location of the '::' in a qualified pseudo-destructor /// expression. @@ -2139,8 +2225,6 @@ class CXXPseudoDestructorExpr : public Expr { /// resolve the name. PseudoDestructorTypeStorage DestroyedType; - friend class ASTStmtReader; - public: CXXPseudoDestructorExpr(const ASTContext &Context, Expr *Base, bool isArrow, SourceLocation OperatorLoc, @@ -2151,8 +2235,7 @@ public: PseudoDestructorTypeStorage DestroyedType); explicit CXXPseudoDestructorExpr(EmptyShell Shell) - : Expr(CXXPseudoDestructorExprClass, Shell), - Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { } + : Expr(CXXPseudoDestructorExprClass, Shell), IsArrow(false) {} Expr *getBase() const { return cast<Expr>(Base); } @@ -2270,13 +2353,17 @@ class TypeTraitExpr final SourceLocation RParenLoc, bool Value); - TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) { } + TypeTraitExpr(EmptyShell Empty) : Expr(TypeTraitExprClass, Empty) {} size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const { return getNumArgs(); } public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + /// \brief Create a new type trait expression. static TypeTraitExpr *Create(const ASTContext &C, QualType T, SourceLocation Loc, TypeTrait Kind, @@ -2323,10 +2410,6 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief An Embarcadero array type trait, as used in the implementation of @@ -2338,13 +2421,11 @@ public: /// __array_extent(int, 1) == 20 /// \endcode class ArrayTypeTraitExpr : public Expr { - virtual void anchor(); - /// \brief The trait. An ArrayTypeTrait enum in MSVC compat unsigned. unsigned ATT : 2; /// \brief The value of the type trait. Unspecified if dependent. - uint64_t Value; + uint64_t Value = 0; /// \brief The array dimension being queried, or -1 if not used. Expr *Dimension; @@ -2356,26 +2437,28 @@ class ArrayTypeTraitExpr : public Expr { SourceLocation RParen; /// \brief The type being queried. - TypeSourceInfo *QueriedType; + TypeSourceInfo *QueriedType = nullptr; + + virtual void anchor(); public: + friend class ASTStmtReader; + ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, TypeSourceInfo *queried, uint64_t value, Expr *dimension, SourceLocation rparen, QualType ty) - : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, - false, queried->getType()->isDependentType(), - (queried->getType()->isInstantiationDependentType() || - (dimension && dimension->isInstantiationDependent())), - queried->getType()->containsUnexpandedParameterPack()), - ATT(att), Value(value), Dimension(dimension), - Loc(loc), RParen(rparen), QueriedType(queried) { } - + : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, + false, queried->getType()->isDependentType(), + (queried->getType()->isInstantiationDependentType() || + (dimension && dimension->isInstantiationDependent())), + queried->getType()->containsUnexpandedParameterPack()), + ATT(att), Value(value), Dimension(dimension), + Loc(loc), RParen(rparen), QueriedType(queried) {} explicit ArrayTypeTraitExpr(EmptyShell Empty) - : Expr(ArrayTypeTraitExprClass, Empty), ATT(0), Value(false), - QueriedType() { } + : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} - virtual ~ArrayTypeTraitExpr() { } + virtual ~ArrayTypeTraitExpr() = default; SourceLocation getLocStart() const LLVM_READONLY { return Loc; } SourceLocation getLocEnd() const LLVM_READONLY { return RParen; } @@ -2398,8 +2481,6 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend class ASTStmtReader; }; /// \brief An expression trait intrinsic. @@ -2412,6 +2493,7 @@ public: class ExpressionTraitExpr : public Expr { /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned. unsigned ET : 31; + /// \brief The value of the type trait. Unspecified if dependent. unsigned Value : 1; @@ -2422,23 +2504,25 @@ class ExpressionTraitExpr : public Expr { SourceLocation RParen; /// \brief The expression being queried. - Expr* QueriedExpression; + Expr* QueriedExpression = nullptr; + public: + friend class ASTStmtReader; + ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, bool value, SourceLocation rparen, QualType resultType) - : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary, - false, // Not type-dependent - // Value-dependent if the argument is type-dependent. - queried->isTypeDependent(), - queried->isInstantiationDependent(), - queried->containsUnexpandedParameterPack()), - ET(et), Value(value), Loc(loc), RParen(rparen), - QueriedExpression(queried) { } + : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary, + false, // Not type-dependent + // Value-dependent if the argument is type-dependent. + queried->isTypeDependent(), + queried->isInstantiationDependent(), + queried->containsUnexpandedParameterPack()), + ET(et), Value(value), Loc(loc), RParen(rparen), + QueriedExpression(queried) {} explicit ExpressionTraitExpr(EmptyShell Empty) - : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false), - QueriedExpression() { } + : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} SourceLocation getLocStart() const LLVM_READONLY { return Loc; } SourceLocation getLocEnd() const LLVM_READONLY { return RParen; } @@ -2457,11 +2541,8 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend class ASTStmtReader; }; - /// \brief A reference to an overloaded function set, either an /// \c UnresolvedLookupExpr or an \c UnresolvedMemberExpr. class OverloadExpr : public Expr { @@ -2475,13 +2556,26 @@ class OverloadExpr : public Expr { /// include UsingShadowDecls. Access is relative to the naming /// class. // FIXME: Allocate this data after the OverloadExpr subclass. - DeclAccessPair *Results; - unsigned NumResults; + DeclAccessPair *Results = nullptr; + + unsigned NumResults = 0; protected: /// \brief Whether the name includes info for explicit template /// keyword and arguments. - bool HasTemplateKWAndArgsInfo; + bool HasTemplateKWAndArgsInfo = false; + + OverloadExpr(StmtClass K, const ASTContext &C, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, + const DeclarationNameInfo &NameInfo, + const TemplateArgumentListInfo *TemplateArgs, + UnresolvedSetIterator Begin, UnresolvedSetIterator End, + bool KnownDependent, + bool KnownInstantiationDependent, + bool KnownContainsUnexpandedParameterPack); + + OverloadExpr(StmtClass K, EmptyShell Empty) : Expr(K, Empty) {} /// \brief Return the optional template keyword and arguments info. ASTTemplateKWAndArgsInfo * @@ -2496,25 +2590,14 @@ protected: /// Return the optional template arguments. TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below - OverloadExpr(StmtClass K, const ASTContext &C, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs, - UnresolvedSetIterator Begin, UnresolvedSetIterator End, - bool KnownDependent, - bool KnownInstantiationDependent, - bool KnownContainsUnexpandedParameterPack); - - OverloadExpr(StmtClass K, EmptyShell Empty) - : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0), - HasTemplateKWAndArgsInfo(false) { } - void initializeResults(const ASTContext &C, UnresolvedSetIterator Begin, UnresolvedSetIterator End); public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + struct FindResult { OverloadExpr *Expression; bool IsAddressOfOperand; @@ -2552,7 +2635,8 @@ public: /// \brief Gets the naming class of this lookup, if any. CXXRecordDecl *getNamingClass() const; - typedef UnresolvedSetImpl::iterator decls_iterator; + using decls_iterator = UnresolvedSetImpl::iterator; + decls_iterator decls_begin() const { return UnresolvedSetIterator(Results); } decls_iterator decls_end() const { return UnresolvedSetIterator(Results + NumResults); @@ -2636,9 +2720,6 @@ public: return T->getStmtClass() == UnresolvedLookupExprClass || T->getStmtClass() == UnresolvedMemberExprClass; } - - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief A reference to a name which we were able to look up during @@ -2656,25 +2737,25 @@ class UnresolvedLookupExpr final : public OverloadExpr, private llvm::TrailingObjects< UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { + friend class ASTStmtReader; + friend class OverloadExpr; + friend TrailingObjects; + /// True if these lookup results should be extended by /// argument-dependent lookup if this is the operand of a function /// call. - bool RequiresADL; + bool RequiresADL = false; /// True if these lookup results are overloaded. This is pretty /// trivially rederivable if we urgently need to kill this field. - bool Overloaded; + bool Overloaded = false; /// The naming class (C++ [class.access.base]p5) of the lookup, if /// any. This can generally be recalculated from the context chain, /// but that can be fairly expensive for unqualified lookups. If we /// want to improve memory use here, this could go in a union /// against the qualified-lookup bits. - CXXRecordDecl *NamingClass; - - size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { - return HasTemplateKWAndArgsInfo ? 1 : 0; - } + CXXRecordDecl *NamingClass = nullptr; UnresolvedLookupExpr(const ASTContext &C, CXXRecordDecl *NamingClass, @@ -2684,20 +2765,17 @@ class UnresolvedLookupExpr final bool RequiresADL, bool Overloaded, const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, - NameInfo, TemplateArgs, Begin, End, false, false, false), - RequiresADL(RequiresADL), - Overloaded(Overloaded), NamingClass(NamingClass) - {} + : OverloadExpr(UnresolvedLookupExprClass, C, QualifierLoc, TemplateKWLoc, + NameInfo, TemplateArgs, Begin, End, false, false, false), + RequiresADL(RequiresADL), + Overloaded(Overloaded), NamingClass(NamingClass) {} UnresolvedLookupExpr(EmptyShell Empty) - : OverloadExpr(UnresolvedLookupExprClass, Empty), - RequiresADL(false), Overloaded(false), NamingClass(nullptr) - {} + : OverloadExpr(UnresolvedLookupExprClass, Empty) {} - friend TrailingObjects; - friend class OverloadExpr; - friend class ASTStmtReader; + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } public: static UnresolvedLookupExpr *Create(const ASTContext &C, @@ -2743,6 +2821,7 @@ public: return l.getBeginLoc(); return getNameInfo().getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) return getRAngleLoc(); @@ -2788,17 +2867,21 @@ class DependentScopeDeclRefExpr final /// keyword and arguments. bool HasTemplateKWAndArgsInfo; - size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { - return HasTemplateKWAndArgsInfo ? 1 : 0; - } - DependentScopeDeclRefExpr(QualType T, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *Args); + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } + public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + static DependentScopeDeclRefExpr *Create(const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2888,6 +2971,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return QualifierLoc.getBeginLoc(); } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) return getRAngleLoc(); @@ -2901,10 +2985,6 @@ public: child_range children() { return child_range(child_iterator(), child_iterator()); } - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// Represents an expression -- generally a full-expression -- that @@ -2925,18 +3005,18 @@ public: /// It's useful to remember the set of blocks; we could also /// remember the set of temporaries, but there's currently /// no need. - typedef BlockDecl *CleanupObject; + using CleanupObject = BlockDecl *; private: + friend class ASTStmtReader; + friend TrailingObjects; + Stmt *SubExpr; ExprWithCleanups(EmptyShell, unsigned NumObjects); ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects, ArrayRef<CleanupObject> Objects); - friend TrailingObjects; - friend class ASTStmtReader; - public: static ExprWithCleanups *Create(const ASTContext &C, EmptyShell empty, unsigned numObjects); @@ -2959,6 +3039,7 @@ public: Expr *getSubExpr() { return cast<Expr>(SubExpr); } const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } + bool cleanupsHaveSideEffects() const { return ExprWithCleanupsBits.CleanupsHaveSideEffects; } @@ -2970,6 +3051,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return SubExpr->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return SubExpr->getLocEnd();} // Implement isa/cast/dyncast/etc. @@ -3005,8 +3087,11 @@ public: class CXXUnresolvedConstructExpr final : public Expr, private llvm::TrailingObjects<CXXUnresolvedConstructExpr, Expr *> { + friend class ASTStmtReader; + friend TrailingObjects; + /// \brief The type being constructed. - TypeSourceInfo *Type; + TypeSourceInfo *Type = nullptr; /// \brief The location of the left parentheses ('('). SourceLocation LParenLoc; @@ -3023,10 +3108,7 @@ class CXXUnresolvedConstructExpr final SourceLocation RParenLoc); CXXUnresolvedConstructExpr(EmptyShell Empty, unsigned NumArgs) - : Expr(CXXUnresolvedConstructExprClass, Empty), Type(), NumArgs(NumArgs) { } - - friend TrailingObjects; - friend class ASTStmtReader; + : Expr(CXXUnresolvedConstructExprClass, Empty), NumArgs(NumArgs) {} public: static CXXUnresolvedConstructExpr *Create(const ASTContext &C, @@ -3056,14 +3138,21 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } + /// Determine whether this expression models list-initialization. + /// If so, there will be exactly one subexpression, which will be + /// an InitListExpr. + bool isListInitialization() const { return LParenLoc.isInvalid(); } + /// \brief Retrieve the number of arguments. unsigned arg_size() const { return NumArgs; } - typedef Expr** arg_iterator; + using arg_iterator = Expr **; + arg_iterator arg_begin() { return getTrailingObjects<Expr *>(); } arg_iterator arg_end() { return arg_begin() + NumArgs; } - typedef const Expr* const * const_arg_iterator; + using const_arg_iterator = const Expr* const *; + const_arg_iterator arg_begin() const { return getTrailingObjects<Expr *>(); } const_arg_iterator arg_end() const { return arg_begin() + NumArgs; @@ -3085,6 +3174,7 @@ public: } SourceLocation getLocStart() const LLVM_READONLY; + SourceLocation getLocEnd() const LLVM_READONLY { if (!RParenLoc.isValid() && NumArgs > 0) return getArg(NumArgs - 1)->getLocEnd(); @@ -3165,6 +3255,10 @@ class CXXDependentScopeMemberExpr final const TemplateArgumentListInfo *TemplateArgs); public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, @@ -3214,7 +3308,6 @@ public: /// name, with source location information. NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } - /// \brief Retrieve the first part of the nested-name-specifier that was /// found in the scope of the member access expression when the member access /// was initially parsed. @@ -3326,10 +3419,6 @@ public: return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; }; /// \brief Represents a C++ member access expression for which lookup @@ -3351,6 +3440,10 @@ class UnresolvedMemberExpr final : public OverloadExpr, private llvm::TrailingObjects< UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { + friend class ASTStmtReader; + friend class OverloadExpr; + friend TrailingObjects; + /// \brief Whether this member expression used the '->' operator or /// the '.' operator. bool IsArrow : 1; @@ -3363,7 +3456,7 @@ class UnresolvedMemberExpr final /// e.g., the \c x in x.f. /// /// This can be null if this is an 'unbased' member expression. - Stmt *Base; + Stmt *Base = nullptr; /// \brief The type of the base expression; never null. QualType BaseType; @@ -3371,10 +3464,6 @@ class UnresolvedMemberExpr final /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; - size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { - return HasTemplateKWAndArgsInfo ? 1 : 0; - } - UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, @@ -3385,12 +3474,12 @@ class UnresolvedMemberExpr final UnresolvedSetIterator Begin, UnresolvedSetIterator End); UnresolvedMemberExpr(EmptyShell Empty) - : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), - HasUnresolvedUsing(false), Base(nullptr) { } + : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), + HasUnresolvedUsing(false) {} - friend TrailingObjects; - friend class OverloadExpr; - friend class ASTStmtReader; + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } public: static UnresolvedMemberExpr * @@ -3463,6 +3552,7 @@ public: return l.getBeginLoc(); return getMemberNameInfo().getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) return getRAngleLoc(); @@ -3508,26 +3598,23 @@ inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { /// The noexcept expression tests whether a given expression might throw. Its /// result is a boolean constant. class CXXNoexceptExpr : public Expr { + friend class ASTStmtReader; + bool Value : 1; Stmt *Operand; SourceRange Range; - friend class ASTStmtReader; - public: CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, SourceLocation Keyword, SourceLocation RParen) - : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, - /*TypeDependent*/false, - /*ValueDependent*/Val == CT_Dependent, - Val == CT_Dependent || Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) - { } - - CXXNoexceptExpr(EmptyShell Empty) - : Expr(CXXNoexceptExprClass, Empty) - { } + : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, + /*TypeDependent*/false, + /*ValueDependent*/Val == CT_Dependent, + Val == CT_Dependent || Operand->isInstantiationDependent(), + Operand->containsUnexpandedParameterPack()), + Value(Val == CT_Cannot), Operand(Operand), Range(Keyword, RParen) {} + + CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {} Expr *getOperand() const { return static_cast<Expr*>(Operand); } @@ -3563,6 +3650,9 @@ public: /// template is instantiated, the pack expansion will instantiate to zero or /// or more function arguments to the function object \c f. class PackExpansionExpr : public Expr { + friend class ASTStmtReader; + friend class ASTStmtWriter; + SourceLocation EllipsisLoc; /// \brief The number of expansions that will be produced by this pack @@ -3574,21 +3664,18 @@ class PackExpansionExpr : public Expr { Stmt *Pattern; - friend class ASTStmtReader; - friend class ASTStmtWriter; - public: PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc, Optional<unsigned> NumExpansions) - : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), - Pattern->getObjectKind(), /*TypeDependent=*/true, - /*ValueDependent=*/true, /*InstantiationDependent=*/true, - /*ContainsUnexpandedParameterPack=*/false), - EllipsisLoc(EllipsisLoc), - NumExpansions(NumExpansions? *NumExpansions + 1 : 0), - Pattern(Pattern) { } + : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), + Pattern->getObjectKind(), /*TypeDependent=*/true, + /*ValueDependent=*/true, /*InstantiationDependent=*/true, + /*ContainsUnexpandedParameterPack=*/false), + EllipsisLoc(EllipsisLoc), + NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), + Pattern(Pattern) {} - PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) { } + PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {} /// \brief Retrieve the pattern of the pack expansion. Expr *getPattern() { return reinterpret_cast<Expr *>(Pattern); } @@ -3612,6 +3699,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return Pattern->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return EllipsisLoc; } static bool classof(const Stmt *T) { @@ -3624,7 +3712,6 @@ public: } }; - /// \brief Represents an expression that computes the length of a parameter /// pack. /// @@ -3637,6 +3724,10 @@ public: class SizeOfPackExpr final : public Expr, private llvm::TrailingObjects<SizeOfPackExpr, TemplateArgument> { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + /// \brief The location of the \c sizeof keyword. SourceLocation OperatorLoc; @@ -3659,11 +3750,7 @@ class SizeOfPackExpr final unsigned Length; /// \brief The parameter pack. - NamedDecl *Pack; - - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; + NamedDecl *Pack = nullptr; /// \brief Create an expression that computes the length of /// the given parameter pack. @@ -3684,7 +3771,7 @@ class SizeOfPackExpr final /// \brief Create an empty expression. SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs) - : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs), Pack() {} + : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs) {} public: static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc, @@ -3749,6 +3836,9 @@ public: /// \brief Represents a reference to a non-type template parameter /// that has been substituted with a template argument. class SubstNonTypeTemplateParmExpr : public Expr { + friend class ASTReader; + friend class ASTStmtReader; + /// \brief The replaced parameter. NonTypeTemplateParmDecl *Param; @@ -3758,10 +3848,8 @@ class SubstNonTypeTemplateParmExpr : public Expr { /// \brief The location of the non-type template parameter reference. SourceLocation NameLoc; - friend class ASTReader; - friend class ASTStmtReader; explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty) - : Expr(SubstNonTypeTemplateParmExprClass, Empty) { } + : Expr(SubstNonTypeTemplateParmExprClass, Empty) {} public: SubstNonTypeTemplateParmExpr(QualType type, @@ -3769,11 +3857,11 @@ public: SourceLocation loc, NonTypeTemplateParmDecl *param, Expr *replacement) - : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary, - replacement->isTypeDependent(), replacement->isValueDependent(), - replacement->isInstantiationDependent(), - replacement->containsUnexpandedParameterPack()), - Param(param), Replacement(replacement), NameLoc(loc) {} + : Expr(SubstNonTypeTemplateParmExprClass, type, valueKind, OK_Ordinary, + replacement->isTypeDependent(), replacement->isValueDependent(), + replacement->isInstantiationDependent(), + replacement->containsUnexpandedParameterPack()), + Param(param), Replacement(replacement), NameLoc(loc) {} SourceLocation getNameLoc() const { return NameLoc; } SourceLocation getLocStart() const LLVM_READONLY { return NameLoc; } @@ -3804,6 +3892,9 @@ public: /// arguments), this type will be replaced with the appropriate underlying /// expression at the current pack substitution index. class SubstNonTypeTemplateParmPackExpr : public Expr { + friend class ASTReader; + friend class ASTStmtReader; + /// \brief The non-type template parameter pack itself. NonTypeTemplateParmDecl *Param; @@ -3817,10 +3908,8 @@ class SubstNonTypeTemplateParmPackExpr : public Expr { /// \brief The location of the non-type template parameter pack reference. SourceLocation NameLoc; - friend class ASTReader; - friend class ASTStmtReader; explicit SubstNonTypeTemplateParmPackExpr(EmptyShell Empty) - : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) { } + : Expr(SubstNonTypeTemplateParmPackExprClass, Empty) {} public: SubstNonTypeTemplateParmPackExpr(QualType T, @@ -3868,6 +3957,10 @@ public: class FunctionParmPackExpr final : public Expr, private llvm::TrailingObjects<FunctionParmPackExpr, ParmVarDecl *> { + friend class ASTReader; + friend class ASTStmtReader; + friend TrailingObjects; + /// \brief The function parameter pack which was referenced. ParmVarDecl *ParamPack; @@ -3881,10 +3974,6 @@ class FunctionParmPackExpr final SourceLocation NameLoc, unsigned NumParams, ParmVarDecl *const *Params); - friend TrailingObjects; - friend class ASTReader; - friend class ASTStmtReader; - public: static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, ParmVarDecl *ParamPack, @@ -3901,7 +3990,7 @@ public: /// \brief Iterators over the parameters which the parameter pack expanded /// into. - typedef ParmVarDecl * const *iterator; + using iterator = ParmVarDecl * const *; iterator begin() const { return getTrailingObjects<ParmVarDecl *>(); } iterator end() const { return begin() + NumParameters; } @@ -3945,6 +4034,9 @@ public: /// declaration which is responsible for the lifetime extension. class MaterializeTemporaryExpr : public Expr { private: + friend class ASTStmtReader; + friend class ASTStmtWriter; + struct ExtraState { /// \brief The temporary-generating expression whose value will be /// materialized. @@ -3958,24 +4050,21 @@ private: }; llvm::PointerUnion<Stmt *, ExtraState *> State; - friend class ASTStmtReader; - friend class ASTStmtWriter; - void initializeExtraState(const ValueDecl *ExtendedBy, unsigned ManglingNumber); public: MaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference) - : Expr(MaterializeTemporaryExprClass, T, - BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, - Temporary->isTypeDependent(), Temporary->isValueDependent(), - Temporary->isInstantiationDependent(), - Temporary->containsUnexpandedParameterPack()), + : Expr(MaterializeTemporaryExprClass, T, + BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary, + Temporary->isTypeDependent(), Temporary->isValueDependent(), + Temporary->isInstantiationDependent(), + Temporary->containsUnexpandedParameterPack()), State(Temporary) {} MaterializeTemporaryExpr(EmptyShell Empty) - : Expr(MaterializeTemporaryExprClass, Empty) { } + : Expr(MaterializeTemporaryExprClass, Empty) {} Stmt *getTemporary() const { return State.is<Stmt *>() ? State.get<Stmt *>() @@ -4026,6 +4115,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return getTemporary()->getLocStart(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getTemporary()->getLocEnd(); } @@ -4053,14 +4143,15 @@ public: /// ( ... op expr ) /// ( expr op ... op expr ) class CXXFoldExpr : public Expr { + friend class ASTStmtReader; + friend class ASTStmtWriter; + SourceLocation LParenLoc; SourceLocation EllipsisLoc; SourceLocation RParenLoc; Stmt *SubExprs[2]; BinaryOperatorKind Opcode; - friend class ASTStmtReader; - friend class ASTStmtWriter; public: CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, @@ -4073,6 +4164,7 @@ public: SubExprs[0] = LHS; SubExprs[1] = RHS; } + CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {} Expr *getLHS() const { return static_cast<Expr*>(SubExprs[0]); } @@ -4082,10 +4174,13 @@ public: bool isRightFold() const { return getLHS() && getLHS()->containsUnexpandedParameterPack(); } + /// Does this produce a left-associated sequence of operators? bool isLeftFold() const { return !isRightFold(); } + /// Get the pattern, that is, the operand that contains an unexpanded pack. Expr *getPattern() const { return isLeftFold() ? getRHS() : getLHS(); } + /// Get the operand that doesn't contain a pack, for a binary fold. Expr *getInit() const { return isLeftFold() ? getLHS() : getRHS(); } @@ -4095,6 +4190,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } @@ -4121,13 +4217,15 @@ public: /// expression is evaluated, and its result is the result of the overall /// expression. class CoroutineSuspendExpr : public Expr { + friend class ASTStmtReader; + SourceLocation KeywordLoc; enum SubExpr { Common, Ready, Suspend, Resume, Count }; + Stmt *SubExprs[SubExpr::Count]; OpaqueValueExpr *OpaqueValue = nullptr; - friend class ASTStmtReader; public: CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume, @@ -4142,6 +4240,7 @@ public: SubExprs[SubExpr::Suspend] = Suspend; SubExprs[SubExpr::Resume] = Resume; } + CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, Expr *Common) : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true, @@ -4154,6 +4253,7 @@ public: SubExprs[SubExpr::Suspend] = nullptr; SubExprs[SubExpr::Resume] = nullptr; } + CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { SubExprs[SubExpr::Common] = nullptr; SubExprs[SubExpr::Ready] = nullptr; @@ -4162,18 +4262,22 @@ public: } SourceLocation getKeywordLoc() const { return KeywordLoc; } + Expr *getCommonExpr() const { return static_cast<Expr*>(SubExprs[SubExpr::Common]); } + /// \brief getOpaqueValue - Return the opaque value placeholder. OpaqueValueExpr *getOpaqueValue() const { return OpaqueValue; } Expr *getReadyExpr() const { return static_cast<Expr*>(SubExprs[SubExpr::Ready]); } + Expr *getSuspendExpr() const { return static_cast<Expr*>(SubExprs[SubExpr::Suspend]); } + Expr *getResumeExpr() const { return static_cast<Expr*>(SubExprs[SubExpr::Resume]); } @@ -4181,6 +4285,7 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return getCommonExpr()->getLocEnd(); } @@ -4198,6 +4303,7 @@ public: /// \brief Represents a 'co_await' expression. class CoawaitExpr : public CoroutineSuspendExpr { friend class ASTStmtReader; + public: CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready, Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue, @@ -4206,11 +4312,13 @@ public: Suspend, Resume, OpaqueValue) { CoawaitBits.IsImplicit = IsImplicit; } + CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand, bool IsImplicit = false) : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) { CoawaitBits.IsImplicit = IsImplicit; } + CoawaitExpr(EmptyShell Empty) : CoroutineSuspendExpr(CoawaitExprClass, Empty) {} @@ -4230,11 +4338,11 @@ public: /// \brief Represents a 'co_await' expression while the type of the promise /// is dependent. class DependentCoawaitExpr : public Expr { + friend class ASTStmtReader; + SourceLocation KeywordLoc; Stmt *SubExprs[2]; - friend class ASTStmtReader; - public: DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op, UnresolvedLookupExpr *OpCoawait) @@ -4255,12 +4363,15 @@ public: : Expr(DependentCoawaitExprClass, Empty) {} Expr *getOperand() const { return cast<Expr>(SubExprs[0]); } + UnresolvedLookupExpr *getOperatorCoawaitLookup() const { return cast<UnresolvedLookupExpr>(SubExprs[1]); } + SourceLocation getKeywordLoc() const { return KeywordLoc; } SourceLocation getLocStart() const LLVM_READONLY { return KeywordLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return getOperand()->getLocEnd(); } @@ -4275,6 +4386,7 @@ public: /// \brief Represents a 'co_yield' expression. class CoyieldExpr : public CoroutineSuspendExpr { friend class ASTStmtReader; + public: CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready, Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) @@ -4295,6 +4407,6 @@ public: } }; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_EXPRCXX_H diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index cd9381758618..ab2df8a34819 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -1,4 +1,4 @@ -//===--- ExprObjC.h - Classes for representing ObjC expressions -*- C++ -*-===// +//===- ExprObjC.h - Classes for representing ObjC expressions ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,28 +14,51 @@ #ifndef LLVM_CLANG_AST_EXPROBJC_H #define LLVM_CLANG_AST_EXPROBJC_H +#include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" +#include "clang/AST/OperationKinds.h" #include "clang/AST/SelectorLocationsKind.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/Type.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/Specifiers.h" +#include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" +#include "llvm/Support/type_traits.h" +#include <cassert> +#include <cstddef> +#include <cstdint> namespace clang { - class IdentifierInfo; - class ASTContext; + +class ASTContext; +class CXXBaseSpecifier; /// ObjCStringLiteral, used for Objective-C string literals /// i.e. @"foo". class ObjCStringLiteral : public Expr { Stmt *String; SourceLocation AtLoc; + public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) - : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - String(SL), AtLoc(L) {} + : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, + false, false), + String(SL), AtLoc(L) {} explicit ObjCStringLiteral(EmptyShell Empty) - : Expr(ObjCStringLiteralClass, Empty) {} + : Expr(ObjCStringLiteralClass, Empty) {} StringLiteral *getString() { return cast<StringLiteral>(String); } const StringLiteral *getString() const { return cast<StringLiteral>(String); } @@ -47,26 +70,26 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return String->getLocEnd(); } + // Iterators + child_range children() { return child_range(&String, &String+1); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCStringLiteralClass; } - - // Iterators - child_range children() { return child_range(&String, &String+1); } }; /// ObjCBoolLiteralExpr - Objective-C Boolean Literal. -/// class ObjCBoolLiteralExpr : public Expr { bool Value; SourceLocation Loc; + public: - ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) : - Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), Value(val), Loc(l) {} - + ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) + : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, + false, false), + Value(val), Loc(l) {} explicit ObjCBoolLiteralExpr(EmptyShell Empty) - : Expr(ObjCBoolLiteralExprClass, Empty) { } + : Expr(ObjCBoolLiteralExprClass, Empty) {} bool getValue() const { return Value; } void setValue(bool V) { Value = V; } @@ -77,14 +100,14 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCBoolLiteralExprClass; - } - // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCBoolLiteralExprClass; + } }; /// ObjCBoxedExpr - used for generalized expression boxing. @@ -95,15 +118,19 @@ class ObjCBoxedExpr : public Expr { Stmt *SubExpr; ObjCMethodDecl *BoxingMethod; SourceRange Range; + public: + friend class ASTStmtReader; + ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, SourceRange R) - : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, - E->isTypeDependent(), E->isValueDependent(), - E->isInstantiationDependent(), E->containsUnexpandedParameterPack()), - SubExpr(E), BoxingMethod(method), Range(R) {} + : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, + E->isTypeDependent(), E->isValueDependent(), + E->isInstantiationDependent(), + E->containsUnexpandedParameterPack()), + SubExpr(E), BoxingMethod(method), Range(R) {} explicit ObjCBoxedExpr(EmptyShell Empty) - : Expr(ObjCBoxedExprClass, Empty) {} + : Expr(ObjCBoxedExprClass, Empty) {} Expr *getSubExpr() { return cast<Expr>(SubExpr); } const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } @@ -116,27 +143,27 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } + SourceRange getSourceRange() const LLVM_READONLY { return Range; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCBoxedExprClass; - } - // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } - typedef ConstExprIterator const_arg_iterator; + using const_arg_iterator = ConstExprIterator; const_arg_iterator arg_begin() const { return reinterpret_cast<Stmt const * const*>(&SubExpr); } + const_arg_iterator arg_end() const { return reinterpret_cast<Stmt const * const*>(&SubExpr + 1); } - - friend class ASTStmtReader; + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCBoxedExprClass; + } }; /// ObjCArrayLiteral - used for objective-c array containers; as in: @@ -153,9 +180,12 @@ class ObjCArrayLiteral final SourceRange SR); explicit ObjCArrayLiteral(EmptyShell Empty, unsigned NumElements) - : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} + : Expr(ObjCArrayLiteralClass, Empty), NumElements(NumElements) {} public: + friend class ASTStmtReader; + friend TrailingObjects; + static ObjCArrayLiteral *Create(const ASTContext &C, ArrayRef<Expr *> Elements, QualType T, ObjCMethodDecl * Method, @@ -168,10 +198,6 @@ public: SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCArrayLiteralClass; - } - /// \brief Retrieve elements of array of literals. Expr **getElements() { return getTrailingObjects<Expr *>(); } @@ -183,7 +209,7 @@ public: /// getNumElements - Return number of elements of objective-c array literal. unsigned getNumElements() const { return NumElements; } - /// getExpr - Return the Expr at the specified index. + /// getElement - Return the Element at the specified index. Expr *getElement(unsigned Index) { assert((Index < NumElements) && "Arg access out of range!"); return cast<Expr>(getElements()[Index]); @@ -203,8 +229,9 @@ public: reinterpret_cast<Stmt **>(getElements()) + NumElements); } - friend TrailingObjects; - friend class ASTStmtReader; + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCArrayLiteralClass; + } }; /// \brief An element in an Objective-C dictionary literal. @@ -226,13 +253,17 @@ struct ObjCDictionaryElement { /// \brief Determines whether this dictionary element is a pack expansion. bool isPackExpansion() const { return EllipsisLoc.isValid(); } }; -} // end namespace clang + +} // namespace clang namespace llvm { + template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {}; -} + +} // namespace llvm namespace clang { + /// \brief Internal struct for storing Key/value pair. struct ObjCDictionaryLiteral_KeyValuePair { Expr *Key; @@ -274,12 +305,8 @@ class ObjCDictionaryLiteral final SourceRange Range; ObjCMethodDecl *DictWithObjectsMethod; - typedef ObjCDictionaryLiteral_KeyValuePair KeyValuePair; - typedef ObjCDictionaryLiteral_ExpansionData ExpansionData; - - size_t numTrailingObjects(OverloadToken<KeyValuePair>) const { - return NumElements; - } + using KeyValuePair = ObjCDictionaryLiteral_KeyValuePair; + using ExpansionData = ObjCDictionaryLiteral_ExpansionData; ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryElement> VK, bool HasPackExpansions, @@ -288,10 +315,18 @@ class ObjCDictionaryLiteral final explicit ObjCDictionaryLiteral(EmptyShell Empty, unsigned NumElements, bool HasPackExpansions) - : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), - HasPackExpansions(HasPackExpansions) {} + : Expr(ObjCDictionaryLiteralClass, Empty), NumElements(NumElements), + HasPackExpansions(HasPackExpansions) {} + + size_t numTrailingObjects(OverloadToken<KeyValuePair>) const { + return NumElements; + } public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + static ObjCDictionaryLiteral *Create(const ASTContext &C, ArrayRef<ObjCDictionaryElement> VK, bool HasPackExpansions, @@ -320,17 +355,14 @@ public: return Result; } - ObjCMethodDecl *getDictWithObjectsMethod() const - { return DictWithObjectsMethod; } + ObjCMethodDecl *getDictWithObjectsMethod() const { + return DictWithObjectsMethod; + } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCDictionaryLiteralClass; - } - + // Iterators child_range children() { // Note: we're taking advantage of the layout of the KeyValuePair struct @@ -342,12 +374,11 @@ public: reinterpret_cast<Stmt **>(getTrailingObjects<KeyValuePair>()) + NumElements * 2); } - - friend class ASTStmtReader; - friend class ASTStmtWriter; - friend TrailingObjects; -}; + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCDictionaryLiteralClass; + } +}; /// ObjCEncodeExpr, used for \@encode in Objective-C. \@encode has the same /// type and behavior as StringLiteral except that the string initializer is @@ -355,19 +386,19 @@ public: class ObjCEncodeExpr : public Expr { TypeSourceInfo *EncodedType; SourceLocation AtLoc, RParenLoc; + public: ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at, SourceLocation rp) - : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, - EncodedType->getType()->isDependentType(), - EncodedType->getType()->isDependentType(), - EncodedType->getType()->isInstantiationDependentType(), - EncodedType->getType()->containsUnexpandedParameterPack()), - EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} + : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, + EncodedType->getType()->isDependentType(), + EncodedType->getType()->isDependentType(), + EncodedType->getType()->isInstantiationDependentType(), + EncodedType->getType()->containsUnexpandedParameterPack()), + EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} - SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -376,6 +407,7 @@ public: QualType getEncodedType() const { return EncodedType->getType(); } TypeSourceInfo *getEncodedTypeSourceInfo() const { return EncodedType; } + void setEncodedTypeSourceInfo(TypeSourceInfo *EncType) { EncodedType = EncType; } @@ -383,28 +415,29 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCEncodeExprClass; - } - // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCEncodeExprClass; + } }; /// ObjCSelectorExpr used for \@selector in Objective-C. class ObjCSelectorExpr : public Expr { Selector SelName; SourceLocation AtLoc, RParenLoc; + public: ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, SourceLocation rp) - : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - SelName(selInfo), AtLoc(at), RParenLoc(rp){} + : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, + false, false), + SelName(selInfo), AtLoc(at), RParenLoc(rp) {} explicit ObjCSelectorExpr(EmptyShell Empty) - : Expr(ObjCSelectorExprClass, Empty) {} + : Expr(ObjCSelectorExprClass, Empty) {} Selector getSelector() const { return SelName; } void setSelector(Selector S) { SelName = S; } @@ -420,14 +453,14 @@ public: /// getNumArgs - Return the number of actual arguments to this call. unsigned getNumArgs() const { return SelName.getNumArgs(); } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCSelectorExprClass; - } - // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCSelectorExprClass; + } }; /// ObjCProtocolExpr used for protocol expression in Objective-C. @@ -441,14 +474,18 @@ public: class ObjCProtocolExpr : public Expr { ObjCProtocolDecl *TheProtocol; SourceLocation AtLoc, ProtoLoc, RParenLoc; + public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, SourceLocation protoLoc, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} + : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, + false, false), + TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} explicit ObjCProtocolExpr(EmptyShell Empty) - : Expr(ObjCProtocolExprClass, Empty) {} + : Expr(ObjCProtocolExprClass, Empty) {} ObjCProtocolDecl *getProtocol() const { return TheProtocol; } void setProtocol(ObjCProtocolDecl *P) { TheProtocol = P; } @@ -462,17 +499,14 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCProtocolExprClass; - } - // Iterators child_range children() { return child_range(child_iterator(), child_iterator()); } - friend class ASTStmtReader; - friend class ASTStmtWriter; + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCProtocolExprClass; + } }; /// ObjCIvarRefExpr - A reference to an ObjC instance variable. @@ -480,27 +514,31 @@ class ObjCIvarRefExpr : public Expr { ObjCIvarDecl *D; Stmt *Base; SourceLocation Loc; + /// OpLoc - This is the location of '.' or '->' SourceLocation OpLoc; - - bool IsArrow:1; // True if this is "X->F", false if this is "X.F". - bool IsFreeIvar:1; // True if ivar reference has no base (self assumed). + + // True if this is "X->F", false if this is "X.F". + bool IsArrow : 1; + + // True if ivar reference has no base (self assumed). + bool IsFreeIvar : 1; public: ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, SourceLocation oploc, Expr *base, - bool arrow = false, bool freeIvar = false) : - Expr(ObjCIvarRefExprClass, t, VK_LValue, - d->isBitField() ? OK_BitField : OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - D(d), Base(base), Loc(l), OpLoc(oploc), - IsArrow(arrow), IsFreeIvar(freeIvar) {} + bool arrow = false, bool freeIvar = false) + : Expr(ObjCIvarRefExprClass, t, VK_LValue, + d->isBitField() ? OK_BitField : OK_Ordinary, + /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), + base->containsUnexpandedParameterPack()), + D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow), + IsFreeIvar(freeIvar) {} explicit ObjCIvarRefExpr(EmptyShell Empty) - : Expr(ObjCIvarRefExprClass, Empty) {} + : Expr(ObjCIvarRefExprClass, Empty) {} ObjCIvarDecl *getDecl() { return D; } const ObjCIvarDecl *getDecl() const { return D; } @@ -526,12 +564,12 @@ public: SourceLocation getOpLoc() const { return OpLoc; } void setOpLoc(SourceLocation L) { OpLoc = L; } + // Iterators + child_range children() { return child_range(&Base, &Base+1); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIvarRefExprClass; } - - // Iterators - child_range children() { return child_range(&Base, &Base+1); } }; /// ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC @@ -542,7 +580,7 @@ private: /// pointer is an (optional) ObjCMethodDecl and Setter may be set. /// if the bool is false, this is an explicit property reference; /// the pointer is an ObjCPropertyDecl and Setter is always null. - llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter; + llvm::PointerIntPair<NamedDecl *, 1, bool> PropertyOrGetter; /// \brief Indicates whether the property reference will result in a message /// to the getter, the setter, or both. @@ -567,40 +605,39 @@ private: /// the location of the 'super' keyword. When it's an interface, /// this is that interface. SourceLocation ReceiverLoc; - llvm::PointerUnion3<Stmt*, const Type*, ObjCInterfaceDecl*> Receiver; + llvm::PointerUnion3<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver; public: ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, Expr *base) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), SetterAndMethodRefFlags(), - IdLoc(l), ReceiverLoc(), Receiver(base) { + : Expr(ObjCPropertyRefExprClass, t, VK, OK, + /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), + base->containsUnexpandedParameterPack()), + PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) { assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, SourceLocation sl, QualType st) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false, st->isInstantiationDependentType(), - st->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), SetterAndMethodRefFlags(), - IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { + : Expr(ObjCPropertyRefExprClass, t, VK, OK, + /*TypeDependent=*/false, false, st->isInstantiationDependentType(), + st->containsUnexpandedParameterPack()), + PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl), + Receiver(st.getTypePtr()) { assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, Expr *Base) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, - Base->isValueDependent(), Base->isInstantiationDependent(), - Base->containsUnexpandedParameterPack()), - PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), - IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) { + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, + Base->isValueDependent(), Base->isInstantiationDependent(), + Base->containsUnexpandedParameterPack()), + PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), + IdLoc(IdLoc), Receiver(Base) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } @@ -608,9 +645,9 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation SuperLoc, QualType SuperTy) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), - PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), - IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), + PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), + IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } @@ -618,14 +655,14 @@ public: QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), - PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), - IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { + : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), + PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), + IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); } explicit ObjCPropertyRefExpr(EmptyShell Empty) - : Expr(ObjCPropertyRefExprClass, Empty) {} + : Expr(ObjCPropertyRefExprClass, Empty) {} bool isImplicitProperty() const { return PropertyOrGetter.getInt(); } bool isExplicitProperty() const { return !PropertyOrGetter.getInt(); } @@ -689,6 +726,7 @@ public: SourceLocation getLocation() const { return IdLoc; } SourceLocation getReceiverLocation() const { return ReceiverLoc; } + QualType getSuperReceiverType() const { return QualType(Receiver.get<const Type*>(), 0); } @@ -696,6 +734,7 @@ public: ObjCInterfaceDecl *getClassReceiver() const { return Receiver.get<ObjCInterfaceDecl*>(); } + bool isObjectReceiver() const { return Receiver.is<Stmt*>(); } bool isSuperReceiver() const { return Receiver.is<const Type*>(); } bool isClassReceiver() const { return Receiver.is<ObjCInterfaceDecl*>(); } @@ -706,11 +745,8 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return isObjectReceiver() ? getBase()->getLocStart() :getReceiverLocation(); } - SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCPropertyRefExprClass; - } + SourceLocation getLocEnd() const LLVM_READONLY { return IdLoc; } // Iterators child_range children() { @@ -721,15 +757,21 @@ public: return child_range(child_iterator(), child_iterator()); } + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCPropertyRefExprClass; + } + private: friend class ASTStmtReader; friend class ASTStmtWriter; + void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) { PropertyOrGetter.setPointer(D); PropertyOrGetter.setInt(false); SetterAndMethodRefFlags.setPointer(nullptr); SetterAndMethodRefFlags.setInt(methRefFlags); } + void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, unsigned methRefFlags) { PropertyOrGetter.setPointer(Getter); @@ -737,6 +779,7 @@ private: SetterAndMethodRefFlags.setPointer(Setter); SetterAndMethodRefFlags.setInt(methRefFlags); } + void setBase(Expr *Base) { Receiver = Base; } void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); } void setClassReceiver(ObjCInterfaceDecl *D) { Receiver = D; } @@ -756,10 +799,10 @@ private: /// ObjCSubscriptRefExpr - used for array and dictionary subscripting. /// array[4] = array[3]; dictionary[key] = dictionary[alt_key]; -/// class ObjCSubscriptRefExpr : public Expr { // Location of ']' in an indexing expression. SourceLocation RBracket; + // array/dictionary base expression. // for arrays, this is a numeric expression. For dictionaries, this is // an objective-c object pointer expression. @@ -773,24 +816,24 @@ class ObjCSubscriptRefExpr : public Expr { ObjCMethodDecl *SetAtIndexMethodDecl; public: - ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, ExprValueKind VK, ExprObjectKind OK, ObjCMethodDecl *getMethod, ObjCMethodDecl *setMethod, SourceLocation RB) - : Expr(ObjCSubscriptRefExprClass, T, VK, OK, - base->isTypeDependent() || key->isTypeDependent(), - base->isValueDependent() || key->isValueDependent(), - base->isInstantiationDependent() || key->isInstantiationDependent(), - (base->containsUnexpandedParameterPack() || - key->containsUnexpandedParameterPack())), - RBracket(RB), - GetAtIndexMethodDecl(getMethod), - SetAtIndexMethodDecl(setMethod) - {SubExprs[BASE] = base; SubExprs[KEY] = key;} + : Expr(ObjCSubscriptRefExprClass, T, VK, OK, + base->isTypeDependent() || key->isTypeDependent(), + base->isValueDependent() || key->isValueDependent(), + (base->isInstantiationDependent() || + key->isInstantiationDependent()), + (base->containsUnexpandedParameterPack() || + key->containsUnexpandedParameterPack())), + RBracket(RB), GetAtIndexMethodDecl(getMethod), + SetAtIndexMethodDecl(setMethod) { + SubExprs[BASE] = base; SubExprs[KEY] = key; + } explicit ObjCSubscriptRefExpr(EmptyShell Empty) - : Expr(ObjCSubscriptRefExprClass, Empty) {} + : Expr(ObjCSubscriptRefExprClass, Empty) {} SourceLocation getRBracket() const { return RBracket; } void setRBracket(SourceLocation RB) { RBracket = RB; } @@ -798,11 +841,8 @@ public: SourceLocation getLocStart() const LLVM_READONLY { return SubExprs[BASE]->getLocStart(); } - SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCSubscriptRefExprClass; - } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracket; } Expr *getBaseExpr() const { return cast<Expr>(SubExprs[BASE]); } void setBaseExpr(Stmt *S) { SubExprs[BASE] = S; } @@ -825,10 +865,14 @@ public: child_range children() { return child_range(SubExprs, SubExprs+END_EXPR); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCSubscriptRefExprClass; + } + private: friend class ASTStmtReader; }; - /// \brief An expression that sends a message to the given Objective-C /// object or class. @@ -856,14 +900,13 @@ private: /// The "void *" trailing objects are actually ONE void * (the /// receiver pointer), and NumArgs Expr *. But due to the /// implementation of children(), these must be together contiguously. - class ObjCMessageExpr final : public Expr, private llvm::TrailingObjects<ObjCMessageExpr, void *, SourceLocation> { /// \brief Stores either the selector that this message is sending /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer /// referring to the method that we type-checked against. - uintptr_t SelectorOrMethod; + uintptr_t SelectorOrMethod = 0; enum { NumArgsBitWidth = 16 }; @@ -904,16 +947,9 @@ class ObjCMessageExpr final /// brackets ('[' and ']', respectively). SourceLocation LBracLoc, RBracLoc; - size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; } - - void setNumArgs(unsigned Num) { - assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); - NumArgs = Num; - } - ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs) - : Expr(ObjCMessageExprClass, Empty), SelectorOrMethod(0), Kind(0), - HasMethod(0), IsDelegateInitCall(0), IsImplicit(0), SelLocsKind(0) { + : Expr(ObjCMessageExprClass, Empty), Kind(0), HasMethod(false), + IsDelegateInitCall(false), IsImplicit(false), SelLocsKind(0) { setNumArgs(NumArgs); } @@ -950,6 +986,13 @@ class ObjCMessageExpr final SourceLocation RBracLoc, bool isImplicit); + size_t numTrailingObjects(OverloadToken<void *>) const { return NumArgs + 1; } + + void setNumArgs(unsigned Num) { + assert((Num >> NumArgsBitWidth) == 0 && "Num of args is out of range!"); + NumArgs = Num; + } + void initArgsAndSelLocs(ArrayRef<Expr *> Args, ArrayRef<SourceLocation> SelLocs, SelectorLocationsKind SelLocsK); @@ -965,6 +1008,7 @@ class ObjCMessageExpr final SelectorLocationsKind getSelLocsKind() const { return (SelectorLocationsKind)SelLocsKind; } + bool hasStandardSelLocs() const { return getSelLocsKind() != SelLoc_NonStandard; } @@ -997,14 +1041,21 @@ class ObjCMessageExpr final unsigned NumStoredSelLocs); public: + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend TrailingObjects; + /// \brief The kind of receiver this message is sending to. enum ReceiverKind { /// \brief The receiver is a class. Class = 0, + /// \brief The receiver is an object instance. Instance, + /// \brief The receiver is a superclass. SuperClass, + /// \brief The receiver is the instance of the superclass object. SuperInstance }; @@ -1029,7 +1080,7 @@ public: /// \param Sel The selector used to determine which method gets called. /// /// \param Method The Objective-C method against which this message - /// send was type-checked. May be NULL. + /// send was type-checked. May be nullptr. /// /// \param Args The message send arguments. /// @@ -1065,7 +1116,7 @@ public: /// \param Sel The selector used to determine which method gets called. /// /// \param Method The Objective-C method against which this message - /// send was type-checked. May be NULL. + /// send was type-checked. May be nullptr. /// /// \param Args The message send arguments. /// @@ -1099,7 +1150,7 @@ public: /// \param Sel The selector used to determine which method gets called. /// /// \param Method The Objective-C method against which this message - /// send was type-checked. May be NULL. + /// send was type-checked. May be nullptr. /// /// \param Args The message send arguments. /// @@ -1175,11 +1226,11 @@ public: if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo()) return TSInfo->getType(); - return QualType(); + return {}; } /// \brief Returns a type-source information of a class message - /// send, or NULL if the message is not a class message. + /// send, or nullptr if the message is not a class message. TypeSourceInfo *getClassReceiverTypeInfo() const { if (getReceiverKind() == Class) return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer()); @@ -1220,7 +1271,7 @@ public: /// whether the message is a class or an instance method, whether it /// is a send to super or not, etc. /// - /// \returns The Objective-C interface if known, otherwise NULL. + /// \returns The Objective-C interface if known, otherwise nullptr. ObjCInterfaceDecl *getReceiverInterface() const; /// \brief Retrieve the type referred to by 'super'. @@ -1295,6 +1346,7 @@ public: assert(Arg < NumArgs && "Arg access out of range!"); return getArgs()[Arg]; } + /// setArg - Set the specified argument. void setArg(unsigned Arg, Expr *ArgExpr) { assert(Arg < NumArgs && "Arg access out of range!"); @@ -1315,6 +1367,7 @@ public: return getLocStart(); return getSelectorLoc(0); } + SourceLocation getSelectorLoc(unsigned Index) const { assert(Index < getNumSelectorLocs() && "Index out of range!"); if (hasStandardSelLocs()) @@ -1341,18 +1394,15 @@ public: LBracLoc = R.getBegin(); RBracLoc = R.getEnd(); } + SourceLocation getLocStart() const LLVM_READONLY { return LBracLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return RBracLoc; } - static bool classof(const Stmt *T) { - return T->getStmtClass() == ObjCMessageExprClass; - } - // Iterators child_range children(); - typedef ExprIterator arg_iterator; - typedef ConstExprIterator const_arg_iterator; + using arg_iterator = ExprIterator; + using const_arg_iterator = ConstExprIterator; llvm::iterator_range<arg_iterator> arguments() { return llvm::make_range(arg_begin(), arg_end()); @@ -1363,19 +1413,22 @@ public: } arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } + arg_iterator arg_end() { return reinterpret_cast<Stmt **>(getArgs() + NumArgs); } + const_arg_iterator arg_begin() const { return reinterpret_cast<Stmt const * const*>(getArgs()); } + const_arg_iterator arg_end() const { return reinterpret_cast<Stmt const * const*>(getArgs() + NumArgs); } - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCMessageExprClass; + } }; /// ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type. @@ -1392,17 +1445,18 @@ class ObjCIsaExpr : public Expr { /// IsArrow - True if this is "X->F", false if this is "X.F". bool IsArrow; + public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, QualType ty) - : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - /*ContainsUnexpandedParameterPack=*/false), - Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} + : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, + /*TypeDependent=*/false, base->isValueDependent(), + base->isInstantiationDependent(), + /*ContainsUnexpandedParameterPack=*/false), + Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} /// \brief Build an empty expression. - explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) { } + explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {} void setBase(Expr *E) { Base = E; } Expr *getBase() const { return cast<Expr>(Base); } @@ -1430,15 +1484,14 @@ public: SourceLocation getExprLoc() const LLVM_READONLY { return IsaMemberLoc; } + // Iterators + child_range children() { return child_range(&Base, &Base+1); } + static bool classof(const Stmt *T) { return T->getStmtClass() == ObjCIsaExprClass; } - - // Iterators - child_range children() { return child_range(&Base, &Base+1); } }; - /// ObjCIndirectCopyRestoreExpr - Represents the passing of a function /// argument by indirect copy-restore in ARC. This is used to support /// passing indirect arguments with the wrong lifetime, e.g. when @@ -1462,27 +1515,27 @@ public: /// __autoreleasing; this qualifier is ignored when initializing /// the value. class ObjCIndirectCopyRestoreExpr : public Expr { + friend class ASTReader; + friend class ASTStmtReader; + Stmt *Operand; // unsigned ObjCIndirectCopyRestoreBits.ShouldCopy : 1; - friend class ASTReader; - friend class ASTStmtReader; + explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) + : Expr(ObjCIndirectCopyRestoreExprClass, Empty) {} void setShouldCopy(bool shouldCopy) { ObjCIndirectCopyRestoreExprBits.ShouldCopy = shouldCopy; } - explicit ObjCIndirectCopyRestoreExpr(EmptyShell Empty) - : Expr(ObjCIndirectCopyRestoreExprClass, Empty) { } - public: ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) - : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, - operand->isTypeDependent(), operand->isValueDependent(), - operand->isInstantiationDependent(), - operand->containsUnexpandedParameterPack()), - Operand(operand) { + : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, + operand->isTypeDependent(), operand->isValueDependent(), + operand->isInstantiationDependent(), + operand->containsUnexpandedParameterPack()), + Operand(operand) { setShouldCopy(shouldCopy); } @@ -1519,26 +1572,26 @@ public: class ObjCBridgedCastExpr final : public ExplicitCastExpr, private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class CastExpr; + friend TrailingObjects; + SourceLocation LParenLoc; SourceLocation BridgeKeywordLoc; unsigned Kind : 2; - friend TrailingObjects; - friend class CastExpr; - friend class ASTStmtReader; - friend class ASTStmtWriter; - public: ObjCBridgedCastExpr(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, CastKind CK, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *Operand) - : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, - CK, Operand, 0, TSInfo), - LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) { } + : ExplicitCastExpr(ObjCBridgedCastExprClass, TSInfo->getType(), VK_RValue, + CK, Operand, 0, TSInfo), + LParenLoc(LParenLoc), BridgeKeywordLoc(BridgeKeywordLoc), Kind(Kind) {} /// \brief Construct an empty Objective-C bridged cast. explicit ObjCBridgedCastExpr(EmptyShell Shell) - : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) { } + : ExplicitCastExpr(ObjCBridgedCastExprClass, Shell, 0) {} SourceLocation getLParenLoc() const { return LParenLoc; } @@ -1554,6 +1607,7 @@ public: SourceLocation getBridgeKeywordLoc() const { return BridgeKeywordLoc; } SourceLocation getLocStart() const LLVM_READONLY { return LParenLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { return getSubExpr()->getLocEnd(); } @@ -1577,10 +1631,11 @@ public: /// expressions. /// class ObjCAvailabilityCheckExpr : public Expr { + friend class ASTStmtReader; + VersionTuple VersionToCheck; SourceLocation AtLoc, RParen; - friend class ASTStmtReader; public: ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, SourceLocation RParen, QualType Ty) @@ -1608,6 +1663,6 @@ public: } }; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_EXPROBJC_H diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h index 51d0c30ad23b..81492aec6e13 100644 --- a/include/clang/AST/ExternalASTMerger.h +++ b/include/clang/AST/ExternalASTMerger.h @@ -16,34 +16,159 @@ #include "clang/AST/ASTImporter.h" #include "clang/AST/ExternalASTSource.h" +#include "llvm/Support/raw_ostream.h" namespace clang { +/// ExternalASTSource implementation that merges information from several +/// ASTContexts. +/// +/// ExtermalASTMerger maintains a vector of ASTImporters that it uses to import +/// (potentially incomplete) Decls and DeclContexts from the source ASTContexts +/// in response to ExternalASTSource API calls. +/// +/// When lookup occurs in the resulting imported DeclContexts, the original +/// DeclContexts need to be queried. Roughly, there are three cases here: +/// +/// - The DeclContext of origin can be found by simple name lookup. In this +/// case, no additional state is required. +/// +/// - The DeclContext of origin is different from what would be found by name +/// lookup. In this case, Origins contains an entry overriding lookup and +/// specifying the correct pair of DeclContext/ASTContext. +/// +/// - The DeclContext of origin was determined by another ExterenalASTMerger. +/// (This is possible when the source ASTContext for one of the Importers has +/// its own ExternalASTMerger). The origin must be properly forwarded in this +/// case. +/// +/// ExternalASTMerger's job is to maintain the data structures necessary to +/// allow this. The data structures themselves can be extracted (read-only) and +/// copied for re-use. class ExternalASTMerger : public ExternalASTSource { public: - struct ImporterPair { - std::unique_ptr<ASTImporter> Forward; - std::unique_ptr<ASTImporter> Reverse; + /// A single origin for a DeclContext. Unlike Decls, DeclContexts do + /// not allow their containing ASTContext to be determined in all cases. + struct DCOrigin { + DeclContext *DC; + ASTContext *AST; }; + typedef std::map<const DeclContext *, DCOrigin> OriginMap; + typedef std::vector<std::unique_ptr<ASTImporter>> ImporterVector; private: - std::vector<ImporterPair> Importers; + /// One importer exists for each source. + ImporterVector Importers; + /// Overrides in case name lookup would return nothing or would return + /// the wrong thing. + OriginMap Origins; + /// The installed log stream. + llvm::raw_ostream *LogStream; public: - struct ImporterEndpoint { + /// The target for an ExternalASTMerger. + /// + /// ASTImporters require both ASTContext and FileManager to be able to + /// import SourceLocations properly. + struct ImporterTarget { ASTContext &AST; FileManager &FM; }; - ExternalASTMerger(const ImporterEndpoint &Target, - llvm::ArrayRef<ImporterEndpoint> Sources); + /// A source for an ExternalASTMerger. + /// + /// ASTImporters require both ASTContext and FileManager to be able to + /// import SourceLocations properly. Additionally, when import occurs for + /// a DeclContext whose origin has been overridden, then this + /// ExternalASTMerger must be able to determine that. + struct ImporterSource { + ASTContext &AST; + FileManager &FM; + const OriginMap &OM; + }; +private: + /// The target for this ExtenralASTMerger. + ImporterTarget Target; + +public: + ExternalASTMerger(const ImporterTarget &Target, + llvm::ArrayRef<ImporterSource> Sources); + + /// Add a set of ASTContexts as possible origins. + /// + /// Usually the set will be initialized in the constructor, but long-lived + /// ExternalASTMergers may neeed to import from new sources (for example, + /// newly-parsed source files). + /// + /// Ensures that Importers does not gain duplicate entries as a result. + void AddSources(llvm::ArrayRef<ImporterSource> Sources); + + /// Remove a set of ASTContexts as possible origins. + /// + /// Sometimes an origin goes away (for example, if a source file gets + /// superseded by a newer version). + /// + /// The caller is responsible for ensuring that this doesn't leave + /// DeclContexts that can't be completed. + void RemoveSources(llvm::ArrayRef<ImporterSource> Sources); + + /// Implementation of the ExternalASTSource API. bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override; + /// Implementation of the ExternalASTSource API. void FindExternalLexicalDecls(const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, SmallVectorImpl<Decl *> &Result) override; + + /// Implementation of the ExternalASTSource API. + void CompleteType(TagDecl *Tag) override; + + /// Implementation of the ExternalASTSource API. + void CompleteType(ObjCInterfaceDecl *Interface) override; + + /// Returns true if DC can be found in any source AST context. + bool CanComplete(DeclContext *DC); + + /// Records an origin in Origins only if name lookup would find + /// something different or nothing at all. + void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin); + + /// Regardless of any checks, override the Origin for a DeclContext. + void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin); + + /// Get a read-only view of the Origins map, for use in constructing + /// an ImporterSource for another ExternalASTMerger. + const OriginMap &GetOrigins() { return Origins; } + + /// Returns true if Importers contains an ASTImporter whose source is + /// OriginContext. + bool HasImporterForOrigin(ASTContext &OriginContext); + + /// Returns a reference to the ASTRImporter from Importers whose origin + /// is OriginContext. This allows manual import of ASTs while preserving the + /// OriginMap correctly. + ASTImporter &ImporterForOrigin(ASTContext &OriginContext); + + /// Sets the current log stream. + void SetLogStream(llvm::raw_string_ostream &Stream) { LogStream = &Stream; } +private: + /// Records and origin in Origins. + void RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin, + ASTImporter &importer); + + /// Performs an action for every DeclContext that is identified as + /// corresponding (either by forced origin or by name lookup) to DC. + template <typename CallbackType> + void ForEachMatchingDC(const DeclContext *DC, CallbackType Callback); + +public: + /// Log something if there is a logging callback installed. + llvm::raw_ostream &logs() { return *LogStream; } + + /// True if the log stream is not llvm::nulls(); + bool LoggingEnabled() { return LogStream != &llvm::nulls(); } }; } // end namespace clang diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index d8dd18ecb8d3..be013c5d6b6a 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -1,4 +1,4 @@ -//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===// +//===- ExternalASTSource.h - Abstract External AST Interface ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,24 +11,44 @@ // construction of AST nodes from some external source. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H #include "clang/AST/CharUnits.h" #include "clang/AST/DeclBase.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <string> +#include <utility> namespace clang { class ASTConsumer; +class ASTContext; class CXXBaseSpecifier; class CXXCtorInitializer; +class CXXRecordDecl; class DeclarationName; -class ExternalSemaSource; // layering violation required for downcasting class FieldDecl; -class Module; +class IdentifierInfo; class NamedDecl; +class ObjCInterfaceDecl; class RecordDecl; class Selector; class Stmt; @@ -42,30 +62,31 @@ class TagDecl; /// actual type and declaration nodes, and read parts of declaration /// contexts. class ExternalASTSource : public RefCountedBase<ExternalASTSource> { + friend class ExternalSemaSource; + /// Generation number for this external AST source. Must be increased /// whenever we might have added new redeclarations for existing decls. - uint32_t CurrentGeneration; + uint32_t CurrentGeneration = 0; /// \brief Whether this AST source also provides information for /// semantic analysis. - bool SemaSource; - - friend class ExternalSemaSource; + bool SemaSource = false; public: - ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { } - + ExternalASTSource() = default; virtual ~ExternalASTSource(); /// \brief RAII class for safely pairing a StartedDeserializing call /// with FinishedDeserializing. class Deserializing { ExternalASTSource *Source; + public: explicit Deserializing(ExternalASTSource *source) : Source(source) { assert(Source); Source->StartedDeserializing(); } + ~Deserializing() { Source->FinishedDeserializing(); } @@ -122,7 +143,7 @@ public: virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); /// \brief Update an out-of-date identifier. - virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { } + virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {} /// \brief Find all declarations with the given name in the given context, /// and add them to the context by calling SetExternalVisibleDeclsForName @@ -154,12 +175,13 @@ public: const Module *ClangModule = nullptr; public: - ASTSourceDescriptor(){}; + ASTSourceDescriptor() = default; ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, ASTFileSignature Signature) : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature){}; + ASTFile(std::move(ASTFile)), Signature(Signature) {} ASTSourceDescriptor(const Module &M); + std::string getModuleName() const; StringRef getPath() const { return Path; } StringRef getASTFile() const { return ASTFile; } @@ -246,7 +268,6 @@ public: /// The default implementation of this method is a no-op. virtual void PrintStats(); - /// \brief Perform layout on the given record. /// /// This routine allows the external AST source to provide an specific @@ -289,7 +310,7 @@ public: size_t mmap_bytes; MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) - : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} + : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} }; /// Return the amount of memory used by memory buffers, breaking down @@ -329,12 +350,12 @@ struct LazyOffsetPtr { /// /// If the low bit is clear, a pointer to the AST node. If the low /// bit is set, the upper 63 bits are the offset. - mutable uint64_t Ptr; + mutable uint64_t Ptr = 0; public: - LazyOffsetPtr() : Ptr(0) { } + LazyOffsetPtr() = default; + explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} - explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { } explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) { assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) @@ -392,15 +413,16 @@ struct LazyGenerationalUpdatePtr { /// A cache of the value of this pointer, in the most recent generation in /// which we queried it. struct LazyData { - LazyData(ExternalASTSource *Source, T Value) - : ExternalSource(Source), LastGeneration(0), LastValue(Value) {} ExternalASTSource *ExternalSource; - uint32_t LastGeneration; + uint32_t LastGeneration = 0; T LastValue; + + LazyData(ExternalASTSource *Source, T Value) + : ExternalSource(Source), LastValue(Value) {} }; // Our value is represented as simply T if there is no external AST source. - typedef llvm::PointerUnion<T, LazyData*> ValueType; + using ValueType = llvm::PointerUnion<T, LazyData*>; ValueType Value; LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} @@ -459,25 +481,31 @@ public: return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); } }; -} // end namespace clang + +} // namespace clang /// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be /// placed into a PointerUnion. namespace llvm { + template<typename Owner, typename T, void (clang::ExternalASTSource::*Update)(Owner)> struct PointerLikeTypeTraits< clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { - typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr; + using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>; + static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } + enum { NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 }; }; -} + +} // namespace llvm namespace clang { + /// \brief Represents a lazily-loaded vector of data. /// /// The lazily-loaded vector of data contains data that is partially loaded @@ -511,13 +539,14 @@ public: class iterator : public llvm::iterator_adaptor_base< iterator, int, std::random_access_iterator_tag, T, int, T *, T &> { + friend class LazyVector; + LazyVector *Self; iterator(LazyVector *Self, int Position) : iterator::iterator_adaptor_base(Position), Self(Self) {} bool isLoaded() const { return this->I < 0; } - friend class LazyVector; public: iterator() : iterator(nullptr, 0) {} @@ -562,23 +591,23 @@ public: }; /// \brief A lazy pointer to a statement. -typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> - LazyDeclStmtPtr; +using LazyDeclStmtPtr = + LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>; /// \brief A lazy pointer to a declaration. -typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> - LazyDeclPtr; +using LazyDeclPtr = + LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>; /// \brief A lazy pointer to a set of CXXCtorInitializers. -typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, - &ExternalASTSource::GetExternalCXXCtorInitializers> - LazyCXXCtorInitializersPtr; +using LazyCXXCtorInitializersPtr = + LazyOffsetPtr<CXXCtorInitializer *, uint64_t, + &ExternalASTSource::GetExternalCXXCtorInitializers>; /// \brief A lazy pointer to a set of CXXBaseSpecifiers. -typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, - &ExternalASTSource::GetExternalCXXBaseSpecifiers> - LazyCXXBaseSpecifiersPtr; +using LazyCXXBaseSpecifiersPtr = + LazyOffsetPtr<CXXBaseSpecifier, uint64_t, + &ExternalASTSource::GetExternalCXXBaseSpecifiers>; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_EXTERNALASTSOURCE_H diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h index adf63a3aea69..3b3e4367d56c 100644 --- a/include/clang/AST/GlobalDecl.h +++ b/include/clang/AST/GlobalDecl.h @@ -1,4 +1,4 @@ -//===--- GlobalDecl.h - Global declaration holder ---------------*- C++ -*-===// +//===- GlobalDecl.h - Global declaration holder -----------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -19,6 +19,12 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" #include "clang/Basic/ABI.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/type_traits.h" +#include <cassert> namespace clang { @@ -27,7 +33,7 @@ namespace clang { /// a CXXDestructorDecl and the destructor type (Base, Complete) or /// a VarDecl, a FunctionDecl or a BlockDecl. class GlobalDecl { - llvm::PointerIntPair<const Decl*, 2> Value; + llvm::PointerIntPair<const Decl *, 2> Value; void Init(const Decl *D) { assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); @@ -37,19 +43,15 @@ class GlobalDecl { } public: - GlobalDecl() {} - + GlobalDecl() = default; GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const FunctionDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } - - GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) - : Value(D, Type) {} - GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) - : Value(D, Type) {} + GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} + GlobalDecl(const CXXDestructorDecl *D, CXXDtorType Type) : Value(D, Type) {} GlobalDecl getCanonicalDecl() const { GlobalDecl CanonGD; @@ -90,10 +92,9 @@ public: } }; -} // end namespace clang +} // namespace clang namespace llvm { - template<class> struct DenseMapInfo; template<> struct DenseMapInfo<clang::GlobalDecl> { static inline clang::GlobalDecl getEmptyKey() { @@ -113,7 +114,6 @@ namespace llvm { clang::GlobalDecl RHS) { return LHS == RHS; } - }; // GlobalDecl isn't *technically* a POD type. However, its copy constructor, @@ -122,6 +122,7 @@ namespace llvm { struct isPodLike<clang::GlobalDecl> { static const bool value = true; }; -} // end namespace llvm -#endif +} // namespace llvm + +#endif // LLVM_CLANG_AST_GLOBALDECL_H diff --git a/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h new file mode 100644 index 000000000000..264f20f19ad5 --- /dev/null +++ b/include/clang/AST/LexicallyOrderedRecursiveASTVisitor.h @@ -0,0 +1,164 @@ +//===--- LexicallyOrderedRecursiveASTVisitor.h - ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the LexicallyOrderedRecursiveASTVisitor interface, which +// recursively traverses the entire AST in a lexical order. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H +#define LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H + +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceManager.h" +#include "llvm/Support/SaveAndRestore.h" + +namespace clang { + +/// A RecursiveASTVisitor subclass that guarantees that AST traversal is +/// performed in a lexical order (i.e. the order in which declarations are +/// written in the source). +/// +/// RecursiveASTVisitor doesn't guarantee lexical ordering because there are +/// some declarations, like Objective-C @implementation declarations +/// that might be represented in the AST differently to how they were written +/// in the source. +/// In particular, Objective-C @implementation declarations may contain +/// non-Objective-C declarations, like functions: +/// +/// @implementation MyClass +/// +/// - (void) method { } +/// void normalFunction() { } +/// +/// @end +/// +/// Clang's AST stores these declarations outside of the @implementation +/// declaration, so the example above would be represented using the following +/// AST: +/// |-ObjCImplementationDecl ... MyClass +/// | `-ObjCMethodDecl ... method +/// | ... +/// `-FunctionDecl ... normalFunction +/// ... +/// +/// This class ensures that these declarations are traversed before the +/// corresponding TraverseDecl for the @implementation returns. This ensures +/// that the lexical parent relationship between these declarations and the +/// @implementation is preserved while traversing the AST. Note that the +/// current implementation doesn't mix these declarations with the declarations +/// contained in the @implementation, so the traversal of all of the +/// declarations in the @implementation still doesn't follow the lexical order. +template <typename Derived> +class LexicallyOrderedRecursiveASTVisitor + : public RecursiveASTVisitor<Derived> { + using BaseType = RecursiveASTVisitor<Derived>; + +public: + LexicallyOrderedRecursiveASTVisitor(const SourceManager &SM) : SM(SM) {} + + bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) { + // Objective-C @implementation declarations should not trigger early exit + // until the additional decls are traversed as their children are not + // lexically ordered. + bool Result = BaseType::TraverseObjCImplementationDecl(D); + return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false; + } + + bool TraverseObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { + bool Result = BaseType::TraverseObjCCategoryImplDecl(D); + return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false; + } + + bool TraverseDeclContextHelper(DeclContext *DC) { + if (!DC) + return true; + + for (auto I = DC->decls_begin(), E = DC->decls_end(); I != E;) { + Decl *Child = *I; + if (BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Child)) { + ++I; + continue; + } + if (!isa<ObjCImplementationDecl>(Child) && + !isa<ObjCCategoryImplDecl>(Child)) { + if (!BaseType::getDerived().TraverseDecl(Child)) + return false; + ++I; + continue; + } + // Gather declarations that follow the Objective-C implementation + // declarations but are lexically contained in the implementation. + LexicallyNestedDeclarations.clear(); + for (++I; I != E; ++I) { + Decl *Sibling = *I; + if (!SM.isBeforeInTranslationUnit(Sibling->getLocStart(), + Child->getLocEnd())) + break; + if (!BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Sibling)) + LexicallyNestedDeclarations.push_back(Sibling); + } + if (!BaseType::getDerived().TraverseDecl(Child)) + return false; + } + return true; + } + + Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); } + + SmallVector<Stmt *, 8> getStmtChildren(CXXOperatorCallExpr *CE) { + SmallVector<Stmt *, 8> Children(CE->children()); + bool Swap; + // Switch the operator and the first operand for all infix and postfix + // operations. + switch (CE->getOperator()) { + case OO_Arrow: + case OO_Call: + case OO_Subscript: + Swap = true; + break; + case OO_PlusPlus: + case OO_MinusMinus: + // These are postfix unless there is exactly one argument. + Swap = Children.size() != 2; + break; + default: + Swap = CE->isInfixBinaryOp(); + break; + } + if (Swap && Children.size() > 1) + std::swap(Children[0], Children[1]); + return Children; + } + +private: + bool TraverseAdditionalLexicallyNestedDeclarations() { + // FIXME: Ideally the gathered declarations and the declarations in the + // @implementation should be mixed and sorted to get a true lexical order, + // but right now we only care about getting the correct lexical parent, so + // we can traverse the gathered nested declarations after the declarations + // in the decl context. + assert(!BaseType::getDerived().shouldTraversePostOrder() && + "post-order traversal is not supported for lexically ordered " + "recursive ast visitor"); + for (Decl *D : LexicallyNestedDeclarations) { + if (!BaseType::getDerived().TraverseDecl(D)) + return false; + } + return true; + } + + const SourceManager &SM; + llvm::SmallVector<Decl *, 8> LexicallyNestedDeclarations; +}; + +} // end namespace clang + +#endif // LLVM_CLANG_AST_LEXICALLY_ORDERED_RECURSIVEASTVISITOR_H diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h index b1ff9bdff589..e2cb45c36de6 100644 --- a/include/clang/AST/NestedNameSpecifier.h +++ b/include/clang/AST/NestedNameSpecifier.h @@ -1,4 +1,4 @@ -//===--- NestedNameSpecifier.h - C++ nested name specifiers -----*- C++ -*-===// +//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,38 +11,42 @@ // a C++ nested-name-specifier. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Compiler.h" +#include <cstdint> +#include <cstdlib> +#include <utility> namespace clang { class ASTContext; class CXXRecordDecl; +class IdentifierInfo; +class LangOptions; class NamespaceAliasDecl; class NamespaceDecl; -class IdentifierInfo; struct PrintingPolicy; class Type; class TypeLoc; -class LangOptions; /// \brief Represents a C++ nested name specifier, such as /// "\::std::vector<int>::". /// /// C++ nested name specifiers are the prefixes to qualified -/// namespaces. For example, "foo::" in "foo::x" is a nested name +/// names. For example, "foo::" in "foo::x" is a nested name /// specifier. Nested name specifiers are made up of a sequence of /// specifiers, each of which can be a namespace, type, identifier /// (for dependent names), decltype specifier, or the global specifier ('::'). /// The last two specifiers can only appear at the start of a /// nested-namespace-specifier. class NestedNameSpecifier : public llvm::FoldingSetNode { - /// \brief Enumeration describing enum StoredSpecifierKind { StoredIdentifier = 0, @@ -66,7 +70,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode { /// specifier '::'. Otherwise, the pointer is one of /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of /// specifier as encoded within the prefix. - void* Specifier; + void* Specifier = nullptr; public: /// \brief The kind of specifier that completes this nested name @@ -74,17 +78,23 @@ public: enum SpecifierKind { /// \brief An identifier, stored as an IdentifierInfo*. Identifier, + /// \brief A namespace, stored as a NamespaceDecl*. Namespace, + /// \brief A namespace alias, stored as a NamespaceAliasDecl*. NamespaceAlias, + /// \brief A type, stored as a Type*. TypeSpec, + /// \brief A type that was preceded by the 'template' keyword, /// stored as a Type*. TypeSpecWithTemplate, + /// \brief The global specifier '::'. There is no stored value. Global, + /// \brief Microsoft's '__super' specifier, stored as a CXXRecordDecl* of /// the class it appeared in. Super @@ -92,17 +102,11 @@ public: private: /// \brief Builds the global specifier. - NestedNameSpecifier() - : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {} + NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {} /// \brief Copy constructor used internally to clone nested name /// specifiers. - NestedNameSpecifier(const NestedNameSpecifier &Other) - : llvm::FoldingSetNode(Other), Prefix(Other.Prefix), - Specifier(Other.Specifier) { - } - - void operator=(const NestedNameSpecifier &) = delete; + NestedNameSpecifier(const NestedNameSpecifier &Other) = default; /// \brief Either find or insert the given nested name specifier /// mockup in the given context. @@ -110,6 +114,8 @@ private: const NestedNameSpecifier &Mockup); public: + NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete; + /// \brief Builds a specifier combining a prefix and an identifier. /// /// The prefix must be dependent, since nested name specifiers @@ -224,8 +230,8 @@ public: /// \brief A C++ nested-name-specifier augmented with source location /// information. class NestedNameSpecifierLoc { - NestedNameSpecifier *Qualifier; - void *Data; + NestedNameSpecifier *Qualifier = nullptr; + void *Data = nullptr; /// \brief Determines the data length for the last component in the /// given nested-name-specifier. @@ -237,12 +243,12 @@ class NestedNameSpecifierLoc { public: /// \brief Construct an empty nested-name-specifier. - NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { } + NestedNameSpecifierLoc() = default; /// \brief Construct a nested-name-specifier with source location information /// from NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data) - : Qualifier(Qualifier), Data(Data) { } + : Qualifier(Qualifier), Data(Data) {} /// \brief Evalutes true when this nested-name-specifier location is /// non-empty. @@ -339,7 +345,7 @@ public: class NestedNameSpecifierLocBuilder { /// \brief The current representation of the nested-name-specifier we're /// building. - NestedNameSpecifier *Representation; + NestedNameSpecifier *Representation = nullptr; /// \brief Buffer used to store source-location information for the /// nested-name-specifier. @@ -347,21 +353,18 @@ class NestedNameSpecifierLocBuilder { /// Note that we explicitly manage the buffer (rather than using a /// SmallVector) because \c Declarator expects it to be possible to memcpy() /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder. - char *Buffer; + char *Buffer = nullptr; /// \brief The size of the buffer used to store source-location information /// for the nested-name-specifier. - unsigned BufferSize; + unsigned BufferSize = 0; /// \brief The capacity of the buffer used to store source-location /// information for the nested-name-specifier. - unsigned BufferCapacity; + unsigned BufferCapacity = 0; public: - NestedNameSpecifierLocBuilder() - : Representation(nullptr), Buffer(nullptr), BufferSize(0), - BufferCapacity(0) {} - + NestedNameSpecifierLocBuilder() = default; NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other); NestedNameSpecifierLocBuilder & @@ -451,6 +454,7 @@ public: /// \param ColonColonLoc The location of the trailing '::'. void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc); + /// \brief Make a new nested-name-specifier from incomplete source-location /// information. /// @@ -511,6 +515,6 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, return DB; } -} +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index a1cae8e18f84..1f732f67517a 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -6,35 +6,55 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// /// \file /// \brief This file defines OpenMP AST classes for clauses. /// There are clauses for executable directives, clauses for declarative /// directives and clauses which can be used in both kinds of directives. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H #define LLVM_CLANG_AST_OPENMPCLAUSE_H +#include "clang/AST/Decl.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtIterator.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> +#include <cstddef> +#include <iterator> +#include <utility> namespace clang { +class ASTContext; + //===----------------------------------------------------------------------===// // AST classes for clauses. //===----------------------------------------------------------------------===// /// \brief This is a basic class for representing single OpenMP clause. -/// class OMPClause { /// \brief Starting location of the clause (the clause keyword). SourceLocation StartLoc; + /// \brief Ending location of the clause. SourceLocation EndLoc; + /// \brief Kind of the clause. OpenMPClauseKind Kind; @@ -45,11 +65,13 @@ protected: public: /// \brief Returns the starting location of the clause. SourceLocation getLocStart() const { return StartLoc; } + /// \brief Returns the ending location of the clause. SourceLocation getLocEnd() const { return EndLoc; } /// \brief Sets the starting location of the clause. void setLocStart(SourceLocation Loc) { StartLoc = Loc; } + /// \brief Sets the ending location of the clause. void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } @@ -58,16 +80,17 @@ public: bool isImplicit() const { return StartLoc.isInvalid(); } - typedef StmtIterator child_iterator; - typedef ConstStmtIterator const_child_iterator; - typedef llvm::iterator_range<child_iterator> child_range; - typedef llvm::iterator_range<const_child_iterator> const_child_range; + using child_iterator = StmtIterator; + using const_child_iterator = ConstStmtIterator; + using child_range = llvm::iterator_range<child_iterator>; + using const_child_range = llvm::iterator_range<const_child_iterator>; child_range children(); const_child_range children() const { auto Children = const_cast<OMPClause *>(this)->children(); return const_child_range(Children.begin(), Children.end()); } + static bool classof(const OMPClause *) { return true; } }; @@ -75,29 +98,34 @@ public: /// 'shedule', 'firstprivate' etc. class OMPClauseWithPreInit { friend class OMPClauseReader; + /// Pre-initialization statement for the clause. - Stmt *PreInit; + Stmt *PreInit = nullptr; + /// Region that captures the associated stmt. - OpenMPDirectiveKind CaptureRegion; + OpenMPDirectiveKind CaptureRegion = OMPD_unknown; protected: + OMPClauseWithPreInit(const OMPClause *This) { + assert(get(This) && "get is not tuned for pre-init."); + } + /// Set pre-initialization statement for the clause. void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) { PreInit = S; CaptureRegion = ThisRegion; } - OMPClauseWithPreInit(const OMPClause *This) - : PreInit(nullptr), CaptureRegion(OMPD_unknown) { - assert(get(This) && "get is not tuned for pre-init."); - } public: /// Get pre-initialization statement for the clause. const Stmt *getPreInitStmt() const { return PreInit; } + /// Get pre-initialization statement for the clause. Stmt *getPreInitStmt() { return PreInit; } + /// Get capture region for the stmt in the clause. OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; } + static OMPClauseWithPreInit *get(OMPClause *C); static const OMPClauseWithPreInit *get(const OMPClause *C); }; @@ -106,21 +134,25 @@ public: /// 'lastprivate', 'reduction' etc. class OMPClauseWithPostUpdate : public OMPClauseWithPreInit { friend class OMPClauseReader; + /// Post-update expression for the clause. - Expr *PostUpdate; + Expr *PostUpdate = nullptr; + protected: - /// Set pre-initialization statement for the clause. - void setPostUpdateExpr(Expr *S) { PostUpdate = S; } - OMPClauseWithPostUpdate(const OMPClause *This) - : OMPClauseWithPreInit(This), PostUpdate(nullptr) { + OMPClauseWithPostUpdate(const OMPClause *This) : OMPClauseWithPreInit(This) { assert(get(This) && "get is not tuned for post-update."); } + /// Set pre-initialization statement for the clause. + void setPostUpdateExpr(Expr *S) { PostUpdate = S; } + public: /// Get post-update expression for the clause. const Expr *getPostUpdateExpr() const { return PostUpdate; } + /// Get post-update expression for the clause. Expr *getPostUpdateExpr() { return PostUpdate; } + static OMPClauseWithPostUpdate *get(OMPClause *C); static const OMPClauseWithPostUpdate *get(const OMPClause *C); }; @@ -130,12 +162,25 @@ public: /// '#pragma omp ...' directives. template <class T> class OMPVarListClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Number of variables in the list. unsigned NumVars; protected: + /// \brief Build a clause with \a N variables + /// + /// \param K Kind of the clause. + /// \param StartLoc Starting location of the clause (the clause keyword). + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) + : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {} + /// \brief Fetches list of variables associated with this clause. MutableArrayRef<Expr *> getVarRefs() { return MutableArrayRef<Expr *>( @@ -150,23 +195,11 @@ protected: static_cast<T *>(this)->template getTrailingObjects<Expr *>()); } - /// \brief Build a clause with \a N variables - /// - /// \param K Kind of the clause. - /// \param StartLoc Starting location of the clause (the clause keyword). - /// \param LParenLoc Location of '('. - /// \param EndLoc Ending location of the clause. - /// \param N Number of the variables in the clause. - /// - OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {} - public: - typedef MutableArrayRef<Expr *>::iterator varlist_iterator; - typedef ArrayRef<const Expr *>::iterator varlist_const_iterator; - typedef llvm::iterator_range<varlist_iterator> varlist_range; - typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range; + using varlist_iterator = MutableArrayRef<Expr *>::iterator; + using varlist_const_iterator = ArrayRef<const Expr *>::iterator; + using varlist_range = llvm::iterator_range<varlist_iterator>; + using varlist_const_range = llvm::iterator_range<varlist_const_iterator>; unsigned varlist_size() const { return NumVars; } bool varlist_empty() const { return NumVars == 0; } @@ -185,6 +218,7 @@ public: /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -203,31 +237,34 @@ public: /// \endcode /// In this example directive '#pragma omp parallel' has simple 'if' clause with /// condition 'a > 5' and directive name modifier 'parallel'. -/// class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Condition of the 'if' clause. - Stmt *Condition; + Stmt *Condition = nullptr; + /// \brief Location of ':' (if any). SourceLocation ColonLoc; + /// \brief Directive name modifier for the clause. - OpenMPDirectiveKind NameModifier; + OpenMPDirectiveKind NameModifier = OMPD_unknown; + /// \brief Name modifier location. SourceLocation NameModifierLoc; /// \brief Set condition. - /// void setCondition(Expr *Cond) { Condition = Cond; } + /// \brief Set directive name modifier for the clause. - /// void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; } + /// \brief Set location of directive name modifier for the clause. - /// void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; } + /// \brief Set location of ':'. - /// void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } public: @@ -243,7 +280,6 @@ public: /// \param NameModifierLoc Location of directive name modifier. /// \param ColonLoc [OpenMP 4.1] Location of ':'. /// \param EndLoc Ending location of the clause. - /// OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, @@ -255,14 +291,13 @@ public: } /// \brief Build an empty clause. - /// OMPIfClause() : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), - OMPClauseWithPreInit(this), LParenLoc(), Condition(nullptr), ColonLoc(), - NameModifier(OMPD_unknown), NameModifierLoc() {} + OMPClauseWithPreInit(this) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -271,17 +306,18 @@ public: /// \brief Returns condition. Expr *getCondition() const { return cast_or_null<Expr>(Condition); } + /// \brief Return directive name modifier associated with the clause. OpenMPDirectiveKind getNameModifier() const { return NameModifier; } /// \brief Return the location of directive name modifier. SourceLocation getNameModifierLoc() const { return NameModifierLoc; } + child_range children() { return child_range(&Condition, &Condition + 1); } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_if; } - - child_range children() { return child_range(&Condition, &Condition + 1); } }; /// \brief This represents 'final' clause in the '#pragma omp ...' directive. @@ -291,16 +327,16 @@ public: /// \endcode /// In this example directive '#pragma omp task' has simple 'final' /// clause with condition 'a > 5'. -/// class OMPFinalClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Condition of the 'if' clause. - Stmt *Condition; + Stmt *Condition = nullptr; /// \brief Set condition. - /// void setCondition(Expr *Cond) { Condition = Cond; } public: @@ -310,31 +346,29 @@ public: /// \param LParenLoc Location of '('. /// \param Cond Condition of the clause. /// \param EndLoc Ending location of the clause. - /// OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc), Condition(Cond) {} /// \brief Build an empty clause. - /// OMPFinalClause() - : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Condition(nullptr) {} + : OMPClause(OMPC_final, SourceLocation(), SourceLocation()) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } /// \brief Returns condition. Expr *getCondition() const { return cast_or_null<Expr>(Condition); } + child_range children() { return child_range(&Condition, &Condition + 1); } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_final; } - - child_range children() { return child_range(&Condition, &Condition + 1); } }; /// \brief This represents 'num_threads' clause in the '#pragma omp ...' @@ -345,16 +379,16 @@ public: /// \endcode /// In this example directive '#pragma omp parallel' has simple 'num_threads' /// clause with number of threads '6'. -/// class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Condition of the 'num_threads' clause. - Stmt *NumThreads; + Stmt *NumThreads = nullptr; /// \brief Set condition. - /// void setNumThreads(Expr *NThreads) { NumThreads = NThreads; } public: @@ -367,7 +401,6 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - /// OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -379,25 +412,24 @@ public: } /// \brief Build an empty clause. - /// OMPNumThreadsClause() : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), - OMPClauseWithPreInit(this), LParenLoc(SourceLocation()), - NumThreads(nullptr) {} + OMPClauseWithPreInit(this) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } /// \brief Returns number of threads. Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); } + child_range children() { return child_range(&NumThreads, &NumThreads + 1); } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_num_threads; } - - child_range children() { return child_range(&NumThreads, &NumThreads + 1); } }; /// \brief This represents 'safelen' clause in the '#pragma omp ...' @@ -412,13 +444,14 @@ public: /// concurrently with SIMD instructions can have a greater distance /// in the logical iteration space than its value. The parameter of /// the safelen clause must be a constant positive integer expression. -/// class OMPSafelenClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Safe iteration space distance. - Stmt *Safelen; + Stmt *Safelen = nullptr; /// \brief Set safelen. void setSafelen(Expr *Len) { Safelen = Len; } @@ -429,31 +462,29 @@ public: /// \param Len Expression associated with this clause. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), Safelen(Len) {} /// \brief Build an empty clause. - /// explicit OMPSafelenClause() - : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Safelen(nullptr) {} + : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } /// \brief Return safe iteration space distance. Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); } + child_range children() { return child_range(&Safelen, &Safelen + 1); } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_safelen; } - - child_range children() { return child_range(&Safelen, &Safelen + 1); } }; /// \brief This represents 'simdlen' clause in the '#pragma omp ...' @@ -467,13 +498,14 @@ public: /// If the 'simdlen' clause is used then it specifies the preferred number of /// iterations to be executed concurrently. The parameter of the 'simdlen' /// clause must be a constant positive integer expression. -/// class OMPSimdlenClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Safe iteration space distance. - Stmt *Simdlen; + Stmt *Simdlen = nullptr; /// \brief Set simdlen. void setSimdlen(Expr *Len) { Simdlen = Len; } @@ -484,31 +516,29 @@ public: /// \param Len Expression associated with this clause. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), Simdlen(Len) {} /// \brief Build an empty clause. - /// explicit OMPSimdlenClause() - : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Simdlen(nullptr) {} + : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } /// \brief Return safe iteration space distance. Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); } + child_range children() { return child_range(&Simdlen, &Simdlen + 1); } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_simdlen; } - - child_range children() { return child_range(&Simdlen, &Simdlen + 1); } }; /// \brief This represents 'collapse' clause in the '#pragma omp ...' @@ -522,13 +552,14 @@ public: /// The parameter must be a constant positive integer expression, it specifies /// the number of nested loops that should be collapsed into a single iteration /// space. -/// class OMPCollapseClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Number of for-loops. - Stmt *NumForLoops; + Stmt *NumForLoops = nullptr; /// \brief Set the number of associated for-loops. void setNumForLoops(Expr *Num) { NumForLoops = Num; } @@ -540,31 +571,29 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - /// OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), NumForLoops(Num) {} /// \brief Build an empty clause. - /// explicit OMPCollapseClause() - : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), NumForLoops(nullptr) {} + : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } /// \brief Return the number of associated for-loops. Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); } + child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } + static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_collapse; } - - child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } }; /// \brief This represents 'default' clause in the '#pragma omp ...' directive. @@ -574,26 +603,26 @@ public: /// \endcode /// In this example directive '#pragma omp parallel' has simple 'default' /// clause with kind 'shared'. -/// class OMPDefaultClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief A kind of the 'default' clause. - OpenMPDefaultClauseKind Kind; + OpenMPDefaultClauseKind Kind = OMPC_DEFAULT_unknown; + /// \brief Start location of the kind in source code. SourceLocation KindKwLoc; /// \brief Set kind of the clauses. /// /// \param K Argument of clause. - /// void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } /// \brief Set argument location. /// /// \param KLoc Argument location. - /// void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } public: @@ -604,7 +633,6 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - /// OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) @@ -612,14 +640,12 @@ public: Kind(A), KindKwLoc(ALoc) {} /// \brief Build an empty clause. - /// OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown), - KindKwLoc(SourceLocation()) {} + : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -629,13 +655,13 @@ public: /// \brief Returns location of clause kind. SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; - } - child_range children() { return child_range(child_iterator(), child_iterator()); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_default; + } }; /// \brief This represents 'proc_bind' clause in the '#pragma omp ...' @@ -646,26 +672,26 @@ public: /// \endcode /// In this example directive '#pragma omp parallel' has simple 'proc_bind' /// clause with kind 'master'. -/// class OMPProcBindClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief A kind of the 'proc_bind' clause. - OpenMPProcBindClauseKind Kind; + OpenMPProcBindClauseKind Kind = OMPC_PROC_BIND_unknown; + /// \brief Start location of the kind in source code. SourceLocation KindKwLoc; /// \brief Set kind of the clause. /// /// \param K Kind of clause. - /// void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; } /// \brief Set clause kind location. /// /// \param KLoc Kind location. - /// void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } public: @@ -677,7 +703,6 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - /// OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) @@ -685,14 +710,12 @@ public: Kind(A), KindKwLoc(ALoc) {} /// \brief Build an empty clause. - /// OMPProcBindClause() - : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown), - KindKwLoc(SourceLocation()) {} + : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } @@ -702,13 +725,13 @@ public: /// \brief Returns location of clause kind. SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; } - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_proc_bind; - } - child_range children() { return child_range(child_iterator(), child_iterator()); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_proc_bind; + } }; /// \brief This represents 'schedule' clause in the '#pragma omp ...' directive. @@ -718,58 +741,63 @@ public: /// \endcode /// In this example directive '#pragma omp for' has 'schedule' clause with /// arguments 'static' and '3'. -/// class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief A kind of the 'schedule' clause. - OpenMPScheduleClauseKind Kind; + OpenMPScheduleClauseKind Kind = OMPC_SCHEDULE_unknown; + /// \brief Modifiers for 'schedule' clause. enum {FIRST, SECOND, NUM_MODIFIERS}; OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS]; + /// \brief Locations of modifiers. SourceLocation ModifiersLoc[NUM_MODIFIERS]; + /// \brief Start location of the schedule ind in source code. SourceLocation KindLoc; + /// \brief Location of ',' (if any). SourceLocation CommaLoc; + /// \brief Chunk size. - Expr *ChunkSize; + Expr *ChunkSize = nullptr; /// \brief Set schedule kind. /// /// \param K Schedule kind. - /// void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; } + /// \brief Set the first schedule modifier. /// /// \param M Schedule modifier. - /// void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) { Modifiers[FIRST] = M; } + /// \brief Set the second schedule modifier. /// /// \param M Schedule modifier. - /// void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) { Modifiers[SECOND] = M; } + /// \brief Set location of the first schedule modifier. - /// void setFirstScheduleModifierLoc(SourceLocation Loc) { ModifiersLoc[FIRST] = Loc; } + /// \brief Set location of the second schedule modifier. - /// void setSecondScheduleModifierLoc(SourceLocation Loc) { ModifiersLoc[SECOND] = Loc; } + /// \brief Set schedule modifier location. /// /// \param M Schedule modifier location. - /// void setScheduleModifer(OpenMPScheduleClauseModifier M) { if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown) Modifiers[FIRST] = M; @@ -778,25 +806,25 @@ class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { Modifiers[SECOND] = M; } } + /// \brief Sets the location of '('. /// /// \param Loc Location of '('. - /// void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Set schedule kind start location. /// /// \param KLoc Schedule kind location. - /// void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } + /// \brief Set location of ','. /// /// \param Loc Location of ','. - /// void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; } + /// \brief Set chunk size. /// /// \param E Chunk size. - /// void setChunkSize(Expr *E) { ChunkSize = E; } public: @@ -815,7 +843,6 @@ public: /// \param M1Loc Location of the first modifier /// \param M2 The second modifier applied to 'schedule' clause. /// \param M2Loc Location of the second modifier - /// OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, @@ -833,62 +860,59 @@ public: } /// \brief Build an empty clause. - /// explicit OMPScheduleClause() : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), - OMPClauseWithPreInit(this), Kind(OMPC_SCHEDULE_unknown), - ChunkSize(nullptr) { + OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; } /// \brief Get kind of the clause. - /// OpenMPScheduleClauseKind getScheduleKind() const { return Kind; } + /// \brief Get the first modifier of the clause. - /// OpenMPScheduleClauseModifier getFirstScheduleModifier() const { return Modifiers[FIRST]; } + /// \brief Get the second modifier of the clause. - /// OpenMPScheduleClauseModifier getSecondScheduleModifier() const { return Modifiers[SECOND]; } + /// \brief Get location of '('. - /// SourceLocation getLParenLoc() { return LParenLoc; } + /// \brief Get kind location. - /// SourceLocation getScheduleKindLoc() { return KindLoc; } + /// \brief Get the first modifier location. - /// SourceLocation getFirstScheduleModifierLoc() const { return ModifiersLoc[FIRST]; } + /// \brief Get the second modifier location. - /// SourceLocation getSecondScheduleModifierLoc() const { return ModifiersLoc[SECOND]; } + /// \brief Get location of ','. - /// SourceLocation getCommaLoc() { return CommaLoc; } + /// \brief Get chunk size. - /// Expr *getChunkSize() { return ChunkSize; } + /// \brief Get chunk size. - /// const Expr *getChunkSize() const { return ChunkSize; } - static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_schedule; - } - child_range children() { return child_range(reinterpret_cast<Stmt **>(&ChunkSize), reinterpret_cast<Stmt **>(&ChunkSize) + 1); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_schedule; + } }; /// \brief This represents 'ordered' clause in the '#pragma omp ...' directive. @@ -898,13 +922,14 @@ public: /// \endcode /// In this example directive '#pragma omp for' has 'ordered' clause with /// parameter 2. -/// class OMPOrderedClause : public OMPClause { friend class OMPClauseReader; + /// \brief Location of '('. SourceLocation LParenLoc; + /// \brief Number of for-loops. - Stmt *NumForLoops; + Stmt *NumForLoops = nullptr; /// \brief Set the number of associated for-loops. void setNumForLoops(Expr *Num) { NumForLoops = Num; } @@ -916,31 +941,29 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('.< |