aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-07-13 05:13:43 +0000
committerChris Lattner <sabre@nondot.org>2007-07-13 05:13:43 +0000
commit88a69ad80e1550e9932666e6efa050a5b1223889 (patch)
tree285b66d3e3590e4b453b66d34332f35a3e567d39
parentfa7c64562d0bf0c9014f0b733a9eaad139c72484 (diff)
implement support for basic codegen of global variables with no initializers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39795 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--CodeGen/CGDecl.cpp1
-rw-r--r--CodeGen/CodeGenModule.cpp35
-rw-r--r--CodeGen/CodeGenModule.h4
-rw-r--r--CodeGen/ModuleBuilder.cpp6
-rw-r--r--Driver/LLVMCodegen.cpp8
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h4
6 files changed, 52 insertions, 6 deletions
diff --git a/CodeGen/CGDecl.cpp b/CodeGen/CGDecl.cpp
index 1cce124a82..d86f305151 100644
--- a/CodeGen/CGDecl.cpp
+++ b/CodeGen/CGDecl.cpp
@@ -19,7 +19,6 @@ using namespace CodeGen;
void CodeGenFunction::EmitDecl(const Decl &D) {
-
switch (D.getKind()) {
default: assert(0 && "Unknown decl kind!");
case Decl::FileVariable:
diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp
index cdc3e63026..b610d3eb27 100644
--- a/CodeGen/CodeGenModule.cpp
+++ b/CodeGen/CodeGenModule.cpp
@@ -48,12 +48,45 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalDecl(const Decl *D) {
0, D->getName(), &getModule());
}
-void CodeGenModule::EmitFunction(FunctionDecl *FD) {
+void CodeGenModule::EmitFunction(const FunctionDecl *FD) {
// If this is not a prototype, emit the body.
if (FD->getBody())
CodeGenFunction(*this).GenerateCode(FD);
}
+void CodeGenModule::EmitGlobalVar(const FileVarDecl *D) {
+ llvm::GlobalVariable *GV = cast<llvm::GlobalVariable>(GetAddrOfGlobalDecl(D));
+
+ // If the storage class is external and there is no initializer, just leave it
+ // as a declaration.
+ if (D->getStorageClass() == VarDecl::Extern && D->getInit() == 0)
+ return;
+
+ // Otherwise, convert the initializer, or use zero if appropriate.
+ llvm::Constant *Init;
+ if (D->getInit() == 0)
+ Init = llvm::Constant::getNullValue(GV->getType()->getElementType());
+ else
+ assert(D->getInit() == 0 && "FIXME: Global variable initializers unimp!");
+
+ GV->setInitializer(Init);
+
+ // Set the llvm linkage type as appropriate.
+ // FIXME: This isn't right. This should handle common linkage and other
+ // stuff.
+ switch (D->getStorageClass()) {
+ case VarDecl::Auto:
+ case VarDecl::Register:
+ assert(0 && "Can't have auto or register globals");
+ case VarDecl::None:
+ case VarDecl::Extern:
+ // todo: common
+ break;
+ case VarDecl::Static:
+ GV->setLinkage(llvm::GlobalVariable::InternalLinkage);
+ break;
+ }
+}
llvm::Function *CodeGenModule::getMemCpyFn() {
diff --git a/CodeGen/CodeGenModule.h b/CodeGen/CodeGenModule.h
index 885fb97a9f..9d8547030e 100644
--- a/CodeGen/CodeGenModule.h
+++ b/CodeGen/CodeGenModule.h
@@ -27,6 +27,7 @@ namespace clang {
class ASTContext;
class FunctionDecl;
class Decl;
+ class FileVarDecl;
namespace CodeGen {
@@ -50,7 +51,8 @@ public:
llvm::Function *getMemCpyFn();
- void EmitFunction(FunctionDecl *FD);
+ void EmitFunction(const FunctionDecl *FD);
+ void EmitGlobalVar(const FileVarDecl *D);
void PrintStats() {}
};
diff --git a/CodeGen/ModuleBuilder.cpp b/CodeGen/ModuleBuilder.cpp
index 16b13d1c4d..e525514df5 100644
--- a/CodeGen/ModuleBuilder.cpp
+++ b/CodeGen/ModuleBuilder.cpp
@@ -32,6 +32,12 @@ void clang::CodeGen::CodeGenFunction(BuilderTy *B, FunctionDecl *D) {
static_cast<CodeGenModule*>(B)->EmitFunction(D);
}
+/// CodeGenGlobalVar - Emit the specified global variable to LLVM.
+void clang::CodeGen::CodeGenGlobalVar(BuilderTy *Builder, FileVarDecl *D) {
+ static_cast<CodeGenModule*>(Builder)->EmitGlobalVar(D);
+}
+
+
/// PrintStats - Emit statistic information to stderr.
///
void clang::CodeGen::PrintStats(BuilderTy *B) {
diff --git a/Driver/LLVMCodegen.cpp b/Driver/LLVMCodegen.cpp
index e593b66cfd..b969ff81ca 100644
--- a/Driver/LLVMCodegen.cpp
+++ b/Driver/LLVMCodegen.cpp
@@ -45,10 +45,12 @@ void clang::EmitLLVMFromASTs(Preprocessor &PP, unsigned MainFileID,
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
CodeGen::CodeGenFunction(Builder, FD);
- } else if (isa<TypedefDecl>(D)) {
- std::cerr << "Read top-level typedef decl: '" << D->getName() << "'\n";
+ } else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
+ CodeGen::CodeGenGlobalVar(Builder, FVD);
} else {
- std::cerr << "Read top-level variable decl: '" << D->getName() << "'\n";
+ assert(isa<TypedefDecl>(D) && "Only expected typedefs here");
+ // don't codegen for now, eventually pass down for debug info.
+ //std::cerr << "Read top-level typedef decl: '" << D->getName() << "'\n";
}
}
diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h
index e9cb2b5bd4..0b1ae476ed 100644
--- a/include/clang/CodeGen/ModuleBuilder.h
+++ b/include/clang/CodeGen/ModuleBuilder.h
@@ -21,6 +21,7 @@ namespace llvm {
namespace clang {
class ASTContext;
class FunctionDecl;
+ class FileVarDecl;
namespace CodeGen {
/// BuilderTy - This is an opaque type used to reference ModuleBuilder
@@ -34,6 +35,9 @@ namespace CodeGen {
///
void CodeGenFunction(BuilderTy *Builder, FunctionDecl *D);
+ /// CodeGenGlobalVar - Emit the specified global variable to LLVM.
+ void CodeGenGlobalVar(BuilderTy *Builder, FileVarDecl *D);
+
/// PrintStats - Emit statistic information to stderr.
///
void PrintStats(BuilderTy *Builder);