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<[email protected]> 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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
