[cfe-dev] Objective-C top-level constructs code generation
David Chisnall
csdavec at swansea.ac.uk
Wed May 28 13:26:31 PDT 2008
On 28 May 2008, at 17:27, Chris Lattner wrote:
> On May 28, 2008, at 8:56 AM, David Chisnall wrote:
>> Hi Devang,
>>
>> Thanks for the feedback. Here is a new version.
>
> Nice! This is looking good. A few more thoughts:
>
> +// Some zeros used for GEPs in lots of places.
> +static llvm::Constant *Zeros[] =
> {llvm::ConstantInt::get(llvm::Type::Int32Ty, 0),
> + llvm::ConstantInt::get(llvm::Type::Int32Ty, 0) };
> +static llvm::Constant *NULLPtr = llvm::ConstantPointerNull::get(
> + llvm::PointerType::getUnqual(llvm::Type::Int8Ty));
> +static llvm::Constant *ProtocolVersion =
> + llvm::ConstantInt::get(llvm::Type::Int32Ty, 2);
>
> This causes static initializers to be formed and run. Please stay
> away from them. Maybe these should be instance variables of the
> class?
Okay.
> + std::map<std::string, llvm::Constant*> ExistingProtocols;
> + typedef std::pair<std::string, std::string> TypedSelector;
> + std::map<TypedSelector, llvm::GlobalAlias*> TypedSelectors;
> + std::map<std::string, llvm::GlobalAlias*> UntypedSelectors;
>
> std::map's from std::string are really inefficient. Can you use
> StringMap for these?
Done for the two with string keys. I'm happy to accept suggestions
for a more efficient way of storing typed selectors (although clang
currently never uses that code path, so the inefficiency isn't
important).
> These:
> +static std::string SymbolNameForClass(std::string ClassName) {
> +static std::string SymbolNameForMethod(const std::string &ClassName,
> const
> + std::string CategoryName, const std::string MethodName, bool
> isClassMethod)
>
>
> Copy the std::string objects. Please pass as "const std::string &foo"
> to avoid this. Likewise in a few other places (e.g. MakeGlobal)
Done.
> + if (isClassMethod)
> + return "._objc_method_" + ClassName +"("+CategoryName+")"+ "+" +
> MethodName;
> + return "._objc_method_" + ClassName +"("+CategoryName+")"+ "-" +
> MethodName;
> +}
>
> How about something like:
> return "._objc_method_" + ClassName +"("+CategoryName+")"+
> (isClassMethod ? "+" : "-") + MethodName;
>
> To make it more obvious what the difference is between the two.
Yup, seems clearer.
> + if (ReturnTy->isSingleValueType() && ReturnTy !=
> llvm::Type::VoidTy) {
> + llvm::SmallVector<llvm::Value*, 16> Args;
> + Args.push_back(Receiver);
> + Args.push_back(cmd);
> + Args.insert(Args.end(), ArgV, ArgV+ArgC);
> + return Builder.CreateCall(imp, Args.begin(), Args.end());
> + } else {
> + llvm::SmallVector<llvm::Value*, 16> Args;
> + llvm::Value *Return = Builder.CreateAlloca(ReturnTy);
> + Args.push_back(Return);
> + Args.push_back(Receiver);
> + Args.push_back(cmd);
> + Args.insert(Args.end(), ArgV, ArgV+ArgC);
> + Builder.CreateCall(imp, Args.begin(), Args.end());
> + return Return;
> + }
>
> Is there a specific reason not to share the common code here?
Other than incompetence? No. Fixed.
> +void CGObjCGNU::GenerateProtocol(const char *ProtocolName,
>
> It would be nice to add a block comment above each of these methods
> with a C struct (in the comment) that describes the thing that you are
> generating. This would make it easier to follow the code.
I don't want to copy the structs directly from the runtime headers,
since the header is GPL'd (with a special exemption for code compiled
with GCC, but not for code compiled with LLVM) and, although you can't
copyright an interface, you can copyright a representation of an
interface (see AT&T Vs UCB). I've added a comment at the top of the
file pointing people in the right direction for finding the structures.
> + if (Classes.size() + Categories.size() + ConstantStrings.size() +
> + ExistingProtocols.size() + TypedSelectors.size() +
> + UntypedSelectors.size() == 0) {
>
> It is generally better to query .empty() instead of .size() if you
> just care about whether it is empty or not. Also, using "if
> (x.empty() && y.empty() && z.empty() ...)" is more idiomatic than
> using additions.
Fixed.
> + Elements.push_back(MakeConstantString((*iter).first.first,
> ".objc_sel_types"));
>
> Watch out for 80 columns.
Fixed.
> + const llvm::StructLayout *Layout =
> + TheTargetData.getStructLayout(llvm::cast<const
> llvm::StructType>(ObjTy));
>
>
> You don't need the llvm:: qualifier on cast, and you don't need
> 'const' in the type argument (the constness of the result follows the
> constness of the input). This should be enough:
>
> + const llvm::StructLayout *Layout =
> + TheTargetData.getStructLayout(cast<llvm::StructType>(ObjTy));
Done.
> +++ lib/CodeGen/ModuleBuilder.cpp (working copy)
> @@ -67,6 +67,24 @@
>
> if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
> Builder->EmitFunction(FD);
> + } else if (dyn_cast<ObjCClassDecl>(D)){
> + //Forward declaration. Only used for type checking.
>
> If you're not using the result of the dyn_cast, please use
> isa<ObjCClassDecl>(D) instead. Likewise for other cases in this file.
Fixed.
David
-------------- next part --------------
A non-text attachment was scrubbed...
Name: objc.diff
Type: application/octet-stream
Size: 61969 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20080528/8337f69f/attachment.obj>
-------------- next part --------------
More information about the cfe-dev
mailing list