diff options
Diffstat (limited to 'include/clang/AST/Decl.h')
-rw-r--r-- | include/clang/AST/Decl.h | 667 |
1 files changed, 400 insertions, 267 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 54e6ebcd8af2a..4db0b1ef949ba 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 |