[cfe-commits] r79248 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCGNU.cpp lib/Sema/Sema.cpp lib/Sema/SemaChecking.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp
David Chisnall
csdavec at swan.ac.uk
Mon Aug 17 09:35:33 PDT 2009
Author: theraven
Date: Mon Aug 17 11:35:33 2009
New Revision: 79248
URL: http://llvm.org/viewvc/llvm-project?rev=79248&view=rev
Log:
Initial patch to support definitions of id and Class from headers in Objective-C code.
This currently breaks test/SemaObjC/id-isa-ref.m and issues some spurious warnings when you attempt to assign a struct objc_class* value to a Class variable. The test case probably should fail as it's written, because without the definition of Class the compiler should not assume struct objc_class* is a valid receiver type, but it's left broken because it would be nice if we could get that passing too for the special case of isa.
Approved by snaroff.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Aug 17 11:35:33 2009
@@ -202,6 +202,11 @@
llvm::OwningPtr<ExternalASTSource> ExternalSource;
clang::PrintingPolicy PrintingPolicy;
+ // Typedefs which may be provided defining the structure of Objective-C
+ // pseudo-builtins
+ QualType ObjCIdRedefinitionType;
+ QualType ObjCClassRedefinitionType;
+
/// \brief Source ranges for all of the comments in the source file,
/// sorted in order of appearance in the translation unit.
std::vector<SourceRange> Comments;
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Aug 17 11:35:33 2009
@@ -43,6 +43,8 @@
LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
+ ObjCIdRedefinitionType = QualType();
+ ObjCClassRedefinitionType = QualType();
if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this);
InitBuiltinTypes();
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Mon Aug 17 11:35:33 2009
@@ -53,6 +53,7 @@
const llvm::PointerType *PtrToInt8Ty;
const llvm::FunctionType *IMPTy;
const llvm::PointerType *IdTy;
+ QualType ASTIdTy;
const llvm::IntegerType *IntTy;
const llvm::PointerType *PtrTy;
const llvm::IntegerType *LongTy;
@@ -226,8 +227,8 @@
PtrTy = PtrToInt8Ty;
// Object type
- IdTy = cast<llvm::PointerType>(
- CGM.getTypes().ConvertType(CGM.getContext().getObjCIdType()));
+ ASTIdTy = CGM.getContext().getObjCIdType();
+ IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
// IMP type
std::vector<const llvm::Type*> IMPArgs;
@@ -257,8 +258,8 @@
llvm::GlobalAlias *&US = UntypedSelectors[Sel.getAsString()];
if (US == 0)
US = new llvm::GlobalAlias(llvm::PointerType::getUnqual(SelectorTy),
- llvm::GlobalValue::InternalLinkage,
- ".objc_untyped_selector_alias",
+ llvm::GlobalValue::PrivateLinkage,
+ ".objc_untyped_selector_alias"+Sel.getAsString(),
NULL, &TheModule);
return Builder.CreateLoad(US);
@@ -282,7 +283,7 @@
// If it isn't, cache it.
llvm::GlobalAlias *Sel = new llvm::GlobalAlias(
llvm::PointerType::getUnqual(SelectorTy),
- llvm::GlobalValue::InternalLinkage, SelName,
+ llvm::GlobalValue::PrivateLinkage, ".objc_selector_alias" + SelName,
NULL, &TheModule);
TypedSelectors[Selector] = Sel;
@@ -348,8 +349,8 @@
CallArgList ActualArgs;
ActualArgs.push_back(
- std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
- CGF.getContext().getObjCIdType()));
+ std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
+ ASTIdTy));
ActualArgs.push_back(std::make_pair(RValue::get(cmd),
CGF.getContext().getObjCSelType()));
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
@@ -436,6 +437,7 @@
bool IsClassMessage,
const CallArgList &CallArgs,
const ObjCMethodDecl *Method) {
+ IdTy = cast<llvm::PointerType>(CGM.getTypes().ConvertType(ASTIdTy));
llvm::Value *cmd;
if (Method)
cmd = GetSelector(CGF.Builder, Method);
@@ -444,8 +446,7 @@
CallArgList ActualArgs;
ActualArgs.push_back(
- std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)),
- CGF.getContext().getObjCIdType()));
+ std::make_pair(RValue::get(CGF.Builder.CreateBitCast(Receiver, IdTy)), ASTIdTy));
ActualArgs.push_back(std::make_pair(RValue::get(cmd),
CGF.getContext().getObjCSelType()));
ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end());
@@ -495,6 +496,8 @@
const llvm::SmallVectorImpl<Selector> &MethodSels,
const llvm::SmallVectorImpl<llvm::Constant *> &MethodTypes,
bool isClassMethodList) {
+ if (MethodSels.empty())
+ return NULLPtr;
// Get the method structure type.
llvm::StructType *ObjCMethodTy = llvm::StructType::get(VMContext,
PtrToInt8Ty, // Really a selector, but the runtime creates it us.
@@ -1257,7 +1260,7 @@
ASTContext &Ctx = CGM.getContext();
// void objc_enumerationMutation (id)
llvm::SmallVector<QualType,16> Params;
- Params.push_back(Ctx.getObjCIdType());
+ Params.push_back(ASTIdTy);
const llvm::FunctionType *FTy =
Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params), false);
return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation");
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Aug 17 11:35:33 2009
@@ -159,6 +159,7 @@
);
PushOnScopeChains(IdTypedef, TUScope);
Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
+ Context.ObjCIdRedefinitionType = Context.getObjCIdType();
}
// Create the built-in typedef for 'Class'.
if (Context.getObjCClassType().isNull()) {
@@ -169,6 +170,7 @@
);
PushOnScopeChains(ClassTypedef, TUScope);
Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
+ Context.ObjCClassRedefinitionType = Context.getObjCClassType();
}
}
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Aug 17 11:35:33 2009
@@ -1257,7 +1257,7 @@
/// * taking the address of an array element where the array is on the stack
static DeclRefExpr* EvalAddr(Expr *E) {
// We should only be called for evaluating pointer expressions.
- assert((E->getType()->isPointerType() ||
+ assert((E->getType()->isAnyPointerType() ||
E->getType()->isBlockPointerType() ||
E->getType()->isObjCQualifiedIdType()) &&
"EvalAddr only works on pointers");
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Aug 17 11:35:33 2009
@@ -534,12 +534,14 @@
case 2:
if (!TypeID->isStr("id"))
break;
+ Context.ObjCIdRedefinitionType = New->getUnderlyingType();
// Install the built-in type for 'id', ignoring the current definition.
New->setTypeForDecl(Context.getObjCIdType().getTypePtr());
return;
case 5:
if (!TypeID->isStr("Class"))
break;
+ Context.ObjCClassRedefinitionType = New->getUnderlyingType();
// Install the built-in type for 'Class', ignoring the current definition.
New->setTypeForDecl(Context.getObjCClassType().getTypePtr());
return;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=79248&r1=79247&r2=79248&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 17 11:35:33 2009
@@ -26,6 +26,7 @@
#include "clang/Parse/Scope.h"
using namespace clang;
+
/// \brief Determine whether the use of this declaration is valid, and
/// emit any corresponding diagnostics.
///
@@ -2127,6 +2128,20 @@
DefaultFunctionArrayConversion(BaseExpr);
QualType BaseType = BaseExpr->getType();
+ // If this is an Objective-C pseudo-builtin and a definition is provided then
+ // use that.
+ if (BaseType->isObjCIdType()) {
+ // We have an 'id' type. Rather than fall through, we check if this
+ // is a reference to 'isa'.
+ if (BaseType != Context.ObjCIdRedefinitionType) {
+ BaseType = Context.ObjCIdRedefinitionType;
+ ImpCastExprToType(BaseExpr, BaseType);
+ }
+ } else if (BaseType->isObjCClassType() &&
+ BaseType != Context.ObjCClassRedefinitionType) {
+ BaseType = Context.ObjCClassRedefinitionType;
+ ImpCastExprToType(BaseExpr, BaseType);
+ }
assert(!BaseType.isNull() && "no type for member expression");
// Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
@@ -2402,11 +2417,6 @@
<< IDecl->getDeclName() << &Member
<< BaseExpr->getSourceRange());
}
- // We have an 'id' type. Rather than fall through, we check if this
- // is a reference to 'isa'.
- if (Member.isStr("isa"))
- return Owned(new (Context) ObjCIsaExpr(BaseExpr, true, MemberLoc,
- Context.getObjCIdType()));
}
// Handle properties on 'id' and qualified "id".
if (OpKind == tok::period && (BaseType->isObjCIdType() ||
@@ -3266,6 +3276,30 @@
ImpCastExprToType(LHS, RHSTy); // promote the null to a pointer.
return RHSTy;
}
+ // Handle things like Class and struct objc_class*. Here we case the result
+ // to the pseudo-builtin, because that will be implicitly cast back to the
+ // redefinition type if an attempt is made to access its fields.
+ if (LHSTy->isObjCClassType() &&
+ (RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
+ ImpCastExprToType(RHS, LHSTy);
+ return LHSTy;
+ }
+ if (RHSTy->isObjCClassType() &&
+ (LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
+ ImpCastExprToType(LHS, RHSTy);
+ return RHSTy;
+ }
+ // And the same for struct objc_object* / id
+ if (LHSTy->isObjCIdType() &&
+ (RHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
+ ImpCastExprToType(RHS, LHSTy);
+ return LHSTy;
+ }
+ if (RHSTy->isObjCIdType() &&
+ (LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
+ ImpCastExprToType(LHS, RHSTy);
+ return RHSTy;
+ }
// Handle block pointer types.
if (LHSTy->isBlockPointerType() || RHSTy->isBlockPointerType()) {
if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
@@ -3484,6 +3518,13 @@
Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
QualType lhptee, rhptee;
+ if ((lhsType->isObjCClassType() &&
+ (rhsType.getDesugaredType() == Context.ObjCClassRedefinitionType)) ||
+ (rhsType->isObjCClassType() &&
+ (lhsType.getDesugaredType() == Context.ObjCClassRedefinitionType))) {
+ return Compatible;
+ }
+
// get the "pointed to" type (ignoring qualifiers at the top level)
lhptee = lhsType->getAs<PointerType>()->getPointeeType();
rhptee = rhsType->getAs<PointerType>()->getPointeeType();
@@ -3607,6 +3648,13 @@
if (lhsType == rhsType)
return Compatible; // Common case: fast path an exact match.
+ if ((lhsType->isObjCClassType() &&
+ (rhsType.getDesugaredType() == Context.ObjCClassRedefinitionType)) ||
+ (rhsType->isObjCClassType() &&
+ (lhsType.getDesugaredType() == Context.ObjCClassRedefinitionType))) {
+ return Compatible;
+ }
+
// If the left-hand side is a reference type, then we are in a
// (rare!) case where we've allowed the use of references in C,
// e.g., as a parameter type in a built-in function. In this case,
More information about the cfe-commits
mailing list