/// Controls when vtordisps will be emitted if this record is used as a
/// virtual base.
- MSVtorDispAttr::Mode getMSVtorDispMode() const;
+ MSVtorDispMode getMSVtorDispMode() const;
/// Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
let SemaHandler = 0;
let AdditionalMembers = [{
- enum Mode {
- Never,
- ForVBaseOverride,
- ForVFTable
- };
-
- Mode getVtorDispMode() const { return Mode(vdm); }
+ MSVtorDispMode getVtorDispMode() const { return MSVtorDispMode(vdm); }
}];
let Documentation = [Undocumented];
}
BENIGN_LANGOPT(NumLargeByValueCopy, 32, 0,
"if non-zero, warn about parameter or return Warn if parameter/return value is larger in bytes than this setting. 0 is no check.")
VALUE_LANGOPT(MSCompatibilityVersion, 32, 0, "Microsoft Visual C/C++ Version")
-VALUE_LANGOPT(VtorDispMode, 2, 1, "How many vtordisps to insert")
+ENUM_LANGOPT(VtorDispMode, MSVtorDispMode, 2, MSVtorDispMode::ForVBaseOverride,
+ "How many vtordisps to insert")
LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
#include "clang/Basic/LangOptions.def"
};
+/// In the Microsoft ABI, this controls the placement of virtual displacement
+/// members used to implement virtual inheritance.
+enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
+
/// Keeps track of the various options that can be
/// enabled, which controls the dialect of C or C++ that is accepted.
class LangOptions : public LangOptionsBase {
PPTMK_FullGeneralityVirtualInheritance
};
+ using MSVtorDispMode = clang::MSVtorDispMode;
+
enum DefaultCallingConvention {
DCC_None,
DCC_CDecl,
/// structors
/// 2: Always insert vtordisps to support RTTI on partially constructed
/// objects
- PragmaStack<MSVtorDispAttr::Mode> VtorDispStack;
+ PragmaStack<MSVtorDispMode> VtorDispStack;
// #pragma pack.
// Sentinel to represent when the stack is set to mac68k alignment.
static const unsigned kMac68kAlignmentSentinel = ~0U;
/// Called on well formed \#pragma vtordisp().
void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
SourceLocation PragmaLoc,
- MSVtorDispAttr::Mode Value);
+ MSVtorDispMode Value);
enum PragmaSectionKind {
PSK_DataSeg,
return IA->getSemanticSpelling();
}
-MSVtorDispAttr::Mode CXXRecordDecl::getMSVtorDispMode() const {
+MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const {
if (MSVtorDispAttr *VDA = getAttr<MSVtorDispAttr>())
return VDA->getVtorDispMode();
- return MSVtorDispAttr::Mode(getASTContext().getLangOpts().VtorDispMode);
+ return getASTContext().getLangOpts().getVtorDispMode();
}
// Returns the number of pointer and integer slots used to represent a member
const CXXRecordDecl *RD) const {
// /vd2 or #pragma vtordisp(2): Always use vtordisps for virtual bases with
// vftables.
- if (RD->getMSVtorDispMode() == MSVtorDispAttr::ForVFTable) {
+ if (RD->getMSVtorDispMode() == MSVtorDispMode::ForVFTable) {
for (const CXXBaseSpecifier &Base : RD->vbases()) {
const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
// * A user declared constructor or destructor aren't declared.
// * #pragma vtordisp(0) or the /vd0 flag are in use.
if ((!RD->hasUserDeclaredConstructor() && !RD->hasUserDeclaredDestructor()) ||
- RD->getMSVtorDispMode() == MSVtorDispAttr::Never)
+ RD->getMSVtorDispMode() == MSVtorDispMode::Never)
return;
// /vd1 or #pragma vtordisp(1): Try to guess based on whether we think it's
// possible for a partially constructed object with virtual base overrides to
// escape a non-trivial constructor.
- assert(RD->getMSVtorDispMode() == MSVtorDispAttr::ForVBaseOverride);
+ assert(RD->getMSVtorDispMode() == MSVtorDispMode::ForVBaseOverride);
// Compute a set of base classes which define methods we override. A virtual
// base in this set will require a vtordisp. A virtual base that transitively
// contains one of these bases as a non-virtual base will also require a
OPT_fno_dollars_in_identifiers,
Opts.DollarIdents);
Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings);
- Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
+ Opts.setVtorDispMode(
+ MSVtorDispMode(getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags)));
Opts.Borland = Args.hasArg(OPT_fborland_extensions);
Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
Opts.ConstStrings = Args.hasFlag(OPT_fconst_strings, OPT_fno_const_strings,
uintptr_t Value = reinterpret_cast<uintptr_t>(Tok.getAnnotationValue());
Sema::PragmaMsStackAction Action =
static_cast<Sema::PragmaMsStackAction>((Value >> 16) & 0xFFFF);
- MSVtorDispAttr::Mode Mode = MSVtorDispAttr::Mode(Value & 0xFFFF);
+ MSVtorDispMode Mode = MSVtorDispMode(Value & 0xFFFF);
SourceLocation PragmaLoc = ConsumeAnnotationToken();
Actions.ActOnPragmaMSVtorDisp(Action, PragmaLoc, Mode);
}
OriginalLexicalContext(nullptr), MSStructPragmaOn(false),
MSPointerToMemberRepresentationMethod(
LangOpts.getMSPointerToMemberRepresentationMethod()),
- VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)), PackStack(0),
+ VtorDispStack(LangOpts.getVtorDispMode()), PackStack(0),
DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
CodeSegStack(nullptr), CurInitSeg(nullptr), VisContext(nullptr),
PragmaAttributeCurrentTargetDecl(nullptr),
// FIXME: We should merge AddAlignmentAttributesForRecord with
// AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
// all active pragmas and applies them as attributes to class definitions.
- if (VtorDispStack.CurrentValue != getLangOpts().VtorDispMode)
- RD->addAttr(
- MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue));
+ if (VtorDispStack.CurrentValue != getLangOpts().getVtorDispMode())
+ RD->addAttr(MSVtorDispAttr::CreateImplicit(
+ Context, unsigned(VtorDispStack.CurrentValue)));
}
template <typename Attribute>
void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
SourceLocation PragmaLoc,
- MSVtorDispAttr::Mode Mode) {
+ MSVtorDispMode Mode) {
if (Action & PSK_Pop && VtorDispStack.Stack.empty())
Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
<< "stack empty";