Generate code for static variables that don't have initializers. Also, report an error if a static initializer is not constant.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43058 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Anders Carlsson 2007-10-17 00:52:43 +00:00
Родитель adc9b13208
Коммит 1a86b33c18
6 изменённых файлов: 49 добавлений и 8 удалений

Просмотреть файл

@ -366,6 +366,7 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
case CharacterLiteralClass:
case ImaginaryLiteralClass:
case TypesCompatibleExprClass:
case CXXBoolLiteralExprClass:
break;
case CallExprClass: {
const CallExpr *CE = cast<CallExpr>(this);

Просмотреть файл

@ -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.

Просмотреть файл

@ -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);
//===--------------------------------------------------------------------===//

Просмотреть файл

@ -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,

Просмотреть файл

@ -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,7 +448,7 @@ 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);

3
test/Sema/static-init.c Normal file
Просмотреть файл

@ -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}}