]> granicus.if.org Git - clang/commitdiff
implement support for basic codegen of global variables with no initializers.
authorChris Lattner <sabre@nondot.org>
Fri, 13 Jul 2007 05:13:43 +0000 (05:13 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 13 Jul 2007 05:13:43 +0000 (05:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39795 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGDecl.cpp
CodeGen/CodeGenModule.cpp
CodeGen/CodeGenModule.h
CodeGen/ModuleBuilder.cpp
Driver/LLVMCodegen.cpp
include/clang/CodeGen/ModuleBuilder.h

index 1cce124a8290c40299be3d4f058fd0358222c9c1..d86f305151ecfe41de362f0be0ed594b91543f96 100644 (file)
@@ -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:
index cdc3e63026dfcba9800808ddc58a2dbc64daecc8..b610d3eb27ef62c252ce340cb8b03fb40dfb5c86 100644 (file)
@@ -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() {
index 885fb97a9f55ec6757f223288bac3bce460f36df..9d8547030ec79610e021c29fdafe442752d37017 100644 (file)
@@ -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() {}
 };
index 16b13d1c4dd8010c42d55f89c783e29069f86420..e525514df52181adbd6eb047c40dd8d47f05b257 100644 (file)
@@ -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) {
index e593b66cfde54b61ad627e41e36bbf6496483223..b969ff81cad659ba7c2d7971e11206f7d0d6d981 100644 (file)
@@ -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";
     }
   }
   
index e9cb2b5bd41be0aa4de6189e0d150a8b70147f55..0b1ae476ed46b11bd1b3eb8d7c8b07c3bd8b97b0 100644 (file)
@@ -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);