[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
Daniel Dunbar
daniel at zuster.org
Mon Aug 17 10:57:34 PDT 2009
David, please do not make commits which intentionally break a test.
Either make the test XFAIL, or fix it.
- Daniel
On Mon, Aug 17, 2009 at 9:35 AM, David Chisnall<csdavec at swan.ac.uk> wrote:
> 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,
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list