Hi hansw, aaron.ballman, rnk, rsmith,
These flags control the inheritance model initially used by the
translation unit.
http://llvm-reviews.chandlerc.com/D2741
Files:
include/clang/Basic/LangOptions.def
include/clang/Basic/LangOptions.h
include/clang/Driver/CLCompatOptions.td
include/clang/Driver/Options.td
include/clang/Sema/Sema.h
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Parse/ParsePragma.cpp
lib/Sema/Sema.cpp
lib/Sema/SemaAttr.cpp
lib/Sema/SemaType.cpp
test/SemaCXX/member-pointer-ms.cpp
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -113,6 +113,7 @@
BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control")
LANGOPT(CharIsSigned , 1, 1, "signed char")
LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t")
+ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method")
LANGOPT(ShortEnums , 1, 0, "short enum types")
Index: include/clang/Basic/LangOptions.h
===================================================================
--- include/clang/Basic/LangOptions.h
+++ include/clang/Basic/LangOptions.h
@@ -66,6 +66,13 @@
SOB_Trapping // -ftrapv
};
+ enum PragmaMSPointersToMembersKind {
+ PPTMK_BestCase,
+ PPTMK_FullGeneralitySingleInheritance,
+ PPTMK_FullGeneralityMultipleInheritance,
+ PPTMK_FullGeneralityVirtualInheritance,
+ };
+
enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
public:
Index: include/clang/Driver/CLCompatOptions.td
===================================================================
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -96,6 +96,16 @@
Alias<show_includes>;
def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">,
MetaVarName<"<macro>">, Alias<U>;
+def _SLASH_vmb : CLFlag<"vmb">,
+ HelpText<"Use a best case representation method for member pointers">;
+def _SLASH_vmg : CLFlag<"vmg">,
+ HelpText<"Use a most general representation for member pointers">;
+def _SLASH_vms : CLFlag<"vms">,
+ HelpText<"Set the default most general representation to single inheritance">;
+def _SLASH_vmm : CLFlag<"vmm">,
+ HelpText<"Set the default most general representation to multiple inheritance">;
+def _SLASH_vmv : CLFlag<"vmv">,
+ HelpText<"Set the default most general representation to virtual inheritance">;
def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>;
def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>;
def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>;
@@ -168,7 +178,6 @@
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
def _SLASH_sdl : CLIgnoredFlag<"sdl">;
def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">;
-def _SLASH_vmg : CLIgnoredFlag<"vmg">;
def _SLASH_w : CLIgnoredJoined<"w">;
def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">;
def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">;
@@ -233,10 +242,6 @@
def _SLASH_u : CLFlag<"u">;
def _SLASH_V : CLFlag<"V">;
def _SLASH_vd : CLJoined<"vd">;
-def _SLASH_vmb : CLFlag<"vmb">;
-def _SLASH_vmm : CLFlag<"vmm">;
-def _SLASH_vms : CLFlag<"vms">;
-def _SLASH_vmv : CLFlag<"vmv">;
def _SLASH_volatile : CLFlag<"volatile">;
def _SLASH_WL : CLFlag<"WL">;
def _SLASH_Wp64 : CLFlag<"Wp64">;
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -571,6 +571,7 @@
def fdelayed_template_parsing : Flag<["-"], "fdelayed-template-parsing">, Group<f_Group>,
HelpText<"Parse templated function definitions at the end of the "
"translation unit">, Flags<[CC1Option]>;
+def fms_memptr_rep_EQ : Joined<["-"], "fms-memptr-rep=">, Group<f_Group>, Flags<[CC1Option]>;
def fmodules_cache_path : Joined<["-"], "fmodules-cache-path=">, Group<i_Group>,
Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
HelpText<"Specify the module cache path">;
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -262,15 +262,9 @@
bool MSStructPragmaOn; // True when \#pragma ms_struct on
- enum PragmaMSPointersToMembersKind {
- PPTMK_BestCase,
- PPTMK_FullGeneralitySingleInheritance,
- PPTMK_FullGeneralityMultipleInheritance,
- PPTMK_FullGeneralityVirtualInheritance,
- };
-
/// \brief Controls member pointer representation format under the MS ABI.
- PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod;
+ LangOptions::PragmaMSPointersToMembersKind
+ MSPointerToMemberRepresentationMethod;
/// \brief Source location for newly created implicit MSInheritanceAttrs
SourceLocation ImplicitMSInheritanceAttrLoc;
@@ -6986,8 +6980,9 @@
/// ActOnPragmaMSPointersToMembers - called on well formed \#pragma
/// pointers_to_members(representation method[, general purpose
/// representation]).
- void ActOnPragmaMSPointersToMembers(PragmaMSPointersToMembersKind Kind,
- SourceLocation PragmaLoc);
+ void ActOnPragmaMSPointersToMembers(
+ LangOptions::PragmaMSPointersToMembersKind Kind,
+ SourceLocation PragmaLoc);
/// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch
void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value);
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -22,6 +22,7 @@
#include "clang/Driver/ToolChain.h"
#include "clang/Driver/Util.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
@@ -36,6 +37,8 @@
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <functional>
#include <sys/stat.h>
using namespace clang::driver;
@@ -4017,6 +4020,40 @@
if (Arg *A = Args.getLastArg(options::OPT_show_includes))
A->render(Args, CmdArgs);
+ const Driver &D = getToolChain().getDriver();
+ bool HasMostGeneralArg = Args.getLastArg(options::OPT__SLASH_vmg);
+ bool HasBestCaseArg = Args.getLastArg(options::OPT__SLASH_vmb);
+ if (HasMostGeneralArg && HasBestCaseArg)
+ D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+ << "-vmg" << "-vmb";
+
+ unsigned MostGeneralRepresentation = 0;
+ if (HasMostGeneralArg) {
+ MostGeneralRepresentation = options::OPT__SLASH_vmv;
+ Arg *InheritanceModelArgs[] = { Args.getLastArg(options::OPT__SLASH_vms),
+ Args.getLastArg(options::OPT__SLASH_vmm),
+ Args.getLastArg(options::OPT__SLASH_vmv) };
+ std::sort(InheritanceModelArgs, llvm::array_endof(InheritanceModelArgs),
+ std::greater<Arg *>());
+
+ if (InheritanceModelArgs[0] && InheritanceModelArgs[1])
+ D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+ << InheritanceModelArgs[0]->getAsString(Args)
+ << InheritanceModelArgs[1]->getAsString(Args);
+
+ if (InheritanceModelArgs[0])
+ MostGeneralRepresentation = InheritanceModelArgs[0]->getOption().getID();
+
+ if (MostGeneralRepresentation == options::OPT__SLASH_vms)
+ CmdArgs.push_back("-fms-memptr-rep=single");
+ else if (MostGeneralRepresentation == options::OPT__SLASH_vmm)
+ CmdArgs.push_back("-fms-memptr-rep=multiple");
+ else if (MostGeneralRepresentation == options::OPT__SLASH_vmv)
+ CmdArgs.push_back("-fms-memptr-rep=virtual");
+ else
+ llvm_unreachable("impossible representation");
+ }
+
if (!Args.hasArg(options::OPT_fdiagnostics_format_EQ)) {
CmdArgs.push_back("-fdiagnostics-format");
if (Args.hasArg(options::OPT__SLASH_fallback))
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -1402,6 +1402,24 @@
}
}
+ if (Arg *A = Args.getLastArg(OPT_fms_memptr_rep_EQ)) {
+ LangOptions::PragmaMSPointersToMembersKind InheritanceModel =
+ llvm::StringSwitch<LangOptions::PragmaMSPointersToMembersKind>(
+ A->getValue())
+ .Case("single",
+ LangOptions::PPTMK_FullGeneralitySingleInheritance)
+ .Case("multiple",
+ LangOptions::PPTMK_FullGeneralityMultipleInheritance)
+ .Case("virtual",
+ LangOptions::PPTMK_FullGeneralityVirtualInheritance)
+ .Default(LangOptions::PPTMK_BestCase);
+ if (InheritanceModel == LangOptions::PPTMK_BestCase)
+ Diags.Report(diag::err_drv_invalid_value)
+ << "-fms-memptr-rep=" << A->getValue();
+
+ Opts.setMSPointerToMemberRepresentationMethod(InheritanceModel);
+ }
+
// Check if -fopenmp is specified.
Opts.OpenMP = Args.hasArg(OPT_fopenmp);
Index: lib/Parse/ParsePragma.cpp
===================================================================
--- lib/Parse/ParsePragma.cpp
+++ lib/Parse/ParsePragma.cpp
@@ -182,8 +182,8 @@
void Parser::HandlePragmaMSPointersToMembers() {
assert(Tok.is(tok::annot_pragma_ms_pointers_to_members));
- Sema::PragmaMSPointersToMembersKind RepresentationMethod =
- static_cast<Sema::PragmaMSPointersToMembersKind>(
+ LangOptions::PragmaMSPointersToMembersKind RepresentationMethod =
+ static_cast<LangOptions::PragmaMSPointersToMembersKind>(
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
SourceLocation PragmaLoc = ConsumeToken(); // The annotation token.
Actions.ActOnPragmaMSPointersToMembers(RepresentationMethod, PragmaLoc);
@@ -834,9 +834,9 @@
}
PP.Lex(Tok);
- Sema::PragmaMSPointersToMembersKind RepresentationMethod;
+ LangOptions::PragmaMSPointersToMembersKind RepresentationMethod;
if (Arg->isStr("best_case")) {
- RepresentationMethod = Sema::PPTMK_BestCase;
+ RepresentationMethod = LangOptions::PPTMK_BestCase;
} else {
if (Arg->isStr("full_generality")) {
if (Tok.is(tok::comma)) {
@@ -854,7 +854,7 @@
// #pragma pointers_to_members(full_generality) implicitly specifies
// virtual_inheritance.
Arg = 0;
- RepresentationMethod = Sema::PPTMK_FullGeneralityVirtualInheritance;
+ RepresentationMethod = LangOptions::PPTMK_FullGeneralityVirtualInheritance;
} else {
PP.Diag(Tok.getLocation(), diag::err_expected_punc)
<< "full_generality";
@@ -864,11 +864,14 @@
if (Arg) {
if (Arg->isStr("single_inheritance")) {
- RepresentationMethod = Sema::PPTMK_FullGeneralitySingleInheritance;
+ RepresentationMethod =
+ LangOptions::PPTMK_FullGeneralitySingleInheritance;
} else if (Arg->isStr("multiple_inheritance")) {
- RepresentationMethod = Sema::PPTMK_FullGeneralityMultipleInheritance;
+ RepresentationMethod =
+ LangOptions::PPTMK_FullGeneralityMultipleInheritance;
} else if (Arg->isStr("virtual_inheritance")) {
- RepresentationMethod = Sema::PPTMK_FullGeneralityVirtualInheritance;
+ RepresentationMethod =
+ LangOptions::PPTMK_FullGeneralityVirtualInheritance;
} else {
PP.Diag(Tok.getLocation(),
diag::err_pragma_pointers_to_members_unknown_kind)
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -76,7 +76,9 @@
CollectStats(false), CodeCompleter(CodeCompleter),
CurContext(0), OriginalLexicalContext(0),
PackContext(0), MSStructPragmaOn(false),
- MSPointerToMemberRepresentationMethod(PPTMK_BestCase), VisContext(0),
+ MSPointerToMemberRepresentationMethod(
+ pp.getLangOpts().getMSPointerToMemberRepresentationMethod()),
+ VisContext(0),
IsBuildingRecoveryCallExpr(false),
ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
Index: lib/Sema/SemaAttr.cpp
===================================================================
--- lib/Sema/SemaAttr.cpp
+++ lib/Sema/SemaAttr.cpp
@@ -288,7 +288,7 @@
}
void Sema::ActOnPragmaMSPointersToMembers(
- PragmaMSPointersToMembersKind RepresentationMethod,
+ LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
SourceLocation PragmaLoc) {
MSPointerToMemberRepresentationMethod = RepresentationMethod;
ImplicitMSInheritanceAttrLoc = PragmaLoc;
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -5087,26 +5087,26 @@
MSInheritanceAttr::Spelling InheritanceModel;
switch (MSPointerToMemberRepresentationMethod) {
- case PPTMK_BestCase:
+ case LangOptions::PPTMK_BestCase:
InheritanceModel = RD->calculateInheritanceModel();
break;
- case PPTMK_FullGeneralitySingleInheritance:
+ case LangOptions::PPTMK_FullGeneralitySingleInheritance:
InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance;
break;
- case PPTMK_FullGeneralityMultipleInheritance:
+ case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
InheritanceModel =
MSInheritanceAttr::Keyword_multiple_inheritance;
break;
- case PPTMK_FullGeneralityVirtualInheritance:
+ case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
InheritanceModel =
MSInheritanceAttr::Keyword_unspecified_inheritance;
break;
}
RD->addAttr(MSInheritanceAttr::CreateImplicit(
getASTContext(), InheritanceModel,
/*BestCase=*/MSPointerToMemberRepresentationMethod ==
- PPTMK_BestCase,
+ LangOptions::PPTMK_BestCase,
ImplicitMSInheritanceAttrLoc.isValid()
? ImplicitMSInheritanceAttrLoc
: RD->getSourceRange()));
Index: test/SemaCXX/member-pointer-ms.cpp
===================================================================
--- test/SemaCXX/member-pointer-ms.cpp
+++ test/SemaCXX/member-pointer-ms.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify %s
-// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=i386-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMB %s
+// RUN: %clang_cc1 -std=c++11 -fms-compatibility -fsyntax-only -triple=x86_64-pc-win32 -verify -DVMV -fms-memptr-rep=virtual %s
//
// This file should also give no diagnostics when run through cl.exe from MSVS
// 2012, which supports C++11 and static_assert. It should pass for both 64-bit
@@ -18,6 +19,7 @@
int f;
};
+#ifdef VMB
enum {
kSingleDataAlign = 1 * sizeof(int),
kSingleFunctionAlign = 1 * sizeof(void *),
@@ -43,11 +45,47 @@
kUnspecifiedDataSize = 3 * sizeof(int),
kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
};
+#elif VMV
+enum {
+ // Everything with more than 1 field is 8 byte aligned, except virtual data
+ // member pointers on x64 (ugh).
+#ifdef _M_X64
+ kVirtualDataAlign = 4,
+#else
+ kVirtualDataAlign = 8,
+#endif
+ kMultipleDataAlign = kVirtualDataAlign,
+ kSingleDataAlign = kVirtualDataAlign,
+
+ kUnspecifiedFunctionAlign = 8,
+ kVirtualFunctionAlign = kUnspecifiedFunctionAlign,
+ kMultipleFunctionAlign = kUnspecifiedFunctionAlign,
+ kSingleFunctionAlign = kUnspecifiedFunctionAlign,
+
+ kUnspecifiedDataSize = 3 * sizeof(int),
+ kVirtualDataSize = kUnspecifiedDataSize,
+ kMultipleDataSize = kUnspecifiedDataSize,
+ kSingleDataSize = kUnspecifiedDataSize,
+
+ kUnspecifiedFunctionSize = 2 * sizeof(int) + 2 * sizeof(void *),
+ kVirtualFunctionSize = kUnspecifiedFunctionSize,
+ kMultipleFunctionSize = kUnspecifiedFunctionSize,
+ kSingleFunctionSize = kUnspecifiedFunctionSize,
+};
+#else
+#error "test doesn't yet support this mode!"
+#endif
// incomplete types
+#ifdef VMB
class __single_inheritance IncSingle;
class __multiple_inheritance IncMultiple;
class __virtual_inheritance IncVirtual;
+#else
+class IncSingle;
+class IncMultiple;
+class IncVirtual;
+#endif
static_assert(sizeof(int IncSingle::*) == kSingleDataSize, "");
static_assert(sizeof(int IncMultiple::*) == kMultipleDataSize, "");
static_assert(sizeof(int IncVirtual::*) == kVirtualDataSize, "");
@@ -83,9 +121,15 @@
// Test both declared and defined templates.
template <typename T> class X;
+#ifdef VMB
template <> class __single_inheritance X<IncSingle>;
template <> class __multiple_inheritance X<IncMultiple>;
template <> class __virtual_inheritance X<IncVirtual>;
+#else
+template <> class X<IncSingle>;
+template <> class X<IncMultiple>;
+template <> class X<IncVirtual>;
+#endif
// Don't declare X<IncUnspecified>.
static_assert(sizeof(int X<IncSingle>::*) == kSingleDataSize, "");
static_assert(sizeof(int X<IncMultiple>::*) == kMultipleDataSize, "");
@@ -183,8 +227,10 @@
void (T::*func_ptr)();
};
+#ifdef VMB
int Virtual::*CastTest = reinterpret_cast<int Virtual::*>(&AA::x);
// expected-error@-1 {{cannot reinterpret_cast from member pointer type}}
+#endif
namespace ErrorTest {
template <typename T, typename U> struct __single_inheritance A;
@@ -202,7 +248,7 @@
struct __virtual_inheritance D;
struct D : virtual B {};
}
-
+#ifdef VMB
#pragma pointers_to_members(full_generality, multiple_inheritance)
struct TrulySingleInheritance;
static_assert(sizeof(int TrulySingleInheritance::*) == kMultipleDataSize, "");
@@ -225,3 +271,4 @@
static_assert(sizeof(int SingleInheritanceAsVirtualBeforePragma::*) == 12, "");
#pragma pointers_to_members(single) // expected-error{{unexpected 'single'}}
+#endif
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits