]> granicus.if.org Git - clang/commitdiff
Generate code for static variables that don't have initializers. Also, report an...
authorAnders Carlsson <andersca@mac.com>
Wed, 17 Oct 2007 00:52:43 +0000 (00:52 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 17 Oct 2007 00:52:43 +0000 (00:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43058 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Expr.cpp
CodeGen/CGDecl.cpp
CodeGen/CodeGenFunction.h
Sema/Sema.h
Sema/SemaDecl.cpp
test/Sema/static-init.c [new file with mode: 0644]

index 5cd56ccbaf13bba9e21b392e46338a9f944afb4e..1b989a4a61c352fb7e25479bc39499a335733827 100644 (file)
@@ -365,7 +365,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
   case IntegerLiteralClass:
   case CharacterLiteralClass:
   case ImaginaryLiteralClass:
-  case TypesCompatibleExprClass: 
+  case TypesCompatibleExprClass:
+  case CXXBoolLiteralExprClass:
     break;
   case CallExprClass: {
     const CallExpr *CE = cast<CallExpr>(this);
index 2af41272310e462edbcb1abf870cc1c6702202dd..75a32854ab5870c938939a0113606d903c68466f 100644 (file)
@@ -12,7 +12,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenFunction.h"
+#include "CodeGenModule.h"
 #include "clang/AST/AST.h"
+#include "llvm/GlobalVariable.h"
 #include "llvm/Type.h"
 using namespace clang;
 using namespace CodeGen;
@@ -50,7 +52,7 @@ void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
 void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
   switch (D.getStorageClass()) {
   case VarDecl::Static:
-    assert(0 && "FIXME: local static vars not implemented yet");
+    return EmitStaticBlockVarDecl(D);
   case VarDecl::Extern:
     assert(0 && "FIXME: should call up to codegenmodule");
   default:
@@ -62,6 +64,28 @@ void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
   }
 }
 
+void CodeGenFunction::EmitStaticBlockVarDecl(const BlockVarDecl &D) {
+  QualType Ty = D.getCanonicalType();
+  assert(Ty->isConstantSizeType(getContext()) && "VLAs can't be static");
+  
+  llvm::Value *&DMEntry = LocalDeclMap[&D];
+  assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
+  
+  const llvm::Type *LTy = ConvertType(Ty);
+  llvm::Constant *Init = 0;
+  if (D.getInit() == 0) {
+    Init = llvm::Constant::getNullValue(LTy);
+  } else
+    assert(0 && "FIXME: Support initializers");
+  
+  
+  DMEntry = 
+    new llvm::GlobalVariable(LTy, false, 
+                            llvm::GlobalValue::InternalLinkage,
+                             Init, D.getName(), &CGM.getModule());
+  
+}
+  
 /// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
 /// variable declaration with auto, register, or no storage class specifier.
 /// These turn into simple stack objects.
index b48280cd31d8d266e8764fc5556f2eadcdc9b74c..abb03ab9c09b42e4d43121c106f47cb2a76b131a 100644 (file)
@@ -304,6 +304,7 @@ public:
   void EmitEnumConstantDecl(const EnumConstantDecl &D);
   void EmitBlockVarDecl(const BlockVarDecl &D);
   void EmitLocalBlockVarDecl(const BlockVarDecl &D);
+  void EmitStaticBlockVarDecl(const BlockVarDecl &D);
   void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
   
   //===--------------------------------------------------------------------===//
index bb5d07fd6d79ae025bd16ec2ff2b2d802a374d3d..abe9250f040b7bc22fea46fb252e5011041b0fc8 100644 (file)
@@ -623,7 +623,8 @@ private:
   /// type checking declaration initializers (C99 6.7.8)
   bool CheckInitializer(Expr *&simpleInit_or_initList, QualType &declType,
                         bool isStatic);
-  bool CheckSingleInitializer(Expr *&simpleInit, QualType declType);
+  bool CheckSingleInitializer(Expr *&simpleInit, bool isStatic, 
+                              QualType declType);
   bool CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
                      bool isStatic, QualType ElementType);
   void CheckVariableInitList(QualType DeclType, InitListExpr *IList, 
index 9b2800f047f88fda2f627745f0fd27651f75b76f..390caafdc0bfa2391931f27ccfa3c26330cec47d 100644 (file)
@@ -299,9 +299,20 @@ Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
   return 0;
 }
 
-bool Sema::CheckSingleInitializer(Expr *&Init, QualType DeclType) {
+bool Sema::CheckSingleInitializer(Expr *&Init, bool isStatic, 
+                                  QualType DeclType) {
+  SourceLocation loc;
+  
+  // FIXME: Remove the isReferenceType check and handle assignment
+  // to a reference.
+  if (isStatic && !DeclType->isReferenceType() &&
+      !Init->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
+    Diag(loc, diag::err_init_element_not_constant, Init->getSourceRange());
+    return true;
+  }
+  
   AssignmentCheckResult result;
-  SourceLocation loc = Init->getLocStart();
+  loc = Init->getLocStart();
   // Get the type before calling CheckSingleAssignmentConstraints(), since
   // it can promote the expression.
   QualType rhsType = Init->getType(); 
@@ -357,7 +368,7 @@ bool Sema::CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
   if (isStatic && !expr->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
     Diag(loc, diag::err_init_element_not_constant, expr->getSourceRange());
     return true;
-  } else if (CheckSingleInitializer(expr, ElementType)) {
+  } else if (CheckSingleInitializer(expr, isStatic, ElementType)) {
     return true; // types weren't compatible.
   }
   if (savExpr != expr) // The type was promoted, update initializer list.
@@ -437,8 +448,8 @@ void Sema::CheckConstantInitList(QualType DeclType, InitListExpr *IList,
 bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {
   InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
   if (!InitList)
-    return CheckSingleInitializer(Init, DeclType);
-
+    return CheckSingleInitializer(Init, isStatic, DeclType);
+  
   // We have an InitListExpr, make sure we set the type.
   Init->setType(DeclType);
 
diff --git a/test/Sema/static-init.c b/test/Sema/static-init.c
new file mode 100644 (file)
index 0000000..e710973
--- /dev/null
@@ -0,0 +1,3 @@
+// RUN: clang -fsyntax-only -verify %s
+static int f = 10;
+static int b = f; // expected-error {{initializer element is not constant}}