[cfe-commits] r39652 - in /cfe/cfe/trunk: AST/Decl.cpp CodeGen/CGDecl.cpp CodeGen/CGExpr.cpp CodeGen/CodeGenFunction.cpp CodeGen/CodeGenFunction.h Lex/Preprocessor.cpp Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h

clattner at cs.uiuc.edu clattner at cs.uiuc.edu
Wed Jul 11 09:46:41 PDT 2007


Author: clattner
Date: Wed Jul 11 11:46:40 2007
New Revision: 39652

URL: http://llvm.org/viewvc/llvm-project?rev=39652&view=rev
Log:
Implement support for formal arguments.  We can now compile this:

int test(int X, short Y, float Z) {
  return (int)(X*Y+Z);
}

to:

define i32 @test(i32 %X, i16 %Y, float %Z) {
entry:
        %promote = sext i16 %Y to i32           ; <i32> [#uses=1]
        %mul = mul i32 %promote, %X             ; <i32> [#uses=1]
        %promote3 = sitofp i32 %mul to float            ; <float> [#uses=1]
        %add = add float %promote3, %Z          ; <float> [#uses=1]
        %conv = fptosi float %add to i32                ; <i32> [#uses=1]
        ret i32 %conv
}

with:

$ clang -emit-llvm t.c | llvm-as | opt -std-compile-opts | llvm-dis

Modified:
    cfe/cfe/trunk/AST/Decl.cpp
    cfe/cfe/trunk/CodeGen/CGDecl.cpp
    cfe/cfe/trunk/CodeGen/CGExpr.cpp
    cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
    cfe/cfe/trunk/CodeGen/CodeGenFunction.h
    cfe/cfe/trunk/Lex/Preprocessor.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/include/clang/AST/Decl.h

Modified: cfe/cfe/trunk/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Decl.cpp?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Decl.cpp (original)
+++ cfe/cfe/trunk/AST/Decl.cpp Wed Jul 11 11:46:40 2007
@@ -124,14 +124,14 @@
   return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
 }
 
-void FunctionDecl::setParams(VarDecl **NewParamInfo, unsigned NumParams) {
+void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) {
   assert(ParamInfo == 0 && "Already has param info!");
   assert(NumParams == getNumParams() && "Parameter count mismatch!");
   
   // Zero params -> null pointer.
   if (NumParams) {
-    ParamInfo = new VarDecl*[NumParams];
-    memcpy(ParamInfo, NewParamInfo, sizeof(VarDecl*)*NumParams);
+    ParamInfo = new ParmVarDecl*[NumParams];
+    memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams);
   }
 }
 

Modified: cfe/cfe/trunk/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGDecl.cpp?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CGDecl.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGDecl.cpp Wed Jul 11 11:46:40 2007
@@ -13,9 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "clang/AST/AST.h"
-//#include "llvm/Constants.h"
-//#include "llvm/DerivedTypes.h"
-//#include "llvm/Function.h"
+#include "llvm/Type.h"
 using namespace llvm;
 using namespace clang;
 using namespace CodeGen;
@@ -89,3 +87,37 @@
   
   // FIXME: Evaluate initializer.
 }
+
+/// Emit an alloca for the specified parameter and set up LocalDeclMap.
+void CodeGenFunction::EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg) {
+  QualType Ty = D.getCanonicalType();
+  
+  llvm::Value *DeclPtr;
+  if (!Ty->isConstantSizeType()) {
+    // Variable sized values always are passed by-reference.
+    DeclPtr = Arg;
+    Arg->setName(DeclPtr->getName());
+  } else {
+    // A fixed sized first class variable becomes an alloca in the entry block.
+    const llvm::Type *LTy = ConvertType(Ty, D.getLocation());
+    if (LTy->isFirstClassType()) {
+      // TODO: Alignment
+      DeclPtr = new AllocaInst(LTy, 0, 
+                               std::string(D.getName())+".addr",AllocaInsertPt);
+      
+      // Store the initial value into the alloca.
+      Builder.CreateStore(Arg, DeclPtr);
+
+      Arg->setName(D.getName());
+    } else {
+      // Otherwise, if this is an aggregate, just use the input pointer.
+      DeclPtr = Arg;
+      Arg->setName(DeclPtr->getName());
+    }
+  }
+
+  llvm::Value *&DMEntry = LocalDeclMap[&D];
+  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  DMEntry = DeclPtr;
+}
+

Modified: cfe/cfe/trunk/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CGExpr.cpp?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CGExpr.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CGExpr.cpp Wed Jul 11 11:46:40 2007
@@ -258,7 +258,7 @@
 
 LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
   const Decl *D = E->getDecl();
-  if (isa<BlockVarDecl>(D)) {
+  if (isa<BlockVarDecl>(D) || isa<ParmVarDecl>(D)) {
     Value *V = LocalDeclMap[D];
     assert(V && "BlockVarDecl not entered in LocalDeclMap?");
     return LValue::getAddr(V);

Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.cpp Wed Jul 11 11:46:40 2007
@@ -141,11 +141,16 @@
   return OpaqueType::get();
 }
 
-void  CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP, 
-                                           std::vector<const llvm::Type*> &
-                                           ArgTys, SourceLocation Loc) {
-  for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i)
-    ArgTys.push_back(ConvertType(FTP.getArgType(i), Loc));
+void CodeGenFunction::DecodeArgumentTypes(const FunctionTypeProto &FTP, 
+                                          std::vector<const llvm::Type*> &
+                                          ArgTys, SourceLocation Loc) {
+  for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
+    const llvm::Type *Ty = ConvertType(FTP.getArgType(i), Loc);
+    if (Ty->isFirstClassType())
+      ArgTys.push_back(Ty);
+    else
+      ArgTys.push_back(llvm::PointerType::get(Ty));
+  }
 }
 
 void CodeGenFunction::GenerateCode(const FunctionDecl *FD) {
@@ -155,14 +160,14 @@
   const llvm::FunctionType *Ty = 
     cast<llvm::FunctionType>(ConvertType(FD->getType(), FD->getLocation()));
   
+  // FIXME: param attributes for sext/zext etc.
+  
   CurFuncDecl = FD;
   CurFn = new Function(Ty, Function::ExternalLinkage,
                        FD->getName(), &CGM.getModule());
   
   BasicBlock *EntryBB = new BasicBlock("entry", CurFn);
   
-  // TODO: Walk the decls, creating allocas etc.
-  
   Builder.SetInsertPoint(EntryBB);
 
   // Create a marker to make it easy to insert allocas into the entryblock
@@ -170,7 +175,12 @@
   AllocaInsertPt = Builder.CreateBitCast(UndefValue::get(llvm::Type::Int32Ty),
                                          llvm::Type::Int32Ty, "allocapt");
   
-  // TODO: handle params. 
+  // Emit allocs for param decls. 
+  llvm::Function::arg_iterator AI = CurFn->arg_begin();
+  for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i, ++AI) {
+    assert(AI != CurFn->arg_end() && "Argument mismatch!");
+    EmitParmDecl(*FD->getParamDecl(i), AI);
+  }
   
   // Emit the function body.
   EmitStmt(FD->getBody());

