ObjcIdType = QualType();
IdStructType = 0;
ObjcConstantStringType = QualType();
+
+ // void * type
+ VoidPtrTy = getPointerType(VoidTy);
}
//===----------------------------------------------------------------------===//
return false;
}
+/// getObjcEncodingTypeSize returns size of type for objective-c encoding
+/// purpose.
+int ASTContext::getObjcEncodingTypeSize(QualType type) {
+ SourceLocation Loc;
+ uint64_t sz = getTypeSize(type, Loc);
+
+ // Make all integer and enum types at least as large as an int
+ if (sz > 0 && type->isIntegralType())
+ sz = std::max(sz, getTypeSize(IntTy, Loc));
+ // Treat arrays as pointers, since that's how they're passed in.
+ else if (type->isArrayType())
+ sz = getTypeSize(VoidPtrTy, Loc);
+ return sz / getTypeSize(CharTy, Loc);
+}
+
+/// getObjcEncodingForMethodDecl - Return the encoded type for this method
+/// declaration.
+void ASTContext::getObjcEncodingForMethodDecl(ObjcMethodDecl *Decl,
+ std::string& S)
+{
+ // TODO: First encode type qualifer, 'in', 'inout', etc. for the return type.
+ // Encode result type.
+ getObjcEncodingForType(Decl->getResultType(), S);
+ // Compute size of all parameters.
+ // Start with computing size of a pointer in number of bytes.
+ // FIXME: There might(should) be a better way of doing this computation!
+ SourceLocation Loc;
+ int PtrSize = getTypeSize(VoidPtrTy, Loc) / getTypeSize(CharTy, Loc);
+ // The first two arguments (self and _cmd) are pointers; account for
+ // their size.
+ int ParmOffset = 2 * PtrSize;
+ int NumOfParams = Decl->getNumParams();
+ for (int i = 0; i < NumOfParams; i++) {
+ QualType PType = Decl->getParamDecl(i)->getType();
+ int sz = getObjcEncodingTypeSize (PType);
+ assert (sz > 0 && "getObjcEncodingForMethodDecl - Incomplete param type");
+ ParmOffset += sz;
+ }
+ S += llvm::utostr(ParmOffset);
+ S += "@0:";
+ S += llvm::utostr(PtrSize);
+
+ // Argument types.
+ ParmOffset = 2 * PtrSize;
+ for (int i = 0; i < NumOfParams; i++) {
+ QualType PType = Decl->getParamDecl(i)->getType();
+ // TODO: Process argument qualifiers for user supplied arguments; such as,
+ // 'in', 'inout', etc.
+ getObjcEncodingForType(PType, S);
+ S += llvm::utostr(ParmOffset);
+ ParmOffset += getObjcEncodingTypeSize(PType);
+ }
+}
+
void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
{
// FIXME: This currently doesn't encode:
return false;
}
+bool Type::isIntegralType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() >= BuiltinType::Bool &&
+ BT->getKind() <= BuiltinType::LongLong;
+ if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+ if (TT->getDecl()->getKind() == Decl::Enum)
+ return true;
+ return false;
+}
+
bool Type::isEnumeralType() const {
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
return TT->getDecl()->getKind() == Decl::Enum;
Result += "\t,{{(SEL)\"";
Result += Methods[0]->getSelector().getName().c_str();
- Result += "\", \"\", 0}\n";
-
+ std::string MethodTypeString;
+ Context->getObjcEncodingForMethodDecl(Methods[0], MethodTypeString);
+ Result += "\", \"";
+ Result += MethodTypeString;
+ Result += "\", 0}\n";
for (int i = 1; i < NumMethods; i++) {
- // TODO: 1) method selector name may hav to go into their own section
- // 2) encode method types for use here (which may have to go into
- // __meth_var_types section, 3) Need method address as 3rd initializer.
+ // TODO: Need method address as 3rd initializer.
Result += "\t ,{(SEL)\"";
Result += Methods[i]->getSelector().getName().c_str();
- Result += "\", \"\", 0}\n";
+ std::string MethodTypeString;
+ Context->getObjcEncodingForMethodDecl(Methods[i], MethodTypeString);
+ Result += "\", \"";
+ Result += MethodTypeString;
+ Result += "\", 0}\n";
}
Result += "\t }\n};\n";
}
Result += "\", \"\"}\n";
for (int i = 1; i < NumMethods; i++) {
- // TODO: 1) method selector name may hav to go into their own section
- // 2) encode method types for use here (which may have to go into
- // __meth_var_types section.
Result += "\t ,{(SEL)\"";
Result += Methods[i]->getSelector().getName().c_str();
- Result += "\", \"\"}\n";
+ std::string MethodTypeString;
+ Context->getObjcEncodingForMethodDecl(Methods[i], MethodTypeString);
+ Result += "\", \"";
+ Result += MethodTypeString;
+ Result += "\"}\n";
}
Result += "\t }\n};\n";
}
Result += "\", \"\"}\n";
for (int i = 1; i < NumMethods; i++) {
- // TODO: 1) method selector name may hav to go into their own section
- // 2) encode method types for use here (which may have to go into
- // __meth_var_types section.
Result += "\t ,{(SEL)\"";
Result += Methods[i]->getSelector().getName().c_str();
- Result += "\", \"\"}\n";
+ std::string MethodTypeString;
+ Context->getObjcEncodingForMethodDecl(Methods[i], MethodTypeString);
+ Result += "\", \"";
+ Result += MethodTypeString;
+ Result += "\"}\n";
}
Result += "\t }\n};\n";
}
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+ compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
projectDirPath = "";
QualType UnsignedLongLongTy;
QualType FloatTy, DoubleTy, LongDoubleTy;
QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
+ QualType VoidPtrTy;
ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents,
SelectorTable &sels) :
// Return the ObjC type encoding for a given type.
void getObjcEncodingForType(QualType t, std::string &S) const;
+
+ /// getObjcEncodingForMethodDecl - Return the encoded type for this method
+ /// declaration.
+ void getObjcEncodingForMethodDecl(ObjcMethodDecl *Decl, std::string &S);
+
+ /// getObjcEncodingTypeSize returns size of type for objective-c encoding
+ /// purpose.
+ int getObjcEncodingTypeSize(QualType t);
// This setter/getter repreents the ObjC 'id' type. It is setup lazily, by
// Sema.
class EnumDecl;
class ObjcInterfaceDecl;
class ObjcProtocolDecl;
+ class ObjcMethodDecl;
class Expr;
class SourceLocation;
class PointerType;
bool isEnumeralType() const;
bool isBooleanType() const;
bool isCharType() const;
+ bool isIntegralType() const;
/// Floating point categories.
bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double)