Encode Class, SEL and Objective-C objects.

llvm-svn: 43540
This commit is contained in:
Anders Carlsson 2007-10-31 02:53:19 +00:00
parent df62bc067a
commit f56a7aee2f
6 changed files with 75 additions and 1 deletions

View File

@ -152,6 +152,9 @@ void ASTContext::InitBuiltinTypes() {
BuiltinVaListType = QualType();
ObjcIdType = QualType();
IdStructType = 0;
ObjcClassType = QualType();
ClassStructType = 0;
ObjcConstantStringType = QualType();
// void * type
@ -1008,9 +1011,15 @@ void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
S += encoding;
} else if (const PointerType *PT = T->getAsPointerType()) {
QualType PointeeTy = PT->getPointeeType();
if (isObjcIdType(PointeeTy)) {
if (isObjcIdType(PointeeTy) || PointeeTy->isObjcInterfaceType()) {
S += '@';
return;
} else if (isObjcClassType(PointeeTy)) {
S += '#';
return;
} else if (isObjcSelType(PointeeTy)) {
S += ':';
return;
}
if (PointeeTy->isCharType()) {
@ -1086,6 +1095,20 @@ void ASTContext::setObjcProtoType(TypedefDecl *TD)
ProtoStructType = TD->getUnderlyingType()->getAsStructureType();
}
void ASTContext::setObjcClassType(TypedefDecl *TD)
{
assert(ObjcClassType.isNull() && "'Class' type already set!");
ObjcClassType = getTypedefType(TD);
// typedef struct objc_class *Class;
const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
assert(ptr && "'Class' incorrectly typed");
const RecordType *rec = ptr->getPointeeType()->getAsStructureType();
assert(rec && "'Class' incorrectly typed");
ClassStructType = rec;
}
void ASTContext::setObjcConstantStringInterface(ObjcInterfaceDecl *Decl) {
assert(ObjcConstantStringType.isNull() &&
"'NSConstantString' type already set!");

View File

@ -82,6 +82,25 @@ QualType Sema::GetObjcProtoType(SourceLocation Loc) {
return Context.getObjcProtoType();
}
/// GetObjcClassType - See comments for Sema::GetObjcIdType above; replace "id"
/// with "Protocol".
QualType Sema::GetObjcClassType(SourceLocation Loc) {
assert(TUScope && "GetObjcClassType(): Top-level scope is null");
if (!Context.getObjcClassType().isNull())
return Context.getObjcClassType();
IdentifierInfo *ClassIdent = &Context.Idents.get("Class");
ScopedDecl *ClassDecl = LookupScopedDecl(ClassIdent, Decl::IDNS_Ordinary,
SourceLocation(), TUScope);
TypedefDecl *ObjcClassTypedef = dyn_cast_or_null<TypedefDecl>(ClassDecl);
if (!ObjcClassTypedef) {
Diag(Loc, diag::err_missing_class_definition);
return QualType();
}
Context.setObjcClassType(ObjcClassTypedef);
return Context.getObjcClassType();
}
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup)
: PP(pp), Context(ctxt), CurFunctionDecl(0), LastInGroupList(prevInGroup) {

View File

@ -284,6 +284,9 @@ private:
/// GetObjcSelType - Getter for the build-in "Protocol *" type.
QualType GetObjcProtoType(SourceLocation Loc = SourceLocation());
// GetObjcClassType - Getter for the built-in "Class" type.
QualType GetObjcClassType(SourceLocation Loc = SourceLocation());
/// AddInstanceMethodToGlobalPool - All instance methods in a translation
/// unit are added to a global pool. This allows us to efficiently associate
/// a selector with a method declaraation for purposes of typechecking

View File

@ -1959,6 +1959,17 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation RParenLoc) {
QualType EncodedType = QualType::getFromOpaquePtr(Ty);
// We cannot build type 'id' lazily. It is needed when checking if a
// type is an 'id' (via call to isObjcIdType) even if there is no
// need for the default 'id' type.
// FIXME: Depending on the need to compare to 'id', this may have to go
// somewhere else. At this time, this is a good enough place to do type
// encoding of methods and ivars for the rewrite client.
// The same is true for the 'Class' and 'SEL' types.
GetObjcIdType(EncodeLoc);
GetObjcClassType(EncodeLoc);
GetObjcSelType(EncodeLoc);
QualType t = Context.getPointerType(Context.CharTy);
return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
}

View File

@ -59,6 +59,10 @@ class ASTContext {
/// ObjcProtoType - another psuedo built-in typedef type (set by Sema).
QualType ObjcProtoType;
const RecordType *ProtoStructType;
/// ObjcClassType - another psuedo built-in typedef type (set by Sema).
QualType ObjcClassType;
const RecordType *ClassStructType;
QualType ObjcConstantStringType;
RecordDecl *CFConstantStringTypeDecl;
@ -196,6 +200,9 @@ public:
void setObjcProtoType(TypedefDecl *Decl);
QualType getObjcProtoType() const { return ObjcProtoType; }
void setObjcClassType(TypedefDecl *Decl);
QualType getObjcClassType() const { return ObjcClassType; }
void setBuiltinVaListType(QualType T);
QualType getBuiltinVaListType() const { return BuiltinVaListType; }
@ -264,6 +271,15 @@ public:
assert(IdStructType && "isObjcIdType used before 'id' type is built");
return T->getAsStructureType() == IdStructType;
}
bool isObjcClassType(QualType T) const {
assert(ClassStructType && "isObjcClassType used before 'Class' type is built");
return T->getAsStructureType() == ClassStructType;
}
bool isObjcSelType(QualType T) const {
assert(SelStructType && "isObjcSelType used before 'SEL' type is built");
return T->getAsStructureType() == SelStructType;
}
private:
ASTContext(const ASTContext&); // DO NOT IMPLEMENT
void operator=(const ASTContext&); // DO NOT IMPLEMENT

View File

@ -450,6 +450,8 @@ DIAG(err_missing_id_definition, ERROR,
"cannot find definition of 'id'")
DIAG(err_missing_proto_definition, ERROR,
"cannot find definition of 'Protocol'")
DIAG(err_missing_class_definition, ERROR,
"cannot find definition of 'Class'")
DIAG(warn_previous_alias_decl, WARNING,
"previously declared alias is ignored")
DIAG(warn_previous_declaration, WARNING,