Modified: cfe/cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/CodeGen/CodeGenFunction.h?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/cfe/trunk/CodeGen/CodeGenFunction.h Wed Jul 11 11:46:40 2007
@@ -51,6 +51,7 @@
   
   class BlockVarDecl;
   class EnumConstantDecl;
+  class ParmVarDecl;
 namespace CodeGen {
   class CodeGenModule;
   
@@ -177,13 +178,14 @@
   Value *ConvertScalarValueToBool(RValue Val, QualType Ty);
   
   //===--------------------------------------------------------------------===//
-  //                        Local Declaration Emission
+  //                            Declaration Emission
   //===--------------------------------------------------------------------===//
   
   void EmitDecl(const Decl &D);
   void EmitEnumConstantDecl(const EnumConstantDecl &D);
   void EmitBlockVarDecl(const BlockVarDecl &D);
   void EmitLocalBlockVarDecl(const BlockVarDecl &D);
+  void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
   
   //===--------------------------------------------------------------------===//
   //                             Statement Emission

Modified: cfe/cfe/trunk/Lex/Preprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/Preprocessor.cpp?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/Lex/Preprocessor.cpp (original)
+++ cfe/cfe/trunk/Lex/Preprocessor.cpp Wed Jul 11 11:46:40 2007
@@ -971,8 +971,8 @@
   // If this is an extension token, diagnose its use.
   // FIXME: tried (unsuccesfully) to shut this up when compiling with gnu99
   // For now, I'm just commenting it out (while I work on attributes).
-  //if (II.isExtensionToken() && Features.C99) 
-  //  Diag(Identifier, diag::ext_token_used);
+  if (II.isExtensionToken() && Features.C99) 
+    Diag(Identifier, diag::ext_token_used);
 }
 
 /// HandleEndOfFile - This callback is invoked when the lexer hits the end of

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:46:40 2007
@@ -27,6 +27,7 @@
   class Decl;
   class Expr;
   class VarDecl;
