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