зеркало из https://github.com/microsoft/clang-1.git
Encode Class, SEL and Objective-C objects.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43540 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
8967e9e6c3
Коммит
8baaca50f0
|
@ -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!");
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче