diff options
author | David Majnemer <david.majnemer@gmail.com> | 2015-03-19 21:54:30 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2015-03-19 21:54:30 +0000 |
commit | a7f8c46439ea05c6e64ba9c6f25d3261521a05d4 (patch) | |
tree | 0a90f468c7c839b9d72fe2ad8502cc0fb66cecbb /clang/lib/Sema/Scope.cpp | |
parent | 0a93e2db9c14fb7da613ecccf5a82cab8402a9e5 (diff) | |
download | bcm5719-llvm-a7f8c46439ea05c6e64ba9c6f25d3261521a05d4.tar.gz bcm5719-llvm-a7f8c46439ea05c6e64ba9c6f25d3261521a05d4.zip |
MS ABI: Implement the MSVC 2015 scheme for scope disambiguation
consider C++ that looks like:
inline int &f(bool b) {
if (b) {
static int i;
return i;
}
static int i;
return i;
}
Both 'i' variables must have distinct (and stable) names for linkage
purposes. The MSVC 2013 ABI would number the variables using a count of
the number of scopes that have been created. However, the final 'i'
returns to a scope that has already been created leading to a mangling
collision.
MSVC 2015 fixes this by giving the second 'i' the name it would have if
it were declared before the 'if'. However, this results in ABI breakage
because the mangled name, in cases where there was no ambiguity, would
now be different.
We implement the new behavior and only enable it if we are targeting the
MSVC 2015 ABI, otherwise the old behavior will be used.
This fixes PR18131.
llvm-svn: 232766
Diffstat (limited to 'clang/lib/Sema/Scope.cpp')
-rw-r--r-- | clang/lib/Sema/Scope.cpp | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/clang/lib/Sema/Scope.cpp b/clang/lib/Sema/Scope.cpp index eeb2e01781e..7c70048acfb 100644 --- a/clang/lib/Sema/Scope.cpp +++ b/clang/lib/Sema/Scope.cpp @@ -38,7 +38,8 @@ void Scope::Init(Scope *parent, unsigned flags) { 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) @@ -47,9 +48,10 @@ void Scope::Init(Scope *parent, unsigned flags) { 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. @@ -57,8 +59,9 @@ void Scope::Init(Scope *parent, unsigned flags) { // 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; @@ -78,7 +81,7 @@ void Scope::Init(Scope *parent, unsigned flags) { else if ((flags & EnumScope)) ; // Don't increment for enum scopes. else - incrementMSLocalManglingNumber(); + incrementMSManglingNumber(); } DeclsInScope.clear(); @@ -209,12 +212,13 @@ void Scope::dumpImpl(raw_ostream &OS) const { 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'; } |