unsigned SClass : 2;
unsigned IsInline : 1;
unsigned IsInlineSpecified : 1;
+ unsigned IsExplicitSpecified : 1;
unsigned IsVirtualAsWritten : 1;
unsigned IsPure : 1;
unsigned HasInheritedPrototype : 1;
StartLoc),
DeclContext(DK), redeclarable_base(C), ParamInfo(nullptr), Body(),
SClass(S), IsInline(isInlineSpecified),
- IsInlineSpecified(isInlineSpecified), IsVirtualAsWritten(false),
- IsPure(false), HasInheritedPrototype(false), HasWrittenPrototype(true),
+ 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),
bool isVirtualAsWritten() const { return IsVirtualAsWritten; }
void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; }
+ /// Whether this function is marked as explicit explicitly.
+ bool isExplicitSpecified() const { return IsExplicitSpecified; }
+ void setExplicitSpecified() {
+ assert((getKind() == CXXConstructor || getKind() == CXXConversion ||
+ isDeductionGuide()) && "cannot be explicit");
+ IsExplicitSpecified = true;
+ }
+
+ /// Whether this function is explicit.
+ bool isExplicit() const {
+ return getFirstDecl()->isExplicitSpecified();
+ }
+
/// Whether this virtual function is pure, i.e. makes the containing class
/// abstract.
bool isPure() const { return IsPure; }
/// \{
/// \brief The arguments used to initialize the base or member.
LazyCXXCtorInitializersPtr CtorInitializers;
- unsigned NumCtorInitializers : 30;
+ unsigned NumCtorInitializers : 31;
/// \}
- /// \brief Whether this constructor declaration has the \c explicit keyword
- /// specified.
- unsigned IsExplicitSpecified : 1;
-
/// \brief Whether this constructor declaration is an implicitly-declared
/// inheriting constructor.
unsigned IsInheritingConstructor : 1;
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
CtorInitializers(nullptr), NumCtorInitializers(0),
- IsExplicitSpecified(isExplicitSpecified),
IsInheritingConstructor((bool)Inherited) {
setImplicit(isImplicitlyDeclared);
if (Inherited)
*getTrailingObjects<InheritedConstructor>() = Inherited;
+ if (isExplicitSpecified)
+ setExplicitSpecified();
}
public:
bool isConstexpr,
InheritedConstructor Inherited = InheritedConstructor());
- /// \brief Determine whether this constructor declaration has the
- /// \c explicit keyword specified.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
- /// \brief Determine whether this constructor was marked "explicit" or not.
- bool isExplicit() const {
- return cast<CXXConstructorDecl>(getFirstDecl())->isExplicitSpecified();
- }
-
/// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer **init_iterator;
/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
void anchor() override;
- /// Whether this conversion function declaration is marked
- /// "explicit", meaning that it can only be applied when the user
- /// explicitly wrote a cast. This is a C++11 feature.
- bool IsExplicitSpecified : 1;
CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicitSpecified,
- bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, EndLocation),
- IsExplicitSpecified(isExplicitSpecified) { }
+ const DeclarationNameInfo &NameInfo, QualType T,
+ TypeSourceInfo *TInfo, bool isInline,
+ bool isExplicitSpecified, bool isConstexpr,
+ SourceLocation EndLocation)
+ : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
+ SC_None, isInline, isConstexpr, EndLocation) {
+ if (isExplicitSpecified)
+ setExplicitSpecified();
+ }
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation EndLocation);
static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- /// Whether this conversion function declaration is marked
- /// "explicit", meaning that it can only be used for direct initialization
- /// (including explitly written casts). This is a C++11 feature.
- bool isExplicitSpecified() const { return IsExplicitSpecified; }
-
- /// \brief Whether this is an explicit conversion operator (C++11 and later).
- ///
- /// Explicit conversion operators are only considered for direct
- /// initialization, e.g., when the user has explicitly written a cast.
- bool isExplicit() const {
- return cast<CXXConversionDecl>(getFirstDecl())->isExplicitSpecified();
- }
-
/// \brief Returns the type that this conversion function is converting to.
QualType getConversionType() const {
return getType()->getAs<FunctionType>()->getReturnType();
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);
VisitCXXMethodDecl(D);
- Record.push_back(D->IsExplicitSpecified);
-
Code = D->isInheritingConstructor()
? serialization::DECL_CXX_INHERITED_CONSTRUCTOR
: serialization::DECL_CXX_CONSTRUCTOR;
void ASTDeclWriter::VisitCXXConversionDecl(CXXConversionDecl *D) {
VisitCXXMethodDecl(D);
- Record.push_back(D->IsExplicitSpecified);
Code = serialization::DECL_CXX_CONVERSION;
}
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); // StorageClass
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Inline
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InlineSpecified
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ExplicitSpecified
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // VirtualAsWritten
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Pure
Abv->Add(BitCodeAbbrevOp(0)); // HasInheritedProto