const Token &getCurToken() const { return Tok; }
Scope *getCurScope() const { return Actions.getCurScope(); }
- void incrementMSLocalManglingNumber() const {
- return Actions.incrementMSLocalManglingNumber();
+ void incrementMSManglingNumber() const {
+ return Actions.incrementMSManglingNumber();
}
Decl *getObjCDeclContext() const { return Actions.getObjCDeclContext(); }
Self->EnterScope(ScopeFlags);
else {
if (BeforeCompoundStmt)
- Self->incrementMSLocalManglingNumber();
+ Self->incrementMSManglingNumber();
this->Self = nullptr;
}
/// \brief Declarations with static linkage are mangled with the number of
/// scopes seen as a component.
- unsigned short MSLocalManglingNumber;
+ unsigned short MSLastManglingNumber;
+
+ unsigned short MSCurManglingNumber;
/// PrototypeDepth - This is the number of function prototype scopes
/// enclosing this scope, including this scope.
/// FnParent - If this scope has a parent scope that is a function body, this
/// pointer is non-null and points to it. This is used for label processing.
Scope *FnParent;
- Scope *MSLocalManglingParent;
+ Scope *MSLastManglingParent;
/// BreakParent/ContinueParent - This is a direct link to the innermost
/// BreakScope/ContinueScope which contains the contents of this scope
const Scope *getFnParent() const { return FnParent; }
Scope *getFnParent() { return FnParent; }
- const Scope *getMSLocalManglingParent() const {
- return MSLocalManglingParent;
+ const Scope *getMSLastManglingParent() const {
+ return MSLastManglingParent;
}
- Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
+ Scope *getMSLastManglingParent() { return MSLastManglingParent; }
/// getContinueParent - Return the closest scope that a continue statement
/// would be affected by.
DeclsInScope.erase(D);
}
- void incrementMSLocalManglingNumber() {
- if (Scope *MSLMP = getMSLocalManglingParent())
- MSLMP->MSLocalManglingNumber += 1;
+ void incrementMSManglingNumber() {
+ if (Scope *MSLMP = getMSLastManglingParent()) {
+ MSLMP->MSLastManglingNumber += 1;
+ MSCurManglingNumber += 1;
+ }
}
- void decrementMSLocalManglingNumber() {
- if (Scope *MSLMP = getMSLocalManglingParent())
- MSLMP->MSLocalManglingNumber -= 1;
+ void decrementMSManglingNumber() {
+ if (Scope *MSLMP = getMSLastManglingParent()) {
+ MSLMP->MSLastManglingNumber -= 1;
+ MSCurManglingNumber -= 1;
+ }
}
- unsigned getMSLocalManglingNumber() const {
- if (const Scope *MSLMP = getMSLocalManglingParent())
- return MSLMP->MSLocalManglingNumber;
+ unsigned getMSLastManglingNumber() const {
+ if (const Scope *MSLMP = getMSLastManglingParent())
+ return MSLMP->MSLastManglingNumber;
return 1;
}
+ unsigned getMSCurManglingNumber() const {
+ return MSCurManglingNumber;
+ }
+
/// isDeclScope - Return true if this is the scope that the specified decl is
/// declared in.
bool isDeclScope(Decl *D) {
/// template substitution or instantiation.
Scope *getCurScope() const { return CurScope; }
- void incrementMSLocalManglingNumber() const {
- return CurScope->incrementMSLocalManglingNumber();
+ void incrementMSManglingNumber() const {
+ return CurScope->incrementMSManglingNumber();
}
IdentifierInfo *getSuperIdentifier() const;
// We have incremented the mangling number for the SwitchScope and the
// InnerScope, which is one too many.
if (C99orCXX)
- getCurScope()->decrementMSLocalManglingNumber();
+ getCurScope()->decrementMSManglingNumber();
// Read the body statement.
StmtResult Body(ParseStatement(TrailingElseLoc));
// It will only be incremented if the body contains other things that would
// normally increment the mangling number (like a compound statement).
if (C99orCXXorObjC)
- getCurScope()->decrementMSLocalManglingNumber();
+ getCurScope()->decrementMSManglingNumber();
// Read the body statement.
StmtResult Body(ParseStatement(TrailingElseLoc));
FnParent = parent->FnParent;
BlockParent = parent->BlockParent;
TemplateParamParent = parent->TemplateParamParent;
- MSLocalManglingParent = parent->MSLocalManglingParent;
+ MSLastManglingParent = parent->MSLastManglingParent;
+ MSCurManglingNumber = getMSLastManglingNumber();
if ((Flags & (FnScope | ClassScope | BlockScope | TemplateParamScope |
FunctionPrototypeScope | AtCatchScope | ObjCMethodScope)) ==
0)
Depth = 0;
PrototypeDepth = 0;
PrototypeIndex = 0;
- MSLocalManglingParent = FnParent = BlockParent = nullptr;
+ MSLastManglingParent = FnParent = BlockParent = nullptr;
TemplateParamParent = nullptr;
- MSLocalManglingNumber = 1;
+ MSLastManglingNumber = 1;
+ MSCurManglingNumber = 1;
}
// If this scope is a function or contains breaks/continues, remember it.
// The MS mangler uses the number of scopes that can hold declarations as
// part of an external name.
if (Flags & (ClassScope | FnScope)) {
- MSLocalManglingNumber = getMSLocalManglingNumber();
- MSLocalManglingParent = this;
+ MSLastManglingNumber = getMSLastManglingNumber();
+ MSLastManglingParent = this;
+ MSCurManglingNumber = 1;
}
if (flags & BreakScope) BreakParent = this;
if (flags & ContinueScope) ContinueParent = this;
else if ((flags & EnumScope))
; // Don't increment for enum scopes.
else
- incrementMSLocalManglingNumber();
+ incrementMSManglingNumber();
}
DeclsInScope.clear();
OS << "Parent: (clang::Scope*)" << Parent << '\n';
OS << "Depth: " << Depth << '\n';
- OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
+ OS << "MSLastManglingNumber: " << getMSLastManglingNumber() << '\n';
+ OS << "MSCurManglingNumber: " << getMSCurManglingNumber() << '\n';
if (const DeclContext *DC = getEntity())
OS << "Entity : (clang::DeclContext*)" << DC << '\n';
if (NRVO.getInt())
- OS << "NRVO not allowed";
+ OS << "NRVO not allowed\n";
else if (NRVO.getPointer())
OS << "NRVO candidate : (clang::VarDecl*)" << NRVO.getPointer() << '\n';
}
return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg());
}
+// The MS ABI changed between VS2013 and VS2015 with regard to numbers used to
+// disambiguate entities defined in different scopes.
+// While the VS2015 ABI fixes potential miscompiles, it is also breaks
+// compatibility.
+// We will pick our mangling number depending on which version of MSVC is being
+// targeted.
+static unsigned getMSManglingNumber(const LangOptions &LO, Scope *S) {
+ return LO.isCompatibleWithMSVC(19) ? S->getMSCurManglingNumber()
+ : S->getMSLastManglingNumber();
+}
+
void Sema::handleTagNumbering(const TagDecl *Tag, Scope *TagScope) {
if (!Context.getLangOpts().CPlusPlus)
return;
MangleNumberingContext &MCtx =
Context.getManglingNumberContext(Tag->getParent());
Context.setManglingNumber(
- Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
+ Tag, MCtx.getManglingNumber(
+ Tag, getMSManglingNumber(getLangOpts(), TagScope)));
return;
}
if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(
Tag->getDeclContext(), ManglingContextDecl)) {
Context.setManglingNumber(
- Tag,
- MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber()));
+ Tag, MCtx->getManglingNumber(
+ Tag, getMSManglingNumber(getLangOpts(), TagScope)));
}
}
if (VarDecl *NewVD = dyn_cast<VarDecl>(Anon)) {
if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) {
Decl *ManglingContextDecl;
- if (MangleNumberingContext *MCtx =
- getCurrentMangleNumberContext(NewVD->getDeclContext(),
- ManglingContextDecl)) {
- Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+ if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(
+ NewVD->getDeclContext(), ManglingContextDecl)) {
+ Context.setManglingNumber(
+ NewVD, MCtx->getManglingNumber(
+ NewVD, getMSManglingNumber(getLangOpts(), S)));
Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
}
}
if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) {
Decl *ManglingContextDecl;
- if (MangleNumberingContext *MCtx =
- getCurrentMangleNumberContext(NewVD->getDeclContext(),
- ManglingContextDecl)) {
+ if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(
+ NewVD->getDeclContext(), ManglingContextDecl)) {
Context.setManglingNumber(
- NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber()));
+ NewVD, MCtx->getManglingNumber(
+ NewVD, getMSManglingNumber(getLangOpts(), S)));
Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
}
}
-// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013
// CHECK: @"\01??_7B@?1??foo@A@@QAEXH@Z@6B@" =
// CHECK: @"\01??_7D@C@?1??foo@@YAXXZ@6B@" =
-// CHECK: define {{.*}} @"\01?baz@E@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"(
+// MSVC2013: define {{.*}} @"\01?baz@E@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"(
+// MSVC2015: define {{.*}} @"\01?baz@E@?1??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"(
// Microsoft Visual C++ ABI examples.
struct A {
// CHECK-DAG: @"\01??R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ"
// Finally, we have the local which is inside of "<lambda_1>" which is inside of
// "define_lambda". Hooray.
-// CHECK-DAG: @"\01?local@?2???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA"
+// MSVC2013-DAG: @"\01?local@?2???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA"
+// MSVC2015-DAG: @"\01?local@?1???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA"
return lambda();
}
-// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015
+// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013
template <typename> int x = 0;
return LocalLambdaWithLocalType();
}
-// CHECK: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A"
+// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A"
+// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A"
+// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A"
+// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A"
// CHECK: "\01??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z"
// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?1@XZ"
auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0);