[cfe-dev] Objective-C top-level constructs code generation
Chris Lattner
clattner at apple.com
Wed May 28 09:27:03 PDT 2008
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?
+ 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?
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)
+ 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.
+ 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?
+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.
+ 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.
+ Elements.push_back(MakeConstantString((*iter).first.first,
".objc_sel_types"));
Watch out for 80 columns.
+ 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));
+++ 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.
This is looking nice!
-Chris
More information about the cfe-dev
mailing list