diff options
Diffstat (limited to 'clang/lib/AST/MicrosoftMangle.cpp')
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 83 |
1 files changed, 40 insertions, 43 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 0599d8af813..24eac84cdd2 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -121,8 +121,7 @@ public: void mangleDeclaration(const NamedDecl *ND); void mangleFunctionEncoding(const FunctionDecl *FD); void mangleVariableEncoding(const VarDecl *VD); - void mangleNumber(uint32_t Number); - void mangleNumber(const llvm::APSInt &Value); + void mangleNumber(int64_t Number); void mangleType(QualType T, SourceRange Range, QualifierMangleMode QMM = QMM_Mangle); void mangleFunctionType(const FunctionType *T, const FunctionDecl *D = 0, @@ -182,7 +181,8 @@ public: virtual bool shouldMangleCXXName(const NamedDecl *D); virtual void mangleCXXName(const NamedDecl *D, raw_ostream &Out); virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD, - int OffsetInVFTable, raw_ostream &); + uint64_t OffsetInVFTable, + raw_ostream &); virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &); @@ -390,40 +390,33 @@ void MicrosoftCXXNameMangler::mangleName(const NamedDecl *ND) { Out << '@'; } -void MicrosoftCXXNameMangler::mangleNumber(uint32_t Number) { - llvm::APSInt APSNumber(/*BitWidth=*/32, /*isUnsigned=*/true); - APSNumber = Number; - mangleNumber(APSNumber); -} +void MicrosoftCXXNameMangler::mangleNumber(int64_t Number) { + // <non-negative integer> ::= A@ # when Number == 0 + // ::= <decimal digit> # when 1 <= Number <= 10 + // ::= <hex digit>+ @ # when Number >= 10 + // + // <number> ::= [?] <non-negative integer> -void MicrosoftCXXNameMangler::mangleNumber(const llvm::APSInt &Value) { - // <number> ::= [?] <decimal digit> # 1 <= Number <= 10 - // ::= [?] <hex digit>+ @ # 0 or > 9; A = 0, B = 1, etc... - // ::= [?] @ # 0 (alternate mangling, not emitted by VC) - if (Value.isSigned() && Value.isNegative()) { + uint64_t Value = static_cast<uint64_t>(Number); + if (Number < 0) { + Value = -Value; Out << '?'; - mangleNumber(llvm::APSInt(Value.abs())); - return; } - llvm::APSInt Temp(Value); - // There's a special shorter mangling for 0, but Microsoft - // chose not to use it. Instead, 0 gets mangled as "A@". Oh well... - if (Value.uge(1) && Value.ule(10)) { - --Temp; - Temp.print(Out, false); - } else { - // We have to build up the encoding in reverse order, so it will come - // out right when we write it out. - char Encoding[64]; - char *EndPtr = Encoding+sizeof(Encoding); - char *CurPtr = EndPtr; - llvm::APSInt NibbleMask(Value.getBitWidth(), Value.isUnsigned()); - NibbleMask = 0xf; - do { - *--CurPtr = 'A' + Temp.And(NibbleMask).getLimitedValue(0xf); - Temp = Temp.lshr(4); - } while (Temp != 0); - Out.write(CurPtr, EndPtr-CurPtr); + + if (Value == 0) + Out << "A@"; + else if (Value >= 1 && Value <= 10) + Out << (Value - 1); + else { + // Numbers that are not encoded as decimal digits are represented as nibbles + // in the range of ASCII characters 'A' to 'P'. + // The number 0x123450 would be encoded as 'BCDEFA' + char EncodedNumberBuffer[sizeof(uint64_t) * 2]; + llvm::MutableArrayRef<char> BufferRef(EncodedNumberBuffer); + llvm::MutableArrayRef<char>::reverse_iterator I = BufferRef.rbegin(); + for (; Value != 0; Value >>= 4) + *I++ = 'A' + (Value & 0xf); + Out.write(I.base(), I - BufferRef.rbegin()); Out << '@'; } } @@ -885,7 +878,7 @@ MicrosoftCXXNameMangler::mangleIntegerLiteral(const llvm::APSInt &Value, if (IsBoolean && Value.getBoolValue()) mangleNumber(1); else - mangleNumber(Value); + mangleNumber(Value.getSExtValue()); } void @@ -1885,14 +1878,18 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, } if (Adjustment.Virtual.Microsoft.VBPtrOffset) { Out << 'R' << AccessSpec; - Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VBPtrOffset); - Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VBOffsetOffset); - Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VtordispOffset); - Mangler.mangleNumber(Adjustment.NonVirtual); + Mangler.mangleNumber( + static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBPtrOffset)); + Mangler.mangleNumber( + static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VBOffsetOffset)); + Mangler.mangleNumber( + static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset)); + Mangler.mangleNumber(static_cast<uint32_t>(Adjustment.NonVirtual)); } else { Out << AccessSpec; - Mangler.mangleNumber(Adjustment.Virtual.Microsoft.VtordispOffset); - Mangler.mangleNumber(-Adjustment.NonVirtual); + Mangler.mangleNumber( + static_cast<uint32_t>(Adjustment.Virtual.Microsoft.VtordispOffset)); + Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual)); } } else if (Adjustment.NonVirtual != 0) { switch (MD->getAccess()) { @@ -1907,7 +1904,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, case AS_public: Out << 'W'; } - Mangler.mangleNumber(-Adjustment.NonVirtual); + Mangler.mangleNumber(-static_cast<uint32_t>(Adjustment.NonVirtual)); } else { switch (MD->getAccess()) { case AS_none: @@ -1925,7 +1922,7 @@ static void mangleThunkThisAdjustment(const CXXMethodDecl *MD, } void MicrosoftMangleContextImpl::mangleVirtualMemPtrThunk( - const CXXMethodDecl *MD, int OffsetInVFTable, raw_ostream &Out) { + const CXXMethodDecl *MD, uint64_t OffsetInVFTable, raw_ostream &Out) { bool Is64Bit = getASTContext().getTargetInfo().getPointerWidth(0) == 64; MicrosoftCXXNameMangler Mangler(*this, Out); |