diff options
-rw-r--r-- | clang/CodeGen/CodeGenFunction.cpp | 113 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenFunction.h | 13 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenModule.h | 4 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenTypes.cpp | 136 | ||||
-rw-r--r-- | clang/CodeGen/CodeGenTypes.h | 49 |
5 files changed, 194 insertions, 121 deletions
diff --git a/clang/CodeGen/CodeGenFunction.cpp b/clang/CodeGen/CodeGenFunction.cpp index 87900096df4..4dece886bec 100644 --- a/clang/CodeGen/CodeGenFunction.cpp +++ b/clang/CodeGen/CodeGenFunction.cpp @@ -23,7 +23,7 @@ using namespace clang; using namespace CodeGen; CodeGenFunction::CodeGenFunction(CodeGenModule &cgm) - : CGM(cgm), Target(CGM.getContext().Target) {} + : CGM(cgm), Target(CGM.getContext().Target), Types(Target) {} ASTContext &CodeGenFunction::getContext() const { return CGM.getContext(); @@ -39,117 +39,8 @@ llvm::BasicBlock *CodeGenFunction::getBasicBlockForLabel(const LabelStmt *S) { } -/// ConvertType - Convert the specified type to its LLVM form. const llvm::Type *CodeGenFunction::ConvertType(QualType T, SourceLocation Loc) { - // FIXME: Cache these, move the CodeGenModule, expand, etc. - const clang::Type &Ty = *T.getCanonicalType(); - - switch (Ty.getTypeClass()) { - case Type::Builtin: { - switch (cast<BuiltinType>(Ty).getKind()) { - case BuiltinType::Void: - // LLVM void type can only be used as the result of a function call. Just - // map to the same as char. - case BuiltinType::Char_S: - case BuiltinType::Char_U: - case BuiltinType::SChar: - case BuiltinType::UChar: - return llvm::IntegerType::get(Target.getCharWidth(Loc)); - - case BuiltinType::Bool: - // FIXME: This is very strange. We want scalars to be i1, but in memory - // they can be i1 or i32. Should the codegen handle this issue? - return llvm::Type::Int1Ty; - - case BuiltinType::Short: - case BuiltinType::UShort: - return llvm::IntegerType::get(Target.getShortWidth(Loc)); - - case BuiltinType::Int: - case BuiltinType::UInt: - return llvm::IntegerType::get(Target.getIntWidth(Loc)); - - case BuiltinType::Long: - case BuiltinType::ULong: - return llvm::IntegerType::get(Target.getLongWidth(Loc)); - - case BuiltinType::LongLong: - case BuiltinType::ULongLong: - return llvm::IntegerType::get(Target.getLongLongWidth(Loc)); - - case BuiltinType::Float: return llvm::Type::FloatTy; - case BuiltinType::Double: return llvm::Type::DoubleTy; - case BuiltinType::LongDouble: - case BuiltinType::FloatComplex: - case BuiltinType::DoubleComplex: - case BuiltinType::LongDoubleComplex: - ; - } - break; - } - case Type::Pointer: { - const PointerType &P = cast<PointerType>(Ty); - return llvm::PointerType::get(ConvertType(P.getPointeeType(), Loc)); - } - case Type::Reference: { - const ReferenceType &R = cast<ReferenceType>(Ty); - return llvm::PointerType::get(ConvertType(R.getReferenceeType(), Loc)); - } - - case Type::Array: { - const ArrayType &A = cast<ArrayType>(Ty); - assert(A.getSizeModifier() == ArrayType::Normal && - A.getIndexTypeQualifier() == 0 && - "FIXME: We only handle trivial array types so far!"); - // FIXME: are there any promotions etc here? - RValue Size = EmitExpr(A.getSize()); - assert(Size.isScalar() && isa<llvm::ConstantInt>(Size.getVal()) && - "FIXME: Only handle fixed-size arrays so far"); - const llvm::Type *EltTy = ConvertType(A.getElementType(), Loc); - return llvm::ArrayType::get(EltTy, - cast<llvm::ConstantInt>(Size.getVal())->getZExtValue()); - } - case Type::FunctionNoProto: - case Type::FunctionProto: { - const FunctionType &FP = cast<FunctionType>(Ty); - const llvm::Type *ResultType; - - if (FP.getResultType()->isVoidType()) - ResultType = llvm::Type::VoidTy; // Result of function uses llvm void. - else - ResultType = ConvertType(FP.getResultType(), Loc); - - // FIXME: Convert argument types. - bool isVarArg; - std::vector<const llvm::Type*> ArgTys; - if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) { - DecodeArgumentTypes(*FTP, ArgTys, Loc); - isVarArg = FTP->isVariadic(); - } else { - isVarArg = true; - } - - return llvm::FunctionType::get(ResultType, ArgTys, isVarArg, 0); - } - case Type::TypeName: - case Type::Tagged: - break; - } - - // FIXME: implement. - return llvm::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) { - const llvm::Type *Ty = ConvertType(FTP.getArgType(i), Loc); - if (Ty->isFirstClassType()) - ArgTys.push_back(Ty); - else - ArgTys.push_back(llvm::PointerType::get(Ty)); - } + return Types.ConvertType(T, Loc); } void CodeGenFunction::GenerateCode(const FunctionDecl *FD) { diff --git a/clang/CodeGen/CodeGenFunction.h b/clang/CodeGen/CodeGenFunction.h index b4123123c70..8897d04eb34 100644 --- a/clang/CodeGen/CodeGenFunction.h +++ b/clang/CodeGen/CodeGenFunction.h @@ -16,20 +16,16 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/Support/LLVMBuilder.h" -#include <vector> +#include "CodeGenTypes.h" namespace llvm { class Module; } namespace clang { - class SourceLocation; - class TargetInfo; class ASTContext; class Decl; class FunctionDecl; - class QualType; - class FunctionTypeProto; class Stmt; class CompoundStmt; @@ -125,6 +121,7 @@ class CodeGenFunction { CodeGenModule &CGM; // Per-module state. TargetInfo &Target; llvm::LLVMBuilder Builder; + CodeGenTypes Types; const FunctionDecl *CurFuncDecl; llvm::Function *CurFn; @@ -147,13 +144,9 @@ public: ASTContext &getContext() const; - const llvm::Type *ConvertType(QualType T, SourceLocation Loc); - void DecodeArgumentTypes(const FunctionTypeProto &FTP, - std::vector<const llvm::Type*> &ArgTys, - SourceLocation Loc); - void GenerateCode(const FunctionDecl *FD); + const llvm::Type *ConvertType(QualType T, SourceLocation Loc); /// getBasicBlockForLabel - Return the LLVM basicblock that the specified /// label maps to. diff --git a/clang/CodeGen/CodeGenModule.h b/clang/CodeGen/CodeGenModule.h index d58f90d2560..448d0f17f86 100644 --- a/clang/CodeGen/CodeGenModule.h +++ b/clang/CodeGen/CodeGenModule.h @@ -16,11 +16,13 @@ namespace llvm { class Module; + class Constant; } namespace clang { class ASTContext; class FunctionDecl; + class Decl; namespace CodeGen { @@ -29,6 +31,8 @@ namespace CodeGen { class CodeGenModule { ASTContext &Context; llvm::Module &TheModule; + + //llvm::DenseMap<const Decl*, llvm::Constant*> GlobalDeclMap; public: CodeGenModule(ASTContext &C, llvm::Module &M) : Context(C), TheModule(M) {} diff --git a/clang/CodeGen/CodeGenTypes.cpp b/clang/CodeGen/CodeGenTypes.cpp new file mode 100644 index 00000000000..330217ce6e7 --- /dev/null +++ b/clang/CodeGen/CodeGenTypes.cpp @@ -0,0 +1,136 @@ +//===--- CodeGenTypes.cpp - Type translation for LLVM CodeGen -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is the code that handles AST -> LLVM type lowering. +// +//===----------------------------------------------------------------------===// + +#include "CodeGenTypes.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/AST/AST.h" +#include "llvm/DerivedTypes.h" + +using namespace clang; +using namespace CodeGen; + + +/// ConvertType - Convert the specified type to its LLVM form. +const llvm::Type *CodeGenTypes::ConvertType(QualType T, SourceLocation Loc) { + // FIXME: Cache these, move the CodeGenModule, expand, etc. + const clang::Type &Ty = *T.getCanonicalType(); + + switch (Ty.getTypeClass()) { + case Type::Builtin: { + switch (cast<BuiltinType>(Ty).getKind()) { + case BuiltinType::Void: + // LLVM void type can only be used as the result of a function call. Just + // map to the same as char. + case BuiltinType::Char_S: + case BuiltinType::Char_U: + case BuiltinType::SChar: + case BuiltinType::UChar: + return llvm::IntegerType::get(Target.getCharWidth(Loc)); + + case BuiltinType::Bool: + // FIXME: This is very strange. We want scalars to be i1, but in memory + // they can be i1 or i32. Should the codegen handle this issue? + return llvm::Type::Int1Ty; + + case BuiltinType::Short: + case BuiltinType::UShort: + return llvm::IntegerType::get(Target.getShortWidth(Loc)); + + case BuiltinType::Int: + case BuiltinType::UInt: + return llvm::IntegerType::get(Target.getIntWidth(Loc)); + + case BuiltinType::Long: + case BuiltinType::ULong: + return llvm::IntegerType::get(Target.getLongWidth(Loc)); + + case BuiltinType::LongLong: + case BuiltinType::ULongLong: + return llvm::IntegerType::get(Target.getLongLongWidth(Loc)); + + case BuiltinType::Float: return llvm::Type::FloatTy; + case BuiltinType::Double: return llvm::Type::DoubleTy; + case BuiltinType::LongDouble: + case BuiltinType::FloatComplex: + case BuiltinType::DoubleComplex: + case BuiltinType::LongDoubleComplex: + ; + } + break; + } + case Type::Pointer: { + const PointerType &P = cast<PointerType>(Ty); + return llvm::PointerType::get(ConvertType(P.getPointeeType(), Loc)); + } + case Type::Reference: { + const ReferenceType &R = cast<ReferenceType>(Ty); + return llvm::PointerType::get(ConvertType(R.getReferenceeType(), Loc)); + } + + case Type::Array: { + const ArrayType &A = cast<ArrayType>(Ty); + assert(A.getSizeModifier() == ArrayType::Normal && + A.getIndexTypeQualifier() == 0 && + "FIXME: We only handle trivial array types so far!"); + + llvm::APSInt Size(32); + if (A.getSize()->isIntegerConstantExpr(Size)) { + const llvm::Type *EltTy = ConvertType(A.getElementType(), Loc); + return llvm::ArrayType::get(EltTy, Size.getZExtValue()); + } else { + assert(0 && "FIXME: VLAs not implemented yet!"); + } + } + case Type::FunctionNoProto: + case Type::FunctionProto: { + const FunctionType &FP = cast<FunctionType>(Ty); + const llvm::Type *ResultType; + + if (FP.getResultType()->isVoidType()) + ResultType = llvm::Type::VoidTy; // Result of function uses llvm void. + else + ResultType = ConvertType(FP.getResultType(), Loc); + + // FIXME: Convert argument types. + bool isVarArg; + std::vector<const llvm::Type*> ArgTys; + if (const FunctionTypeProto *FTP = dyn_cast<FunctionTypeProto>(&FP)) { + DecodeArgumentTypes(*FTP, ArgTys, Loc); + isVarArg = FTP->isVariadic(); + } else { + isVarArg = true; + } + + return llvm::FunctionType::get(ResultType, ArgTys, isVarArg, 0); + } + case Type::TypeName: + case Type::Tagged: + break; + } + + // FIXME: implement. + return llvm::OpaqueType::get(); +} + +void CodeGenTypes::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)); + } +} + diff --git a/clang/CodeGen/CodeGenTypes.h b/clang/CodeGen/CodeGenTypes.h new file mode 100644 index 00000000000..0a6551faa71 --- /dev/null +++ b/clang/CodeGen/CodeGenTypes.h @@ -0,0 +1,49 @@ +//===--- CodeGenTypes.h - Type translation for LLVM CodeGen -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Chris Lattner and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is the code that handles AST -> LLVM type lowering. +// +//===----------------------------------------------------------------------===// + +#ifndef CODEGEN_CODEGENTYPES_H +#define CODEGEN_CODEGENTYPES_H + +#include <vector> + +namespace llvm { + class Type; +} + +namespace clang { + class TargetInfo; + class QualType; + class SourceLocation; + class FunctionTypeProto; + +namespace CodeGen { + +/// CodeGenTypes - This class organizes the cross-module state that is used +/// while lowering AST types to LLVM types. +class CodeGenTypes { + TargetInfo &Target; + +public: + CodeGenTypes(TargetInfo &target) : Target(target) {} + + TargetInfo &getTarget() const { return Target; } + + const llvm::Type *ConvertType(QualType T, SourceLocation Loc); + void DecodeArgumentTypes(const FunctionTypeProto &FTP, + std::vector<const llvm::Type*> &ArgTys, + SourceLocation Loc); +}; +} // end namespace CodeGen +} // end namespace clang + +#endif |