+  class ParmVarDecl;
   class TypedefDecl;
   class FunctionDecl;
   class QualType;
@@ -132,8 +133,8 @@
   void AddTopLevelDecl(Decl *current, Decl *last);
 
   /// More parsing and symbol table subroutines...
-  VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
-                                Scope *FnBodyScope);
+  ParmVarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
+                                    Scope *FnBodyScope);
   Decl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI, SourceLocation IdLoc,
                          Scope *S);  
   Decl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Scope *S);

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:46:40 2007
@@ -439,7 +439,7 @@
   return NewGroup;
 }
   
-VarDecl *
+ParmVarDecl *
 Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
                            Scope *FnScope) {
   const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
@@ -455,9 +455,9 @@
   
   // FIXME: Handle storage class (auto, register). No declarator?
   // TODO: Chain to previous parameter with the prevdeclarator chain?
-  VarDecl *New = new ParmVarDecl(PI.IdentLoc, II, 
-                                 QualType::getFromOpaquePtr(PI.TypeInfo), 
-                                 VarDecl::None, 0);
+  ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II, 
+                                     QualType::getFromOpaquePtr(PI.TypeInfo), 
+                                     VarDecl::None, 0);
 
   // If this has an identifier, add it to the scope stack.
   if (II) {
@@ -504,7 +504,7 @@
   CurFunctionDecl = FD;
   
   // Create Decl objects for each parameter, adding them to the FunctionDecl.
-  SmallVector<VarDecl*, 16> Params;
+  SmallVector<ParmVarDecl*, 16> Params;
   
   // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs function that takes
   // no arguments, not a function that takes a single void argument.

Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=39652&r1=39651&r2=39652&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:46:40 2007
@@ -220,11 +220,15 @@
   void setDeclChain(Decl *D) { DeclChain = D; }
 
   unsigned getNumParams() const;
-  VarDecl *getParamDecl(unsigned i) const {
+  const ParmVarDecl *getParamDecl(unsigned i) const {
     assert(i < getNumParams() && "Illegal param #");
     return ParamInfo[i];
   }
-  void setParams(VarDecl **NewParamInfo, unsigned NumParams);
+  ParmVarDecl *getParamDecl(unsigned i) {
+    assert(i < getNumParams() && "Illegal param #");
+    return ParamInfo[i];
+  }
+  void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
 
   QualType getResultType() const { 
     return cast<FunctionType>(getType())->getResultType();
@@ -239,7 +243,7 @@
   /// parameters of this function.  This is null if a prototype or if there are
   /// no formals.  TODO: we could allocate this space immediately after the
   /// FunctionDecl object to save an allocation like FunctionType does.
-  VarDecl **ParamInfo;
+  ParmVarDecl **ParamInfo;
   
   Stmt *Body;  // Null if a prototype.
   





More information about the cfe-commits mailing list