r202951 - [-cxx-abi microsoft] Implement local manglings accurately
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Thu Mar 6 04:42:53 PST 2014
This broke MemorySanitizer bootstrap:
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-bootstrap/builds/2507/steps/check-clang%20msan/logs/stdio
WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x7fd3e6fb2f66 in (anonymous
namespace)::MicrosoftCXXNameMangler::mangleNumber(long)
/home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp:562
#1 0x7fd3e6fb0558 in (anonymous
namespace)::MicrosoftMangleContextImpl::mangleStaticGuardVariable(clang::VarDecl
const*, llvm::raw_ostream&)
/home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/AST/MicrosoftMangle.cpp:2257
#2 0x7fd3e4322d2f in (anonymous
namespace)::MicrosoftCXXABI::EmitGuardedInit(clang::CodeGen::CodeGenFunction&,
clang::VarDecl const&, llvm::GlobalVariable*, bool)
/home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/CodeGen/MicrosoftCXXABI.cpp:1315
#3 0x7fd3e445011a in EmitCXXGuardedInit
/home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp:226
#4 0x7fd3e445011a in
clang::CodeGen::CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function*,
clang::VarDecl const*, llvm::GlobalVariable*, bool)
/home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp:422
#5 0x7fd3e444e72f in
clang::CodeGen::CodeGenModule::EmitCXXGlobalVarDeclInitFunc(clang::VarDecl
const*, llvm::GlobalVariable*, bool)
/home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/CodeGen/CGDeclCXX.cpp:273
#6 0x7fd3e42559c2 in
clang::CodeGen::CodeGenModule::EmitGlobalVarDefinition(clang::VarDecl
const*) /home/dtoolsbot/build/sanitizer-x86_64-linux-bootstrap/build/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp:1855
...
On Wed, Mar 5, 2014 at 12:58 PM, David Majnemer
<david.majnemer at gmail.com> wrote:
> Author: majnemer
> Date: Wed Mar 5 02:57:59 2014
> New Revision: 202951
>
> URL: http://llvm.org/viewvc/llvm-project?rev=202951&view=rev
> Log:
> [-cxx-abi microsoft] Implement local manglings accurately
>
> Summary:
> The MSVC ABI appears to mangle the lexical scope into the names of
> statics. Specifically, a counter is incremented whenever a scope is
> entered where things can be declared in such a way that an ambiguity can
> arise. For example, a class scope inside of a class scope doesn't do
> anything interesting because the nested class cannot collide with
> another nested class.
>
> There are problems with this scheme:
> - It is unreliable. The counter is only incremented when a previously
> never encountered scope is entered. There are cases where this will
> cause ambiguity amongst declarations that have the same name where one
> was introduced in a deep scope while the other was introduced right
> after in the previous lexical scope.
> - It is wasteful. Statements like: {{{{{{{ static int foo = a; }}}}}}}
> will make the mangling of "foo" larger than it need be because the
> scope counter has been incremented many times.
>
> Because of these problems, and practical implementation concerns. We
> choose not to implement this scheme if the local static or local type
> isn't visible. The mangling of these declarations will look very
> similar but the numbering will make far more sense, this scheme is
> lifted from the Itanium ABI implementation.
>
> Reviewers: rsmith, doug.gregor, rnk, eli.friedman, cdavis5x
>
> Reviewed By: rnk
>
> CC: cfe-commits
>
> Differential Revision: http://llvm-reviews.chandlerc.com/D2953
>
> Modified:
> cfe/trunk/include/clang/AST/ASTContext.h
> cfe/trunk/include/clang/AST/Mangle.h
> cfe/trunk/include/clang/AST/MangleNumberingContext.h
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/include/clang/Sema/Scope.h
> cfe/trunk/lib/AST/ASTContext.cpp
> cfe/trunk/lib/AST/ItaniumCXXABI.cpp
> cfe/trunk/lib/AST/ItaniumMangle.cpp
> cfe/trunk/lib/AST/MangleNumberingContext.cpp
> cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
> cfe/trunk/lib/AST/MicrosoftMangle.cpp
> cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> cfe/trunk/lib/Parse/ParseStmt.cpp
> cfe/trunk/lib/Sema/Scope.cpp
> cfe/trunk/lib/Sema/SemaDecl.cpp
> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp
> cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Wed Mar 5 02:57:59 2014
> @@ -365,6 +365,7 @@ private:
> /// \brief Side-table of mangling numbers for declarations which rarely
> /// need them (like static local vars).
> llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
> + llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
>
> /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
> /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
> @@ -2171,6 +2172,9 @@ public:
> void setManglingNumber(const NamedDecl *ND, unsigned Number);
> unsigned getManglingNumber(const NamedDecl *ND) const;
>
> + void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
> + unsigned getStaticLocalNumber(const VarDecl *VD) const;
> +
> /// \brief Retrieve the context for computing mangling numbers in the given
> /// DeclContext.
> MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
>
> Modified: cfe/trunk/include/clang/AST/Mangle.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Mangle.h?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Mangle.h (original)
> +++ cfe/trunk/include/clang/AST/Mangle.h Wed Mar 5 02:57:59 2014
> @@ -80,6 +80,7 @@ private:
>
> llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
> llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
> + llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
>
> public:
> ManglerKind getKind() const { return Kind; }
> @@ -104,7 +105,13 @@ public:
> Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
> return Result.first->second;
> }
> -
> +
> + uint64_t getAnonymousStructId(const TagDecl *TD) {
> + std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
> + Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
> + return Result.first->second;
> + }
> +
> /// @name Mangler Entry Points
> /// @{
>
>
> Modified: cfe/trunk/include/clang/AST/MangleNumberingContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/MangleNumberingContext.h?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/MangleNumberingContext.h (original)
> +++ cfe/trunk/include/clang/AST/MangleNumberingContext.h Wed Mar 5 02:57:59 2014
> @@ -16,6 +16,7 @@
> #define LLVM_CLANG_MANGLENUMBERINGCONTEXT_H
>
> #include "clang/Basic/LLVM.h"
> +#include "clang/Sema/Scope.h"
> #include "llvm/ADT/DenseMap.h"
> #include "llvm/ADT/IntrusiveRefCntPtr.h"
>
> @@ -33,7 +34,6 @@ class VarDecl;
> class MangleNumberingContext
> : public RefCountedBase<MangleNumberingContext> {
> llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
> - llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
>
> public:
> virtual ~MangleNumberingContext() {}
> @@ -46,13 +46,16 @@ public:
> /// context.
> unsigned getManglingNumber(const BlockDecl *BD);
>
> + /// Static locals are numbered by source order.
> + unsigned getStaticLocalNumber(const VarDecl *VD);
> +
> /// \brief Retrieve the mangling number of a static local variable within
> /// this context.
> - virtual unsigned getManglingNumber(const VarDecl *VD) = 0;
> + virtual unsigned getManglingNumber(const VarDecl *VD, Scope *S) = 0;
>
> /// \brief Retrieve the mangling number of a static local variable within
> /// this context.
> - unsigned getManglingNumber(const TagDecl *TD);
> + virtual unsigned getManglingNumber(const TagDecl *TD, Scope *S) = 0;
> };
>
> } // end namespace clang
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Wed Mar 5 02:57:59 2014
> @@ -737,14 +737,18 @@ public:
> public:
> // ParseScope - Construct a new object to manage a scope in the
> // parser Self where the new Scope is created with the flags
> - // ScopeFlags, but only when ManageScope is true (the default). If
> - // ManageScope is false, this object does nothing.
> - ParseScope(Parser *Self, unsigned ScopeFlags, bool ManageScope = true)
> + // ScopeFlags, but only when we aren't about to enter a compound statement.
> + ParseScope(Parser *Self, unsigned ScopeFlags, bool EnteredScope = true,
> + bool BeforeCompoundStmt = false)
> : Self(Self) {
> - if (ManageScope)
> + if (EnteredScope && !BeforeCompoundStmt)
> Self->EnterScope(ScopeFlags);
> - else
> + else {
> + if (BeforeCompoundStmt)
> + Self->getCurScope()->incrementMSLocalManglingNumber();
> +
> this->Self = 0;
> + }
> }
>
> // Exit - Exit the scope associated with this object now, rather
>
> Modified: cfe/trunk/include/clang/Sema/Scope.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Scope.h (original)
> +++ cfe/trunk/include/clang/Sema/Scope.h Wed Mar 5 02:57:59 2014
> @@ -18,6 +18,12 @@
> #include "llvm/ADT/SmallPtrSet.h"
> #include "llvm/ADT/SmallVector.h"
>
> +namespace llvm {
> +
> +class raw_ostream;
> +
> +}
> +
> namespace clang {
>
> class Decl;
> @@ -109,6 +115,10 @@ private:
> /// interrelates with other control flow statements.
> unsigned short Flags;
>
> + /// \brief Declarations with static linkage are mangled with the number of
> + /// scopes seen as a component.
> + unsigned short MSLocalManglingNumber;
> +
> /// PrototypeDepth - This is the number of function prototype scopes
> /// enclosing this scope, including this scope.
> unsigned short PrototypeDepth;
> @@ -120,6 +130,7 @@ private:
> /// 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;
>
> /// BreakParent/ContinueParent - This is a direct link to the innermost
> /// BreakScope/ContinueScope which contains the contents of this scope
> @@ -181,6 +192,11 @@ public:
> const Scope *getFnParent() const { return FnParent; }
> Scope *getFnParent() { return FnParent; }
>
> + const Scope *getMSLocalManglingParent() const {
> + return MSLocalManglingParent;
> + }
> + Scope *getMSLocalManglingParent() { return MSLocalManglingParent; }
> +
> /// getContinueParent - Return the closest scope that a continue statement
> /// would be affected by.
> Scope *getContinueParent() {
> @@ -232,6 +248,22 @@ public:
> DeclsInScope.erase(D);
> }
>
> + void incrementMSLocalManglingNumber() {
> + if (Scope *MSLMP = getMSLocalManglingParent())
> + MSLMP->MSLocalManglingNumber += 1;
> + }
> +
> + void decrementMSLocalManglingNumber() {
> + if (Scope *MSLMP = getMSLocalManglingParent())
> + MSLMP->MSLocalManglingNumber -= 1;
> + }
> +
> + unsigned getMSLocalManglingNumber() const {
> + if (const Scope *MSLMP = getMSLocalManglingParent())
> + return MSLMP->MSLocalManglingNumber;
> + return 1;
> + }
> +
> /// isDeclScope - Return true if this is the scope that the specified decl is
> /// declared in.
> bool isDeclScope(Decl *D) {
> @@ -359,6 +391,9 @@ public:
> /// variables accordingly.
> ///
> void AddFlags(unsigned Flags);
> +
> + void dumpImpl(raw_ostream &OS) const;
> + void dump() const;
> };
>
> } // end namespace clang
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Wed Mar 5 02:57:59 2014
> @@ -8052,6 +8052,17 @@ unsigned ASTContext::getManglingNumber(c
> return I != MangleNumbers.end() ? I->second : 1;
> }
>
> +void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) {
> + if (Number > 1)
> + StaticLocalNumbers[VD] = Number;
> +}
> +
> +unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const {
> + llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I =
> + StaticLocalNumbers.find(VD);
> + return I != StaticLocalNumbers.end() ? I->second : 1;
> +}
> +
> MangleNumberingContext &
> ASTContext::getManglingNumberContext(const DeclContext *DC) {
> assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.
>
> Modified: cfe/trunk/lib/AST/ItaniumCXXABI.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumCXXABI.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumCXXABI.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumCXXABI.cpp Wed Mar 5 02:57:59 2014
> @@ -33,12 +33,17 @@ namespace {
> /// literals within a particular context.
> class ItaniumNumberingContext : public MangleNumberingContext {
> llvm::DenseMap<IdentifierInfo*, unsigned> VarManglingNumbers;
> + llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
>
> public:
> /// Variable decls are numbered by identifier.
> - virtual unsigned getManglingNumber(const VarDecl *VD) {
> + virtual unsigned getManglingNumber(const VarDecl *VD, Scope *) {
> return ++VarManglingNumbers[VD->getIdentifier()];
> }
> +
> + virtual unsigned getManglingNumber(const TagDecl *TD, Scope *) {
> + return ++TagManglingNumbers[TD->getIdentifier()];
> + }
> };
>
> class ItaniumCXXABI : public CXXABI {
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Wed Mar 5 02:57:59 2014
> @@ -101,11 +101,18 @@ static const NamedDecl *getStructor(cons
> const FunctionDecl *fn = dyn_cast_or_null<FunctionDecl>(decl);
> return (fn ? getStructor(fn) : decl);
> }
> -
> +
> +static bool isLambda(const NamedDecl *ND) {
> + const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
> + if (!Record)
> + return false;
> +
> + return Record->isLambda();
> +}
> +
> static const unsigned UnknownArity = ~0U;
>
> class ItaniumMangleContextImpl : public ItaniumMangleContext {
> - llvm::DenseMap<const TagDecl *, uint64_t> AnonStructIds;
> typedef std::pair<const DeclContext*, IdentifierInfo*> DiscriminatorKeyTy;
> llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
> llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
> @@ -115,13 +122,6 @@ public:
> DiagnosticsEngine &Diags)
> : ItaniumMangleContext(Context, Diags) {}
>
> - uint64_t getAnonymousStructId(const TagDecl *TD) {
> - std::pair<llvm::DenseMap<const TagDecl *,
> - uint64_t>::iterator, bool> Result =
> - AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
> - return Result.first->second;
> - }
> -
> /// @name Mangler Entry Points
> /// @{
>
> @@ -158,9 +158,8 @@ public:
>
> bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
> // Lambda closure types are already numbered.
> - if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND))
> - if (RD->isLambda())
> - return false;
> + if (isLambda(ND))
> + return false;
>
> // Anonymous tags are already numbered.
> if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
> @@ -538,14 +537,6 @@ isTemplate(const NamedDecl *ND, const Te
> return 0;
> }
>
> -static bool isLambda(const NamedDecl *ND) {
> - const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
> - if (!Record)
> - return false;
> -
> - return Record->isLambda();
> -}
> -
> void CXXNameMangler::mangleName(const NamedDecl *ND) {
> // <name> ::= <nested-name>
> // ::= <unscoped-name>
> @@ -1149,7 +1140,7 @@ void CXXNameMangler::mangleUnqualifiedNa
> }
>
> // Get a unique id for the anonymous struct.
> - uint64_t AnonStructId = Context.getAnonymousStructId(TD);
> + unsigned AnonStructId = Context.getAnonymousStructId(TD);
>
> // Mangle it as a source name in the form
> // [n] $_<id>
>
> Modified: cfe/trunk/lib/AST/MangleNumberingContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MangleNumberingContext.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/MangleNumberingContext.cpp (original)
> +++ cfe/trunk/lib/AST/MangleNumberingContext.cpp Wed Mar 5 02:57:59 2014
> @@ -38,6 +38,8 @@ MangleNumberingContext::getManglingNumbe
> }
>
> unsigned
> -MangleNumberingContext::getManglingNumber(const TagDecl *TD) {
> - return ++TagManglingNumbers[TD->getIdentifier()];
> +MangleNumberingContext::getStaticLocalNumber(const VarDecl *VD) {
> + // FIXME: Compute a BlockPointerType? Not obvious how.
> + const Type *Ty = 0;
> + return ++ManglingNumbers[Ty];
> }
>
> Modified: cfe/trunk/lib/AST/MicrosoftCXXABI.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftCXXABI.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftCXXABI.cpp Wed Mar 5 02:57:59 2014
> @@ -28,15 +28,13 @@ namespace {
> /// \brief Numbers things which need to correspond across multiple TUs.
> /// Typically these are things like static locals, lambdas, or blocks.
> class MicrosoftNumberingContext : public MangleNumberingContext {
> - unsigned NumStaticLocals;
> -
> public:
> - MicrosoftNumberingContext() : NumStaticLocals(0) { }
> + virtual unsigned getManglingNumber(const VarDecl *VD, Scope *S) {
> + return S->getMSLocalManglingNumber();
> + }
>
> - /// Static locals are numbered by source order.
> - virtual unsigned getManglingNumber(const VarDecl *VD) {
> - assert(VD->isStaticLocal());
> - return ++NumStaticLocals;
> + virtual unsigned getManglingNumber(const TagDecl *TD, Scope *S) {
> + return S->getMSLocalManglingNumber();
> }
> };
>
>
> Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Wed Mar 5 02:57:59 2014
> @@ -25,6 +25,7 @@
> #include "clang/Basic/ABI.h"
> #include "clang/Basic/DiagnosticOptions.h"
> #include "clang/Basic/TargetInfo.h"
> +#include "llvm/ADT/StringExtras.h"
> #include "llvm/ADT/StringMap.h"
>
> using namespace clang;
> @@ -72,10 +73,89 @@ static const FunctionDecl *getStructor(c
> return fn;
> }
>
> +static bool isLambda(const NamedDecl *ND) {
> + const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(ND);
> + if (!Record)
> + return false;
> +
> + return Record->isLambda();
> +}
> +
> +/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
> +/// Microsoft Visual C++ ABI.
> +class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
> + typedef std::pair<const DeclContext *, IdentifierInfo *> DiscriminatorKeyTy;
> + llvm::DenseMap<DiscriminatorKeyTy, unsigned> Discriminator;
> + llvm::DenseMap<const NamedDecl*, unsigned> Uniquifier;
> +
> +public:
> + MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
> + : MicrosoftMangleContext(Context, Diags) {}
> + virtual bool shouldMangleCXXName(const NamedDecl *D);
> + virtual void mangleCXXName(const NamedDecl *D, raw_ostream &Out);
> + virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
> + raw_ostream &);
> + virtual void mangleThunk(const CXXMethodDecl *MD,
> + const ThunkInfo &Thunk,
> + raw_ostream &);
> + virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
> + const ThisAdjustment &ThisAdjustment,
> + raw_ostream &);
> + virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
> + ArrayRef<const CXXRecordDecl *> BasePath,
> + raw_ostream &Out);
> + virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
> + ArrayRef<const CXXRecordDecl *> BasePath,
> + raw_ostream &Out);
> + virtual void mangleCXXRTTI(QualType T, raw_ostream &);
> + virtual void mangleCXXRTTIName(QualType T, raw_ostream &);
> + virtual void mangleTypeName(QualType T, raw_ostream &);
> + virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
> + raw_ostream &);
> + virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
> + raw_ostream &);
> + virtual void mangleReferenceTemporary(const VarDecl *, raw_ostream &);
> + virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out);
> + virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
> + virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
> + raw_ostream &Out);
> + bool getNextDiscriminator(const NamedDecl *ND, unsigned &disc) {
> + // Lambda closure types are already numbered.
> + if (isLambda(ND))
> + return false;
> +
> + const DeclContext *DC = getEffectiveDeclContext(ND);
> + if (!DC->isFunctionOrMethod())
> + return false;
> +
> + // Use the canonical number for externally visible decls.
> + if (ND->isExternallyVisible()) {
> + disc = getASTContext().getManglingNumber(ND);
> + return true;
> + }
> +
> + // Anonymous tags are already numbered.
> + if (const TagDecl *Tag = dyn_cast<TagDecl>(ND)) {
> + if (Tag->getName().empty() && !Tag->getTypedefNameForAnonDecl())
> + return false;
> + }
> +
> + // Make up a reasonable number for internal decls.
> + unsigned &discriminator = Uniquifier[ND];
> + if (!discriminator)
> + discriminator = ++Discriminator[std::make_pair(DC, ND->getIdentifier())];
> + disc = discriminator;
> + return true;
> + }
> +
> +private:
> + void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
> +};
> +
> /// MicrosoftCXXNameMangler - Manage the mangling of a single name for the
> /// Microsoft Visual C++ ABI.
> class MicrosoftCXXNameMangler {
> - MangleContext &Context;
> + MicrosoftMangleContextImpl &Context;
> raw_ostream &Out;
>
> /// The "structor" is the top-level declaration being mangled, if
> @@ -100,14 +180,14 @@ class MicrosoftCXXNameMangler {
> public:
> enum QualifierMangleMode { QMM_Drop, QMM_Mangle, QMM_Escape, QMM_Result };
>
> - MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_)
> + MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_)
> : Context(C), Out(Out_),
> Structor(0), StructorType(-1),
> UseNameBackReferences(true),
> PointersAre64Bit(C.getASTContext().getTargetInfo().getPointerWidth(0) ==
> 64) { }
>
> - MicrosoftCXXNameMangler(MangleContext &C, raw_ostream &Out_,
> + MicrosoftCXXNameMangler(MicrosoftMangleContextImpl &C, raw_ostream &Out_,
> const CXXDestructorDecl *D, CXXDtorType Type)
> : Context(C), Out(Out_),
> Structor(getStructor(D)), StructorType(Type),
> @@ -133,7 +213,7 @@ public:
> QualifierMangleMode QMM = QMM_Mangle);
> void mangleFunctionType(const FunctionType *T, const FunctionDecl *D = 0,
> bool ForceInstMethod = false);
> - void manglePostfix(const DeclContext *DC, bool NoFunction = false);
> + void mangleNestedName(const NamedDecl *ND);
>
> private:
> void disableBackReferences() { UseNameBackReferences = false; }
> @@ -152,7 +232,6 @@ private:
> void mangleTemplateInstantiationName(const TemplateDecl *TD,
> const TemplateArgumentList &TemplateArgs);
> void mangleObjCMethodName(const ObjCMethodDecl *MD);
> - void mangleLocalName(const FunctionDecl *FD);
>
> void mangleArgumentType(QualType T, SourceRange Range);
>
> @@ -179,46 +258,6 @@ private:
> const TemplateArgumentList &TemplateArgs);
> void mangleTemplateArg(const TemplateDecl *TD, const TemplateArgument &TA);
> };
> -
> -/// MicrosoftMangleContextImpl - Overrides the default MangleContext for the
> -/// Microsoft Visual C++ ABI.
> -class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
> -public:
> - MicrosoftMangleContextImpl(ASTContext &Context, DiagnosticsEngine &Diags)
> - : MicrosoftMangleContext(Context, Diags) {}
> - virtual bool shouldMangleCXXName(const NamedDecl *D);
> - virtual void mangleCXXName(const NamedDecl *D, raw_ostream &Out);
> - virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
> - raw_ostream &);
> - virtual void mangleThunk(const CXXMethodDecl *MD,
> - const ThunkInfo &Thunk,
> - raw_ostream &);
> - virtual void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type,
> - const ThisAdjustment &ThisAdjustment,
> - raw_ostream &);
> - virtual void mangleCXXVFTable(const CXXRecordDecl *Derived,
> - ArrayRef<const CXXRecordDecl *> BasePath,
> - raw_ostream &Out);
> - virtual void mangleCXXVBTable(const CXXRecordDecl *Derived,
> - ArrayRef<const CXXRecordDecl *> BasePath,
> - raw_ostream &Out);
> - virtual void mangleCXXRTTI(QualType T, raw_ostream &);
> - virtual void mangleCXXRTTIName(QualType T, raw_ostream &);
> - virtual void mangleTypeName(QualType T, raw_ostream &);
> - virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type,
> - raw_ostream &);
> - virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
> - raw_ostream &);
> - virtual void mangleReferenceTemporary(const VarDecl *, raw_ostream &);
> - virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out);
> - virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &Out);
> - virtual void mangleDynamicAtExitDestructor(const VarDecl *D,
> - raw_ostream &Out);
> -
> -private:
> - void mangleInitFiniStub(const VarDecl *D, raw_ostream &Out, char CharCode);
> -};
> -
> }
>
> bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) {
> @@ -497,18 +536,11 @@ void MicrosoftCXXNameMangler::mangleVirt
>
> void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) {
> // <name> ::= <unscoped-name> {[<named-scope>]+ | [<nested-name>]}? @
> - const DeclContext *DC = ND->getDeclContext();
>
> // Always start with the unqualified name.
> mangleUnqualifiedName(ND);
>
> - // If this is an extern variable declared locally, the relevant DeclContext
> - // is that of the containing namespace, or the translation unit.
> - if (isa<FunctionDecl>(DC) && ND->hasLinkage())
> - while (!DC->isNamespace() && !DC->isTranslationUnit())
> - DC = DC->getParent();
> -
> - manglePostfix(DC);
> + mangleNestedName(ND);
>
> // Terminate the whole name with an '@'.
> Out << '@';
> @@ -647,6 +679,20 @@ MicrosoftCXXNameMangler::mangleUnqualifi
> }
> }
>
> + if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
> + // We must have an anonymous union or struct declaration.
> + const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl();
> + assert(RD && "expected variable decl to have a record type");
> + // Anonymous types with no tag or typedef get the name of their
> + // declarator mangled in. If they have no declarator, number them with
> + // a $S prefix.
> + llvm::SmallString<64> Name("$S");
> + // Get a unique id for the anonymous struct.
> + Name += llvm::utostr(Context.getAnonymousStructId(RD) + 1);
> + mangleSourceName(Name.str());
> + break;
> + }
> +
> // We must have an anonymous struct.
> const TagDecl *TD = cast<TagDecl>(ND);
> if (const TypedefNameDecl *D = TD->getTypedefNameForAnonDecl()) {
> @@ -658,18 +704,18 @@ MicrosoftCXXNameMangler::mangleUnqualifi
> break;
> }
>
> + llvm::SmallString<64> Name("<unnamed-type-");
> if (TD->hasDeclaratorForAnonDecl()) {
> // Anonymous types with no tag or typedef get the name of their
> - // declarator mangled in.
> - llvm::SmallString<64> Name("<unnamed-type-");
> + // declarator mangled in if they have one.
> Name += TD->getDeclaratorForAnonDecl()->getName();
> - Name += ">";
> - mangleSourceName(Name.str());
> } else {
> - // Anonymous types with no tag, no typedef, or declarator get
> - // '<unnamed-tag>'.
> - mangleSourceName("<unnamed-tag>");
> + // Otherwise, number the types using a $S prefix.
> + Name += "$S";
> + Name += llvm::utostr(Context.getAnonymousStructId(TD) + 1);
> }
> + Name += ">";
> + mangleSourceName(Name.str());
> break;
> }
>
> @@ -721,45 +767,44 @@ MicrosoftCXXNameMangler::mangleUnqualifi
> }
> }
>
> -void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
> - bool NoFunction) {
> +void MicrosoftCXXNameMangler::mangleNestedName(const NamedDecl *ND) {
> // <postfix> ::= <unqualified-name> [<postfix>]
> // ::= <substitution> [<postfix>]
> + const DeclContext *DC = ND->getDeclContext();
>
> - if (!DC) return;
> + while (!DC->isTranslationUnit()) {
> + if (isa<TagDecl>(ND) || isa<VarDecl>(ND)) {
> + unsigned Disc;
> + if (Context.getNextDiscriminator(ND, Disc)) {
> + Out << '?';
> + mangleNumber(Disc);
> + Out << '?';
> + }
> + }
>
> - while (isa<LinkageSpecDecl>(DC))
> + if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
> + DiagnosticsEngine Diags = Context.getDiags();
> + unsigned DiagID =
> + Diags.getCustomDiagID(DiagnosticsEngine::Error,
> + "cannot mangle a local inside this block yet");
> + Diags.Report(BD->getLocation(), DiagID);
> +
> + // FIXME: This is completely, utterly, wrong; see ItaniumMangle
> + // for how this should be done.
> + Out << "__block_invoke" << Context.getBlockId(BD, false);
> + Out << '@';
> + continue;
> + } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) {
> + mangleObjCMethodName(Method);
> + } else if (isa<NamedDecl>(DC)) {
> + ND = cast<NamedDecl>(DC);
> + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
> + mangle(FD, "?");
> + break;
> + } else
> + mangleUnqualifiedName(ND);
> + }
> DC = DC->getParent();
> -
> - if (DC->isTranslationUnit())
> - return;
> -
> - if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
> - DiagnosticsEngine Diags = Context.getDiags();
> - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
> - "cannot mangle a local inside this block yet");
> - Diags.Report(BD->getLocation(), DiagID);
> -
> - // FIXME: This is completely, utterly, wrong; see ItaniumMangle
> - // for how this should be done.
> - Out << "__block_invoke" << Context.getBlockId(BD, false);
> - Out << '@';
> - return manglePostfix(DC->getParent(), NoFunction);
> - } else if (isa<CapturedDecl>(DC)) {
> - // Skip CapturedDecl context.
> - manglePostfix(DC->getParent(), NoFunction);
> - return;
> - }
> -
> - if (NoFunction && (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)))
> - return;
> - else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC))
> - mangleObjCMethodName(Method);
> - else if (const FunctionDecl *Func = dyn_cast<FunctionDecl>(DC))
> - mangleLocalName(Func);
> - else {
> - mangleUnqualifiedName(cast<NamedDecl>(DC));
> - manglePostfix(DC->getParent(), NoFunction);
> }
> }
>
> @@ -933,44 +978,6 @@ void MicrosoftCXXNameMangler::mangleObjC
> Context.mangleObjCMethodName(MD, Out);
> }
>
> -// Find out how many function decls live above this one and return an integer
> -// suitable for use as the number in a numbered anonymous scope.
> -// TODO: Memoize.
> -static unsigned getLocalNestingLevel(const FunctionDecl *FD) {
> - const DeclContext *DC = FD->getParent();
> - int level = 1;
> -
> - while (DC && !DC->isTranslationUnit()) {
> - if (isa<FunctionDecl>(DC) || isa<ObjCMethodDecl>(DC)) level++;
> - DC = DC->getParent();
> - }
> -
> - return 2*level;
> -}
> -
> -void MicrosoftCXXNameMangler::mangleLocalName(const FunctionDecl *FD) {
> - // <nested-name> ::= <numbered-anonymous-scope> ? <mangled-name>
> - // <numbered-anonymous-scope> ::= ? <number>
> - // Even though the name is rendered in reverse order (e.g.
> - // A::B::C is rendered as C at B@A), VC numbers the scopes from outermost to
> - // innermost. So a method bar in class C local to function foo gets mangled
> - // as something like:
> - // ?bar at C@?1??foo@@YAXXZ at QAEXXZ
> - // This is more apparent when you have a type nested inside a method of a
> - // type nested inside a function. A method baz in class D local to method
> - // bar of class C local to function foo gets mangled as:
> - // ?baz at D@?3??bar at C@?1??foo@@YAXXZ at QAEXXZ@QAEXXZ
> - // This scheme is general enough to support GCC-style nested
> - // functions. You could have a method baz of class C inside a function bar
> - // inside a function foo, like so:
> - // ?baz at C@?3??bar@?1??foo@@YAXXZ at YAXXZ@QAEXXZ
> - unsigned NestLevel = getLocalNestingLevel(FD);
> - Out << '?';
> - mangleNumber(NestLevel);
> - Out << '?';
> - mangle(FD, "?");
> -}
> -
> void MicrosoftCXXNameMangler::mangleTemplateInstantiationName(
> const TemplateDecl *TD,
> const TemplateArgumentList &TemplateArgs) {
> @@ -2228,7 +2235,7 @@ void MicrosoftMangleContextImpl::mangleS
> // N.B. This means that they can get more than 32 static variable guards in a
> // scope. It also means that they broke compatibility with their own ABI.
>
> - // <guard-name> ::= ?_B <postfix> @51
> + // <guard-name> ::= ?_B <postfix> @5 <scope-depth>
> // ::= ?$S <guard-num> @ <postfix> @4IA
>
> // The first mangling is what MSVC uses to guard static locals in inline
> @@ -2242,8 +2249,13 @@ void MicrosoftMangleContextImpl::mangleS
> bool Visible = VD->isExternallyVisible();
> // <operator-name> ::= ?_B # local static guard
> Mangler.getStream() << (Visible ? "\01??_B" : "\01?$S1@");
> - Mangler.manglePostfix(VD->getDeclContext());
> - Mangler.getStream() << (Visible ? "@51" : "@4IA");
> + Mangler.mangleNestedName(VD);
> + Mangler.getStream() << (Visible ? "@5" : "@4IA");
> + if (Visible) {
> + unsigned ScopeDepth;
> + getNextDiscriminator(VD, ScopeDepth);
> + Mangler.mangleNumber(ScopeDepth);
> + }
> }
>
> void MicrosoftMangleContextImpl::mangleInitFiniStub(const VarDecl *D,
>
> Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Mar 5 02:57:59 2014
> @@ -1291,7 +1291,7 @@ void MicrosoftCXXABI::EmitGuardedInit(Co
> if (D.isExternallyVisible()) {
> // Externally visible variables have to be numbered in Sema to properly
> // handle unreachable VarDecls.
> - BitIndex = getContext().getManglingNumber(&D);
> + BitIndex = getContext().getStaticLocalNumber(&D);
> assert(BitIndex > 0);
> BitIndex--;
> } else {
>
> Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Mar 5 02:57:59 2014
> @@ -1078,8 +1078,7 @@ StmtResult Parser::ParseIfStatement(Sour
> // would have to notify ParseStatement not to create a new scope. It's
> // simpler to let it create a new scope.
> //
> - ParseScope InnerScope(this, Scope::DeclScope,
> - C99orCXX && Tok.isNot(tok::l_brace));
> + ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
>
> // Read the 'then' stmt.
> SourceLocation ThenStmtLoc = Tok.getLocation();
> @@ -1111,8 +1110,7 @@ StmtResult Parser::ParseIfStatement(Sour
> // The substatement in a selection-statement (each substatement, in the else
> // form of the if statement) implicitly defines a local scope.
> //
> - ParseScope InnerScope(this, Scope::DeclScope,
> - C99orCXX && Tok.isNot(tok::l_brace));
> + ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
>
> ElseStmt = ParseStatement();
>
> @@ -1215,8 +1213,7 @@ StmtResult Parser::ParseSwitchStatement(
> // condition and a new scope for substatement in C++.
> //
> getCurScope()->AddFlags(Scope::BreakScope);
> - ParseScope InnerScope(this, Scope::DeclScope,
> - C99orCXX && Tok.isNot(tok::l_brace));
> + ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
>
> // Read the body statement.
> StmtResult Body(ParseStatement(TrailingElseLoc));
> @@ -1293,8 +1290,7 @@ StmtResult Parser::ParseWhileStatement(S
> // See comments in ParseIfStatement for why we create a scope for the
> // condition and a new scope for substatement in C++.
> //
> - ParseScope InnerScope(this, Scope::DeclScope,
> - C99orCXX && Tok.isNot(tok::l_brace));
> + ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
>
> // Read the body statement.
> StmtResult Body(ParseStatement(TrailingElseLoc));
> @@ -1335,9 +1331,8 @@ StmtResult Parser::ParseDoStatement() {
> // The substatement in an iteration-statement implicitly defines a local scope
> // which is entered and exited each time through the loop.
> //
> - ParseScope InnerScope(this, Scope::DeclScope,
> - (getLangOpts().C99 || getLangOpts().CPlusPlus) &&
> - Tok.isNot(tok::l_brace));
> + bool C99orCXX = getLangOpts().C99 || getLangOpts().CPlusPlus;
> + ParseScope InnerScope(this, Scope::DeclScope, C99orCXX, Tok.is(tok::l_brace));
>
> // Read the body statement.
> StmtResult Body(ParseStatement());
> @@ -1624,8 +1619,15 @@ StmtResult Parser::ParseForStatement(Sou
> // See comments in ParseIfStatement for why we create a scope for
> // for-init-statement/condition and a new scope for substatement in C++.
> //
> - ParseScope InnerScope(this, Scope::DeclScope,
> - C99orCXXorObjC && Tok.isNot(tok::l_brace));
> + ParseScope InnerScope(this, Scope::DeclScope, C99orCXXorObjC,
> + Tok.is(tok::l_brace));
> +
> + // The body of the for loop has the same local mangling number as the
> + // for-init-statement.
> + // 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();
>
> // Read the body statement.
> StmtResult Body(ParseStatement(TrailingElseLoc));
>
> Modified: cfe/trunk/lib/Sema/Scope.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Scope.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/Scope.cpp (original)
> +++ cfe/trunk/lib/Sema/Scope.cpp Wed Mar 5 02:57:59 2014
> @@ -13,6 +13,7 @@
> //===----------------------------------------------------------------------===//
>
> #include "clang/Sema/Scope.h"
> +#include "llvm/Support/raw_ostream.h"
>
> using namespace clang;
>
> @@ -36,16 +37,24 @@ void Scope::Init(Scope *parent, unsigned
> FnParent = parent->FnParent;
> BlockParent = parent->BlockParent;
> TemplateParamParent = parent->TemplateParamParent;
> + MSLocalManglingParent = parent->MSLocalManglingParent;
> } else {
> Depth = 0;
> PrototypeDepth = 0;
> PrototypeIndex = 0;
> - FnParent = BlockParent = 0;
> + MSLocalManglingParent = FnParent = BlockParent = 0;
> TemplateParamParent = 0;
> + MSLocalManglingNumber = 1;
> }
>
> // If this scope is a function or contains breaks/continues, remember it.
> if (flags & FnScope) FnParent = this;
> + // 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;
> + }
> if (flags & BreakScope) BreakParent = this;
> if (flags & ContinueScope) ContinueParent = this;
> if (flags & BlockScope) BlockParent = this;
> @@ -53,6 +62,16 @@ void Scope::Init(Scope *parent, unsigned
>
> // If this is a prototype scope, record that.
> if (flags & FunctionPrototypeScope) PrototypeDepth++;
> + if (flags & DeclScope) {
> + if (flags & FunctionPrototypeScope)
> + ; // Prototype scopes are uninteresting.
> + else if ((flags & ClassScope) && getParent()->isClassScope())
> + ; // Nested class scopes aren't ambiguous.
> + else if ((flags & ClassScope) && getParent()->getFlags() == DeclScope)
> + ; // Classes inside of namespaces aren't ambiguous.
> + else
> + incrementMSLocalManglingNumber();
> + }
>
> DeclsInScope.clear();
> UsingDirectives.clear();
> @@ -84,3 +103,77 @@ void Scope::AddFlags(unsigned FlagsToSet
> Flags |= FlagsToSet;
> }
>
> +void Scope::dump() const { dumpImpl(llvm::errs()); }
> +
> +void Scope::dumpImpl(raw_ostream &OS) const {
> + unsigned Flags = getFlags();
> + bool HasFlags = Flags != 0;
> +
> + if (HasFlags)
> + OS << "Flags: ";
> +
> + while (Flags) {
> + if (Flags & FnScope) {
> + OS << "FnScope";
> + Flags &= ~FnScope;
> + } else if (Flags & BreakScope) {
> + OS << "BreakScope";
> + Flags &= ~BreakScope;
> + } else if (Flags & ContinueScope) {
> + OS << "ContinueScope";
> + Flags &= ~ContinueScope;
> + } else if (Flags & DeclScope) {
> + OS << "DeclScope";
> + Flags &= ~DeclScope;
> + } else if (Flags & ControlScope) {
> + OS << "ControlScope";
> + Flags &= ~ControlScope;
> + } else if (Flags & ClassScope) {
> + OS << "ClassScope";
> + Flags &= ~ClassScope;
> + } else if (Flags & BlockScope) {
> + OS << "BlockScope";
> + Flags &= ~BlockScope;
> + } else if (Flags & TemplateParamScope) {
> + OS << "TemplateParamScope";
> + Flags &= ~TemplateParamScope;
> + } else if (Flags & FunctionPrototypeScope) {
> + OS << "FunctionPrototypeScope";
> + Flags &= ~FunctionPrototypeScope;
> + } else if (Flags & FunctionDeclarationScope) {
> + OS << "FunctionDeclarationScope";
> + Flags &= ~FunctionDeclarationScope;
> + } else if (Flags & AtCatchScope) {
> + OS << "AtCatchScope";
> + Flags &= ~AtCatchScope;
> + } else if (Flags & ObjCMethodScope) {
> + OS << "ObjCMethodScope";
> + Flags &= ~ObjCMethodScope;
> + } else if (Flags & SwitchScope) {
> + OS << "SwitchScope";
> + Flags &= ~SwitchScope;
> + } else if (Flags & TryScope) {
> + OS << "TryScope";
> + Flags &= ~TryScope;
> + } else if (Flags & FnTryCatchScope) {
> + OS << "FnTryCatchScope";
> + Flags &= ~FnTryCatchScope;
> + } else if (Flags & OpenMPDirectiveScope) {
> + OS << "OpenMPDirectiveScope";
> + Flags &= ~OpenMPDirectiveScope;
> + }
> +
> + if (Flags)
> + OS << " | ";
> + }
> + if (HasFlags)
> + OS << '\n';
> +
> + if (const Scope *Parent = getParent())
> + OS << "Parent: (clang::Scope*)" << Parent << '\n';
> +
> + OS << "Depth: " << Depth << '\n';
> + OS << "MSLocalManglingNumber: " << getMSLocalManglingNumber() << '\n';
> + if (const DeclContext *DC = getEntity())
> + OS << "Entity : (clang::DeclContext*)" << DC << '\n';
> +}
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Mar 5 02:57:59 2014
> @@ -3157,7 +3157,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(S
> return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg());
> }
>
> -static void HandleTagNumbering(Sema &S, const TagDecl *Tag) {
> +static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) {
> if (!S.Context.getLangOpts().CPlusPlus)
> return;
>
> @@ -3168,7 +3168,7 @@ static void HandleTagNumbering(Sema &S,
> return;
> MangleNumberingContext &MCtx =
> S.Context.getManglingNumberContext(Tag->getParent());
> - S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag));
> + S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag, TagScope));
> return;
> }
>
> @@ -3177,7 +3177,7 @@ static void HandleTagNumbering(Sema &S,
> if (MangleNumberingContext *MCtx =
> S.getCurrentMangleNumberContext(Tag->getDeclContext(),
> ManglingContextDecl)) {
> - S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag));
> + S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag, TagScope));
> }
> }
>
> @@ -3210,7 +3210,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(S
> }
>
> if (Tag) {
> - HandleTagNumbering(*this, Tag);
> + HandleTagNumbering(*this, Tag, S);
> Tag->setFreeStanding();
> if (Tag->isInvalidDecl())
> return Tag;
> @@ -3810,6 +3810,18 @@ Decl *Sema::BuildAnonymousStructOrUnion(
> Chain, false))
> Invalid = true;
>
> + 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));
> + Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
> + }
> + }
> + }
> +
> if (Invalid)
> Anon->setInvalidDecl();
>
> @@ -5470,7 +5482,8 @@ Sema::ActOnVariableDeclarator(Scope *S,
> if (MangleNumberingContext *MCtx =
> getCurrentMangleNumberContext(NewVD->getDeclContext(),
> ManglingContextDecl)) {
> - Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD));
> + Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S));
> + Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD));
> }
> }
>
> @@ -8990,7 +9003,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDecla
>
> if (DeclSpec::isDeclRep(DS.getTypeSpecType())) {
> if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) {
> - HandleTagNumbering(*this, Tag);
> + HandleTagNumbering(*this, Tag, S);
> if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl())
> Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup);
> }
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Mar 5 02:57:59 2014
> @@ -3636,6 +3636,7 @@ void Sema::BuildVariableInstantiation(
>
> // Forward the mangling number from the template to the instantiated decl.
> Context.setManglingNumber(NewVar, Context.getManglingNumber(OldVar));
> + Context.setStaticLocalNumber(NewVar, Context.getStaticLocalNumber(OldVar));
>
> // Delay instantiation of the initializer for variable templates until a
> // definition of the variable is needed.
>
> Modified: cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/mangle-ms-abi-examples.cpp Wed Mar 5 02:57:59 2014
> @@ -11,7 +11,7 @@ struct A {
> B();
> }
> };
> -void foo () {
> +inline void foo () {
> struct C {
> struct D { virtual ~D() {} };
> void bar () {
> @@ -25,4 +25,6 @@ void foo () {
> C::D();
> C().bar();
> }
> -
> +void call () {
> + foo();
> +}
>
> Modified: cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp?rev=202951&r1=202950&r2=202951&view=diff
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/microsoft-abi-static-initializers.cpp Wed Mar 5 02:57:59 2014
> @@ -24,8 +24,8 @@ void StaticLocal() {
> static S TheS;
> }
> // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"()
> -// CHECK: load i32* @"\01?$S1@?1??StaticLocal@@YAXXZ at 4IA"
> -// CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ at 4IA"
> +// CHECK: load i32* @"\01?$S1@?0??StaticLocal@@YAXXZ at 4IA"
> +// CHECK: store i32 {{.*}}, i32* @"\01?$S1@?0??StaticLocal@@YAXXZ at 4IA"
> // CHECK: ret
>
> void MultipleStatics() {
> @@ -66,7 +66,7 @@ void MultipleStatics() {
> static S S35;
> }
> // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"()
> -// CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ at 4IA"
> +// CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ at 4IA"
> // CHECK: and i32 {{.*}}, 1
> // CHECK: and i32 {{.*}}, 2
> // CHECK: and i32 {{.*}}, 4
> @@ -74,7 +74,7 @@ void MultipleStatics() {
> // CHECK: and i32 {{.*}}, 16
> // ...
> // CHECK: and i32 {{.*}}, -2147483648
> -// CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ at 4IA1"
> +// CHECK: load i32* @"\01?$S1@?0??MultipleStatics@@YAXXZ at 4IA1"
> // CHECK: and i32 {{.*}}, 1
> // CHECK: and i32 {{.*}}, 2
> // CHECK: and i32 {{.*}}, 4
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list