From a1c033e9514865f3a7b0d8b3b20e6de926cfec6c Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 23 Dec 2008 19:56:47 +0000 Subject: [PATCH] Lot more encoding work. We are closing the gap to gcc compatibilty in all aspects of encoding now. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61383 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 2 ++ lib/AST/ASTContext.cpp | 60 ++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 4ac1c5d764..ee217522dc 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -300,6 +300,8 @@ public: /// record field names are also encoded. void getObjCEncodingForType(QualType t, std::string &S, FieldDecl *Field=NULL) const; + + void getLegacyIntegralTypeEncoding(QualType &t) const; // Put the string version of type qualifiers into S. void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index ad6c0dfc6c..b9514f35a0 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1749,6 +1749,22 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD, // FIXME: OBJCGC: weak & strong } +/// getLegacyIntegralTypeEncoding - +/// Another legacy compatibility encoding: 32-bit longs are encoded as +/// 'l' or 'L', but not always. For typedefs, we need to use +/// 'i' or 'I' instead if encoding a struct field, or a pointer! +/// +void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const { + if (dyn_cast(PointeeTy.getTypePtr())) { + if (const BuiltinType *BT = PointeeTy->getAsBuiltinType()) { + if (BT->getKind() == BuiltinType::ULong) + PointeeTy = UnsignedIntTy; + else if (BT->getKind() == BuiltinType::Long) + PointeeTy = IntTy; + } + } +} + void ASTContext::getObjCEncodingForType(QualType T, std::string& S, FieldDecl *Field) const { // We follow the behavior of gcc, expanding structures which are @@ -1807,8 +1823,37 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } else if (const PointerType *PT = T->getAsPointerType()) { QualType PointeeTy = PT->getPointeeType(); - if (OutermostType && PointeeTy.isConstQualified()) - S += 'r'; + bool isReadOnly = false; + // For historical/compatibility reasons, the read-only qualifier of the + // pointee gets emitted _before_ the '^'. The read-only qualifier of + // the pointer itself gets ignored, _unless_ we are looking at a typedef! + // Also, do not emit the 'r' for anything but the outermost type! + if (dyn_cast(T.getTypePtr())) { + if (OutermostType && T.isConstQualified()) { + isReadOnly = true; + S += 'r'; + } + } + else if (OutermostType) { + QualType P = PointeeTy; + while (P->getAsPointerType()) + P = P->getAsPointerType()->getPointeeType(); + if (P.isConstQualified()) { + isReadOnly = true; + S += 'r'; + } + } + if (isReadOnly) { + // Another legacy compatibility encoding. Some ObjC qualifier and type + // combinations need to be rearranged. + // Rewrite "in const" from "nr" to "rn" + const char * s = S.c_str(); + int len = S.length(); + if (len >= 2 && s[len-2] == 'n' && s[len-1] == 'r') { + std::string replace = "rn"; + S.replace(S.end()-2, S.end(), replace); + } + } if (isObjCIdType(PointeeTy)) { S += '@'; return; @@ -1840,7 +1885,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } S += '^'; - getObjCEncodingForTypeImpl(PT->getPointeeType(), S, + getLegacyIntegralTypeEncoding(PointeeTy); + + getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures, NULL); } else if (const ArrayType *AT = @@ -1883,10 +1930,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getObjCEncodingForTypeImpl(Field->getType(), S, false, true, (*Field)); } else { - // FIXME! Another legacy kludge: 32-bit longs are encoded as - // 'l' or 'L', but not always. For typedefs, we need to use - // 'i' or 'I' instead if encoding a struct field, or a pointer! - getObjCEncodingForTypeImpl(Field->getType(), S, false, true, + QualType qt = Field->getType(); + getLegacyIntegralTypeEncoding(qt); + getObjCEncodingForTypeImpl(qt, S, false, true, FD); } } -- 2.40.0