aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2007-10-31 02:53:19 +0000
committerAnders Carlsson <andersca@mac.com>2007-10-31 02:53:19 +0000
commit8baaca50f07d0c10bba69c8d88c1b9078c92d06d (patch)
treecb6a289add9d8d9e1d53faa13d1125d6fbad17e7
parent8967e9e6c30b61fa9399dd38d6e383651ddbc54d (diff)
Encode Class, SEL and Objective-C objects.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43540 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--AST/ASTContext.cpp25
-rw-r--r--Sema/Sema.cpp19
-rw-r--r--Sema/Sema.h3
-rw-r--r--Sema/SemaExpr.cpp11
-rw-r--r--include/clang/AST/ASTContext.h16
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
6 files changed, 75 insertions, 1 deletions
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
index 93ec288270..ec7cd7b558 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -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!");
diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp
index 2be198de43..92d17e1e99 100644
--- a/Sema/Sema.cpp
+++ b/Sema/Sema.cpp
@@ -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) {
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 9db00fb1c2..13ba636d52 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -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
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index ee3510785b..aac6ca3218 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -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);
}
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index dda0490f24..043ffb30c9 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -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
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index bbdb6bc517..8a65b7310e 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -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,