[cfe-dev] Objective-C: methods, ivars, and cleanup

Chris Lattner clattner at apple.com
Wed Mar 26 11:29:47 PDT 2008


>>> +  assert(!verifyFunction(*CurFn));
>>
>> nit-pick, add a message here.
>
> That code was copied-and-pasted from the GenerateCode method used  
> for generating functions.  For completeness I've added a message in  
> to where I originally copied it from as well.

Hi David,

Some more minor nit-picky stuff (this is why small patches are better  
than big ones ;-):

+++ lib/CodeGen/CGObjCGNU.cpp	(working copy)

+#include <stdarg.h>

Use <cstdarg> and move it to the end of the #include list if it is  
needed.

+  llvm::Value *GenerateIvarList(llvm::LLVMFoldingBuilder &Builder,
+      std::vector<llvm::Constant*> MethodNames,
+      std::vector<llvm::Constant*> MethodTypes,
+      std::vector<llvm::Constant*> MethodIMPs);

You're passing these vectors by value, I'd suggest passing them by  
(const) reference unless you really really want a copy made.  likewise  
in a few other places.

+  // Get the selector Type.
+  std::vector<const llvm::Type*> Str2(2, PtrToInt8Ty);
+  const llvm::Type *SelStructTy = llvm::StructType::get(Str2);

Please use the variadic version of STructType::get to avoid the vector.


+  // C string type.  Used in lots of places.
+  PtrToInt8Ty =
+    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
+  // Get the selector Type.
+  std::vector<const llvm::Type*> Str2(2, PtrToInt8Ty);
+  const llvm::Type *SelStructTy = llvm::StructType::get(Str2);
+  SelectorTy = llvm::PointerType::getUnqual(SelStructTy);
+  PtrToIntTy = llvm::PointerType::getUnqual(IntTy);
+  PtrTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

You call PointerType::getUnqual(llvm::Type::Int8Ty) twice here, please  
eliminate one.


+  // Object type
+  llvm::OpaqueType *OpaqueObjTy = llvm::OpaqueType::get();
+  llvm::Type *OpaqueIdTy = llvm::PointerType::getUnqual(OpaqueObjTy);
+  IdTy =  
llvm::PointerType::getUnqual(llvm::StructType::get(OpaqueIdTy, NULL));
+  OpaqueObjTy->refineAbstractTypeTo(IdTy);

This code is unsafe, you need to use a PATypeHolder as described here:
http://llvm.org/docs/ProgrammersManual.html#TypeResolve

Likewise in GenerateMethodList and other places you use  
refineAbstractTypeTo


+static void SetField(llvm::LLVMFoldingBuilder &Builder,
+                     llvm::Value *Structure,
+                     unsigned Index,
+                     llvm::Value *Value) {
+    llvm::Value *element_ptr = Builder.CreateStructGEP(Structure,  
Index);
+    Builder.CreateStore(Value, element_ptr);


Nice, much better than a macro ;-) ;-).  Please only indent the body  
by 2, not 4 though.  Also, you could just use:

+    Builder.CreateStore(Value, Builder.CreateStructGEP(Structure,  
Index));

at which point it might make more sense to just inline this everywhere  
it is used.


+  if(SelTypes == 0) {
+    llvm::Constant *SelFunction =
+      TheModule.getOrInsertFunction("sel_get_uid", SelectorTy,  
PtrToInt8Ty, NULL);
+    cmd = Builder.CreateCall(SelFunction, SelName);

80 cols.

+    llvm::SmallVector<llvm::Value*, 2> Args;
+    Args.push_back(SelName);
+    Args.push_back(SelTypes);
+    cmd = Builder.CreateCall(SelFunction, Args.begin(), Args.end());

There is no need to use a SmallVector when the size is fixed, I'd just  
use:

    llvm::Value *Args[] = { SelName, SelTypes };
    cmd = Builder.CreateCall(SelFunction, Args, Args+2);


+  for(unsigned int i=0 ; i<1 ; i++) {

urr?  A single iteration loop?



+  std::vector<const llvm::Type*> Args;
+  Args.push_back(SelfTy);
+  Args.push_back(SelectorTy);
+  for (unsigned i=0; i<ArgC ; i++) {
+    Args.push_back(ArgTy[i]);
+  }

Instead of the loop, you can use:

+  Args.insert(Args.end(), ArgTy, ArgTy+ArgC);


+  llvm::FunctionType *MethodTy = llvm::FunctionType::get(ReturnTy,  
Args, isVarArg);

80 cols



+  FnRetTy = OMD->getResultType(); ///.getCanonicalType();

Please remove this comment or improve it.


+  FnRetTy = CurFuncDecl->getType().getCanonicalType();
+  FnRetTy = cast<FunctionType>(FnRetTy)->getResultType();


This would be more idiomatic to write as:

FnRetTy = CurFuncDecl->getType()->getAsFunctionType()->getResultType();




+Value *ScalarExprEmitter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {

A lot of this code will be independent of whether the IVar is a  
scalar, complex or aggregate.  I'd suggest moving the "get the address  
of an ivar" piece into CGObjC*.cpp and just have VisitObjCIvarRefExpr  
be a simple function which calls into the "form address" part and then  
just does a load.  This can be done as a follow on patch, but will be  
required to get Complex and aggregate (e.g. struct) ivars  
working.  ... actually, isn't this function just  
"EmitObjCIvarRefLValue" ?



@@ -341,6 +345,17 @@
        return LValue::MakeAddr(CGM.GetAddrOfGlobalVar(VD, false));
      else {
        llvm::Value *V = LocalDeclMap[D];
+      // Check if it's an implicit argument
+      // TODO: Other runtimes may set non-argument hidden variables
+      if (!V) {
+        std::string VarName(D->getName());
+        llvm::Function::arg_iterator AI = CurFn->arg_begin();
+        do {
+          if(VarName == AI->getName()) {
+            return LValue::MakeAddr(AI);
+          }
+        } while(++AI);
+      }
        assert(V && "BlockVarDecl not entered in LocalDeclMap?");

This is incredibly inefficient, what are you trying to accomplish  
here?  I'd suggest removing this and handling it as part of a follow- 
on patch.


-Chris






More information about the cfe-dev mailing list