Index: include/clang/AST/Decl.h =================================================================== --- include/clang/AST/Decl.h +++ include/clang/AST/Decl.h @@ -1711,8 +1711,11 @@ /// contains all of the information known about the function. Other, /// previous declarations of the function are available via the /// getPreviousDecl() chain. -class FunctionDecl : public DeclaratorDecl, public DeclContext, +class FunctionDecl : public DeclaratorDecl, + public DeclContext, public Redeclarable { + // This class stores some data in DeclContext::FunctionDeclBits + // to save some space. Use the provided accessors to access it. public: /// The kind of templated function a FunctionDecl can be. enum TemplatedKind { @@ -1731,64 +1734,6 @@ LazyDeclStmtPtr Body; - // FIXME: This can be packed into the bitfields in DeclContext. - // NOTE: VC++ packs bitfields poorly if the types differ. - 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; - unsigned HasInheritedPrototype : 1; - unsigned HasWrittenPrototype : 1; - unsigned IsDeleted : 1; - unsigned IsTrivial : 1; // sunk from CXXMethodDecl - - /// This flag indicates whether this function is trivial for the purpose of - /// calls. This is meaningful only when this function is a copy/move - /// constructor or a destructor. - unsigned IsTrivialForCall : 1; - - unsigned IsDefaulted : 1; // sunk from CXXMethoDecl - unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl - unsigned HasImplicitReturnZero : 1; - unsigned IsLateTemplateParsed : 1; - unsigned IsConstexpr : 1; - unsigned InstantiationIsPending : 1; - - /// Indicates if the function uses __try. - unsigned UsesSEHTry : 1; - - /// Indicates if the function was a definition but its body was - /// skipped. - unsigned HasSkippedBody : 1; - - /// Indicates if the function declaration will have a body, once we're done - /// parsing it. - unsigned WillHaveBody : 1; - - /// Indicates that this function is a multiversioned function using attribute - /// 'target'. - unsigned IsMultiVersion : 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: - - /// Store the ODRHash after first calculation. - unsigned HasODRHash : 1; unsigned ODRHash; /// End part of this FunctionDecl's source range. @@ -1858,25 +1803,22 @@ void setParams(ASTContext &C, ArrayRef NewParamInfo); + // This is unfortunately needed because ASTDeclWriter::VisitFunctionDecl + // need to access this bit but we want to avoid making ASTDeclWriter + // a friend of FunctionDeclBitfields just for this. + bool isDeletedBit() const { return FunctionDeclBits.IsDeleted; } + + /// Whether an ODRHash has been stored. + bool hasODRHash() const { return FunctionDeclBits.HasODRHash; } + + /// State that an ODRHash has been stored. + void setHasODRHash(bool B = true) { FunctionDeclBits.HasODRHash = B; } + protected: FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, - bool isConstexprSpecified) - : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, - StartLoc), - 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), IsTrivialForCall(false), - IsDefaulted(false), - IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), - IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified), - InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false), - WillHaveBody(false), IsMultiVersion(false), - IsCopyDeductionCandidate(false), HasODRHash(false), ODRHash(0), - EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {} + bool isConstexprSpecified); using redeclarable_base = Redeclarable; @@ -2015,13 +1957,13 @@ /// 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 || HasSkippedBody || - IsLateTemplateParsed || WillHaveBody || hasDefiningAttr(); + return isDeletedAsWritten() || isDefaulted() || Body || hasSkippedBody() || + isLateTemplateParsed() || willHaveBody() || hasDefiningAttr(); } /// Returns whether this specific declaration of the function has a body. bool doesThisDeclarationHaveABody() const { - return Body || IsLateTemplateParsed; + return Body || isLateTemplateParsed(); } void setBody(Stmt *B); @@ -2031,62 +1973,102 @@ bool isVariadic() const; /// Whether this function is marked as virtual explicitly. - bool isVirtualAsWritten() const { return IsVirtualAsWritten; } - void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; } + bool isVirtualAsWritten() const { + return FunctionDeclBits.IsVirtualAsWritten; + } + + /// State that this function is marked as virtual explicitly. + void setVirtualAsWritten(bool V) { FunctionDeclBits.IsVirtualAsWritten = V; } /// Whether this virtual function is pure, i.e. makes the containing class /// abstract. - bool isPure() const { return IsPure; } + bool isPure() const { return FunctionDeclBits.IsPure; } void setPure(bool P = true); /// Whether this templated function will be late parsed. - bool isLateTemplateParsed() const { return IsLateTemplateParsed; } - void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; } + bool isLateTemplateParsed() const { + return FunctionDeclBits.IsLateTemplateParsed; + } + + /// State that this templated function will be late parsed. + void setLateTemplateParsed(bool ILT = true) { + FunctionDeclBits.IsLateTemplateParsed = ILT; + } /// Whether this function is "trivial" in some specialized C++ senses. /// Can only be true for default constructors, copy constructors, /// copy assignment operators, and destructors. Not meaningful until /// the class has been fully built by Sema. - bool isTrivial() const { return IsTrivial; } - void setTrivial(bool IT) { IsTrivial = IT; } + bool isTrivial() const { return FunctionDeclBits.IsTrivial; } + void setTrivial(bool IT) { FunctionDeclBits.IsTrivial = IT; } - bool isTrivialForCall() const { return IsTrivialForCall; } - void setTrivialForCall(bool IT) { IsTrivialForCall = IT; } + bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; } + void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; } /// Whether this function is defaulted per C++0x. Only valid for /// special member functions. - bool isDefaulted() const { return IsDefaulted; } - void setDefaulted(bool D = true) { IsDefaulted = D; } + bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; } + void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; } /// Whether this function is explicitly defaulted per C++0x. Only valid /// for special member functions. - bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; } - void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; } + bool isExplicitlyDefaulted() const { + return FunctionDeclBits.IsExplicitlyDefaulted; + } + + /// State that this function is explicitly defaulted per C++0x. Only valid + /// for special member functions. + void setExplicitlyDefaulted(bool ED = true) { + FunctionDeclBits.IsExplicitlyDefaulted = ED; + } /// Whether falling off this function implicitly returns null/zero. /// If a more specific implicit return value is required, front-ends /// should synthesize the appropriate return statements. - bool hasImplicitReturnZero() const { return HasImplicitReturnZero; } - void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; } + bool hasImplicitReturnZero() const { + return FunctionDeclBits.HasImplicitReturnZero; + } + + /// State that falling off this function implicitly returns null/zero. + /// If a more specific implicit return value is required, front-ends + /// should synthesize the appropriate return statements. + void setHasImplicitReturnZero(bool IRZ) { + FunctionDeclBits.HasImplicitReturnZero = IRZ; + } /// Whether this function has a prototype, either because one /// was explicitly written or because it was "inherited" by merging /// a declaration without a prototype with a declaration that has a /// prototype. bool hasPrototype() const { - return HasWrittenPrototype || HasInheritedPrototype; + return hasWrittenPrototype() || hasInheritedPrototype(); + } + + /// Whether this function has a written prototype. + bool hasWrittenPrototype() const { + return FunctionDeclBits.HasWrittenPrototype; } - bool hasWrittenPrototype() const { return HasWrittenPrototype; } + /// State that this function has a written prototype. + void setHasWrittenPrototype(bool P = true) { + FunctionDeclBits.HasWrittenPrototype = P; + } /// Whether this function inherited its prototype from a /// previous declaration. - bool hasInheritedPrototype() const { return HasInheritedPrototype; } - void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; } + bool hasInheritedPrototype() const { + return FunctionDeclBits.HasInheritedPrototype; + } + + /// State that this function inherited its prototype from a + /// previous declaration. + void setHasInheritedPrototype(bool P = true) { + FunctionDeclBits.HasInheritedPrototype = P; + } /// Whether this is a (C++11) constexpr function or constexpr constructor. - bool isConstexpr() const { return IsConstexpr; } - void setConstexpr(bool IC) { IsConstexpr = IC; } + bool isConstexpr() const { return FunctionDeclBits.IsConstexpr; } + void setConstexpr(bool IC) { FunctionDeclBits.IsConstexpr = IC; } /// Whether the instantiation of this function is pending. /// This bit is set when the decision to instantiate this function is made @@ -2094,12 +2076,19 @@ /// cases where instantiation did not happen because the template definition /// was not seen in this TU. This bit remains set in those cases, under the /// assumption that the instantiation will happen in some other TU. - bool instantiationIsPending() const { return InstantiationIsPending; } - void setInstantiationIsPending(bool IC) { InstantiationIsPending = IC; } + bool instantiationIsPending() const { + return FunctionDeclBits.InstantiationIsPending; + } + + /// State that the instantiation of this function is pending. + /// (see instantiationIsPending) + void setInstantiationIsPending(bool IC) { + FunctionDeclBits.InstantiationIsPending = IC; + } /// Indicates the function uses __try. - bool usesSEHTry() const { return UsesSEHTry; } - void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } + bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; } + void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; } /// Whether this function has been deleted. /// @@ -2120,9 +2109,15 @@ /// }; /// @endcode // If a function is deleted, its first declaration must be. - bool isDeleted() const { return getCanonicalDecl()->IsDeleted; } - bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; } - void setDeletedAsWritten(bool D = true) { IsDeleted = D; } + bool isDeleted() const { + return getCanonicalDecl()->FunctionDeclBits.IsDeleted; + } + + bool isDeletedAsWritten() const { + return FunctionDeclBits.IsDeleted && !isDefaulted(); + } + + void setDeletedAsWritten(bool D = true) { FunctionDeclBits.IsDeleted = D; } /// Determines whether this function is "main", which is the /// entry point into an executable program. @@ -2193,20 +2188,24 @@ bool isNoReturn() const; /// True if the function was a definition but its body was skipped. - bool hasSkippedBody() const { return HasSkippedBody; } - void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + bool hasSkippedBody() const { return FunctionDeclBits.HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { + FunctionDeclBits.HasSkippedBody = Skipped; + } /// True if this function will eventually have a body, once it's fully parsed. - bool willHaveBody() const { return WillHaveBody; } - void setWillHaveBody(bool V = true) { WillHaveBody = V; } + bool willHaveBody() const { return FunctionDeclBits.WillHaveBody; } + void setWillHaveBody(bool V = true) { FunctionDeclBits.WillHaveBody = V; } /// True if this function is considered a multiversioned function. - bool isMultiVersion() const { return getCanonicalDecl()->IsMultiVersion; } + bool isMultiVersion() const { + return getCanonicalDecl()->FunctionDeclBits.IsMultiVersion; + } /// Sets the multiversion state for this declaration and all of its /// redeclarations. void setIsMultiVersion(bool V = true) { - getCanonicalDecl()->IsMultiVersion = V; + getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V; } /// True if this function is a multiversioned dispatch function as a part of @@ -2296,27 +2295,42 @@ /// Returns the storage class as written in the source. For the /// computed linkage of symbol, see getLinkage. - StorageClass getStorageClass() const { return StorageClass(SClass); } + StorageClass getStorageClass() const { + return static_cast(FunctionDeclBits.SClass); + } + + /// Sets the storage class as written in the source. + void setStorageClass(StorageClass SClass) { + FunctionDeclBits.SClass = SClass; + } /// Determine whether the "inline" keyword was specified for this /// function. - bool isInlineSpecified() const { return IsInlineSpecified; } + bool isInlineSpecified() const { return FunctionDeclBits.IsInlineSpecified; } /// Set whether the "inline" keyword was specified for this function. void setInlineSpecified(bool I) { - IsInlineSpecified = I; - IsInline = I; + FunctionDeclBits.IsInlineSpecified = I; + FunctionDeclBits.IsInline = I; } /// Flag that this function is implicitly inline. - void setImplicitlyInline() { - IsInline = true; - } + void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; } /// Determine whether this function should be inlined, because it is /// either marked "inline" or "constexpr" or is a member function of a class /// that was defined in the class body. - bool isInlined() const { return IsInline; } + bool isInlined() const { return FunctionDeclBits.IsInline; } + + /// Whether this function is marked as explicit explicitly. + bool isExplicitSpecified() const { + return FunctionDeclBits.IsExplicitSpecified; + } + + /// State that this function is marked as explicit explicitly. + void setExplicitSpecified(bool ExpSpec = true) { + FunctionDeclBits.IsExplicitSpecified = ExpSpec; + } bool isInlineDefinitionExternallyVisible() const; Index: include/clang/AST/DeclCXX.h =================================================================== --- include/clang/AST/DeclCXX.h +++ include/clang/AST/DeclCXX.h @@ -1999,7 +1999,8 @@ SC_None, false, false) { if (EndLocation.isValid()) setRangeEnd(EndLocation); - IsExplicitSpecified = IsExplicit; + setExplicitSpecified(IsExplicit); + setIsCopyDeductionCandidate(false); } public: @@ -2015,21 +2016,20 @@ static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID); /// Whether this deduction guide is explicit. - bool isExplicit() const { return IsExplicitSpecified; } - - /// Whether this deduction guide was declared with the 'explicit' specifier. - bool isExplicitSpecified() const { return IsExplicitSpecified; } + bool isExplicit() const { return isExplicitSpecified(); } /// Get the template for which this guide performs deduction. TemplateDecl *getDeducedTemplate() const { return getDeclName().getCXXDeductionGuideTemplate(); } - void setIsCopyDeductionCandidate() { - IsCopyDeductionCandidate = true; + void setIsCopyDeductionCandidate(bool isCDC = true) { + FunctionDeclBits.IsCopyDeductionCandidate = isCDC; } - bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; } + bool isCopyDeductionCandidate() const { + return FunctionDeclBits.IsCopyDeductionCandidate; + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2475,31 +2475,20 @@ class CXXConstructorDecl final : public CXXMethodDecl, private llvm::TrailingObjects { + // This class stores some data in DeclContext::CXXConstructorDeclBits + // to save some space. Use the provided accessors to access it. + /// \name Support for base and member initializers. /// \{ /// The arguments used to initialize the base or member. LazyCXXCtorInitializersPtr CtorInitializers; - unsigned NumCtorInitializers : 31; - /// \} - - /// Whether this constructor declaration is an implicitly-declared - /// inheriting constructor. - unsigned IsInheritingConstructor : 1; CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, bool isConstexpr, - InheritedConstructor Inherited) - : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, isConstexpr, SourceLocation()), - NumCtorInitializers(0), IsInheritingConstructor((bool)Inherited) { - setImplicit(isImplicitlyDeclared); - if (Inherited) - *getTrailingObjects() = Inherited; - IsExplicitSpecified = isExplicitSpecified; - } + InheritedConstructor Inherited); void anchor() override; @@ -2542,12 +2531,12 @@ /// Retrieve an iterator past the last initializer. init_iterator init_end() { - return init_begin() + NumCtorInitializers; + return init_begin() + getNumCtorInitializers(); } /// Retrieve an iterator past the last initializer. init_const_iterator init_end() const { - return init_begin() + NumCtorInitializers; + return init_begin() + getNumCtorInitializers(); } using init_reverse_iterator = std::reverse_iterator; @@ -2571,20 +2560,22 @@ /// Determine the number of arguments used to initialize the member /// or base. unsigned getNumCtorInitializers() const { - return NumCtorInitializers; + return CXXConstructorDeclBits.NumCtorInitializers; } void setNumCtorInitializers(unsigned numCtorInitializers) { - NumCtorInitializers = numCtorInitializers; + CXXConstructorDeclBits.NumCtorInitializers = numCtorInitializers; + // This assert added because NumCtorInitializers is stored + // in CXXConstructorDeclBits as a bitfield and its width has + // been shrunk from 32 bits to fit into CXXConstructorDeclBitfields. + assert(CXXConstructorDeclBits.NumCtorInitializers == + numCtorInitializers && "NumCtorInitializers overflow!"); } void setCtorInitializers(CXXCtorInitializer **Initializers) { CtorInitializers = Initializers; } - /// Whether this function is marked as explicit explicitly. - bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// Whether this function is explicit. bool isExplicit() const { return getCanonicalDecl()->isExplicitSpecified(); @@ -2665,12 +2656,20 @@ /// Determine whether this is an implicit constructor synthesized to /// model a call to a constructor inherited from a base class. - bool isInheritingConstructor() const { return IsInheritingConstructor; } + bool isInheritingConstructor() const { + return CXXConstructorDeclBits.IsInheritingConstructor; + } + + /// State that this is an implicit constructor synthesized to + /// model a call to a constructor inherited from a base class. + void setInheritingConstructor(bool isIC = true) { + CXXConstructorDeclBits.IsInheritingConstructor = isIC; + } /// Get the constructor that this inheriting constructor is based on. InheritedConstructor getInheritedConstructor() const { - return IsInheritingConstructor ? *getTrailingObjects() - : InheritedConstructor(); + return isInheritingConstructor() ? + *getTrailingObjects() : InheritedConstructor(); } CXXConstructorDecl *getCanonicalDecl() override { @@ -2765,7 +2764,7 @@ SourceLocation EndLocation) : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, EndLocation) { - IsExplicitSpecified = isExplicitSpecified; + setExplicitSpecified(isExplicitSpecified); } void anchor() override; @@ -2783,9 +2782,6 @@ SourceLocation EndLocation); static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// Whether this function is marked as explicit explicitly. - bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// Whether this function is explicit. bool isExplicit() const { return getCanonicalDecl()->isExplicitSpecified(); Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -2609,6 +2609,38 @@ // FunctionDecl Implementation //===----------------------------------------------------------------------===// +FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, + TypeSourceInfo *TInfo, StorageClass S, + bool isInlineSpecified, bool isConstexprSpecified) + : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, + StartLoc), + DeclContext(DK), redeclarable_base(C), ODRHash(0), + EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) { + setStorageClass(S); + setInlineSpecified(isInlineSpecified); + setExplicitSpecified(false); + setVirtualAsWritten(false); + setPure(false); + setHasInheritedPrototype(false); + setHasWrittenPrototype(true); + setDeletedAsWritten(false); + setTrivial(false); + setTrivialForCall(false); + setDefaulted(false); + setExplicitlyDefaulted(false); + setHasImplicitReturnZero(false); + setLateTemplateParsed(false); + setConstexpr(isConstexprSpecified); + setInstantiationIsPending(false); + setUsesSEHTry(false); + setHasSkippedBody(false); + setWillHaveBody(false); + setIsMultiVersion(false); + setHasODRHash(false); +} + void FunctionDecl::getNameForDiagnostic( raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const { NamedDecl::getNameForDiagnostic(OS, Policy, Qualified); @@ -2676,7 +2708,7 @@ } void FunctionDecl::setPure(bool P) { - IsPure = P; + FunctionDeclBits.IsPure = P; if (P) if (auto *Parent = dyn_cast(getDeclContext())) Parent->markedVirtualFunctionPure(); @@ -2892,8 +2924,8 @@ FunTmpl->setPreviousDecl(PrevFunTmpl); } - if (PrevDecl && PrevDecl->IsInline) - IsInline = true; + if (PrevDecl && PrevDecl->isInlined()) + setImplicitlyInline(true); } FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); } @@ -3664,23 +3696,23 @@ } unsigned FunctionDecl::getODRHash() const { - assert(HasODRHash); + assert(hasODRHash()); return ODRHash; } unsigned FunctionDecl::getODRHash() { - if (HasODRHash) + if (hasODRHash()) return ODRHash; if (auto *FT = getInstantiatedFromMemberFunction()) { - HasODRHash = true; + setHasODRHash(true); ODRHash = FT->getODRHash(); return ODRHash; } class ODRHash Hash; Hash.AddFunctionDecl(this); - HasODRHash = true; + setHasODRHash(true); ODRHash = Hash.CalculateHash(); return ODRHash; } @@ -4350,7 +4382,7 @@ FunctionDecl *New = new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo, SC, isInlineSpecified, isConstexprSpecified); - New->HasWrittenPrototype = hasWrittenPrototype; + New->setHasWrittenPrototype(hasWrittenPrototype); return New; } Index: lib/AST/DeclCXX.cpp =================================================================== --- lib/AST/DeclCXX.cpp +++ lib/AST/DeclCXX.cpp @@ -2246,6 +2246,21 @@ return SourceRange(getSourceLocation(), getRParenLoc()); } +CXXConstructorDecl::CXXConstructorDecl( + ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, + bool isConstexpr, InheritedConstructor Inherited) + : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, + SC_None, isInline, isConstexpr, SourceLocation()) { + setNumCtorInitializers(0); + setInheritingConstructor(static_cast(Inherited)); + setImplicit(isImplicitlyDeclared); + if (Inherited) + *getTrailingObjects() = Inherited; + setExplicitSpecified(isExplicitSpecified); +} + void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, @@ -2255,7 +2270,7 @@ auto *Result = new (C, ID, Extra) CXXConstructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, false, InheritedConstructor()); - Result->IsInheritingConstructor = Inherited; + Result->setInheritingConstructor(Inherited); return Result; } Index: lib/Serialization/ASTReaderDecl.cpp =================================================================== --- lib/Serialization/ASTReaderDecl.cpp +++ lib/Serialization/ASTReaderDecl.cpp @@ -506,8 +506,8 @@ if (Record.readInt()) Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile; if (auto *CD = dyn_cast(FD)) { - CD->NumCtorInitializers = Record.readInt(); - if (CD->NumCtorInitializers) + CD->setNumCtorInitializers(Record.readInt()); + if (CD->getNumCtorInitializers()) CD->CtorInitializers = ReadGlobalOffset(); } // Store the offset of the body so we can lazily load it later. @@ -855,30 +855,31 @@ // FunctionDecl's body is handled last at ASTDeclReader::Visit, // after everything else is read. - FD->SClass = (StorageClass)Record.readInt(); - FD->IsInline = Record.readInt(); - FD->IsInlineSpecified = Record.readInt(); - FD->IsExplicitSpecified = Record.readInt(); - FD->IsVirtualAsWritten = Record.readInt(); - FD->IsPure = Record.readInt(); - FD->HasInheritedPrototype = Record.readInt(); - FD->HasWrittenPrototype = Record.readInt(); - FD->IsDeleted = Record.readInt(); - FD->IsTrivial = Record.readInt(); - FD->IsTrivialForCall = Record.readInt(); - FD->IsDefaulted = Record.readInt(); - FD->IsExplicitlyDefaulted = Record.readInt(); - FD->HasImplicitReturnZero = Record.readInt(); - FD->IsConstexpr = Record.readInt(); - FD->UsesSEHTry = Record.readInt(); - FD->HasSkippedBody = Record.readInt(); - FD->IsMultiVersion = Record.readInt(); - FD->IsLateTemplateParsed = Record.readInt(); - FD->setCachedLinkage(Linkage(Record.readInt())); + FD->setStorageClass(static_cast(Record.readInt())); + FD->setInlineSpecified(Record.readInt()); + FD->setImplicitlyInline(Record.readInt()); + FD->setExplicitSpecified(Record.readInt()); + FD->setVirtualAsWritten(Record.readInt()); + FD->setPure(Record.readInt()); + FD->setHasInheritedPrototype(Record.readInt()); + FD->setHasWrittenPrototype(Record.readInt()); + FD->setDeletedAsWritten(Record.readInt()); + FD->setTrivial(Record.readInt()); + FD->setTrivialForCall(Record.readInt()); + FD->setDefaulted(Record.readInt()); + FD->setExplicitlyDefaulted(Record.readInt()); + FD->setHasImplicitReturnZero(Record.readInt()); + FD->setConstexpr(Record.readInt()); + FD->setUsesSEHTry(Record.readInt()); + FD->setHasSkippedBody(Record.readInt()); + FD->setIsMultiVersion(Record.readInt()); + FD->setLateTemplateParsed(Record.readInt()); + + FD->setCachedLinkage(static_cast(Record.readInt())); FD->EndRangeLoc = ReadSourceLocation(); FD->ODRHash = Record.readInt(); - FD->HasODRHash = true; + FD->setHasODRHash(true); switch ((FunctionDecl::TemplatedKind)Record.readInt()) { case FunctionDecl::TK_NonTemplate: @@ -1958,7 +1959,7 @@ void ASTDeclReader::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { VisitFunctionDecl(D); - D->IsCopyDeductionCandidate = Record.readInt(); + D->setIsCopyDeductionCandidate(Record.readInt()); } void ASTDeclReader::VisitCXXMethodDecl(CXXMethodDecl *D) { @@ -3380,7 +3381,7 @@ // If the previous declaration is an inline function declaration, then this // declaration is too. - if (PrevFD->IsInline != FD->IsInline) { + if (PrevFD->isInlined() != FD->isInlined()) { // FIXME: [dcl.fct.spec]p4: // If a function with external linkage is declared inline in one // translation unit, it shall be declared inline in all translation @@ -3396,7 +3397,7 @@ // module C instantiates the definition of X::f // // If module B and C are merged, we do not have a violation of this rule. - FD->IsInline = true; + FD->setImplicitlyInline(true); } // If we need to propagate an exception specification along the redecl Index: lib/Serialization/ASTWriterDecl.cpp =================================================================== --- lib/Serialization/ASTWriterDecl.cpp +++ lib/Serialization/ASTWriterDecl.cpp @@ -529,26 +529,25 @@ // FunctionDecl's body is handled last at ASTWriterDecl::Visit, // after everything else is written. - - Record.push_back((int)D->SClass); // FIXME: stable encoding - Record.push_back(D->IsInline); - Record.push_back(D->IsInlineSpecified); - Record.push_back(D->IsExplicitSpecified); - Record.push_back(D->IsVirtualAsWritten); - Record.push_back(D->IsPure); - Record.push_back(D->HasInheritedPrototype); - Record.push_back(D->HasWrittenPrototype); - Record.push_back(D->IsDeleted); - Record.push_back(D->IsTrivial); - Record.push_back(D->IsTrivialForCall); - Record.push_back(D->IsDefaulted); - Record.push_back(D->IsExplicitlyDefaulted); - Record.push_back(D->HasImplicitReturnZero); - Record.push_back(D->IsConstexpr); - Record.push_back(D->UsesSEHTry); - Record.push_back(D->HasSkippedBody); - Record.push_back(D->IsMultiVersion); - Record.push_back(D->IsLateTemplateParsed); + Record.push_back(static_cast(D->getStorageClass())); // FIXME: stable encoding + Record.push_back(D->isInlineSpecified()); + Record.push_back(D->isInlined()); + Record.push_back(D->isExplicitSpecified()); + Record.push_back(D->isVirtualAsWritten()); + Record.push_back(D->isPure()); + Record.push_back(D->hasInheritedPrototype()); + Record.push_back(D->hasWrittenPrototype()); + Record.push_back(D->isDeletedBit()); + Record.push_back(D->isTrivial()); + Record.push_back(D->isTrivialForCall()); + Record.push_back(D->isDefaulted()); + Record.push_back(D->isExplicitlyDefaulted()); + Record.push_back(D->hasImplicitReturnZero()); + Record.push_back(D->isConstexpr()); + Record.push_back(D->usesSEHTry()); + Record.push_back(D->hasSkippedBody()); + Record.push_back(D->isMultiVersion()); + Record.push_back(D->isLateTemplateParsed()); Record.push_back(D->getLinkageInternal()); Record.AddSourceLocation(D->getLocEnd()); @@ -628,7 +627,7 @@ void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) { VisitFunctionDecl(D); - Record.push_back(D->IsCopyDeductionCandidate); + Record.push_back(D->isCopyDeductionCandidate()); Code = serialization::DECL_CXX_DEDUCTION_GUIDE; }