forked from OSchip/llvm-project
Generate code for static variables that don't have initializers. Also, report an error if a static initializer is not constant.
llvm-svn: 43058
This commit is contained in:
parent
86edafc6d6
commit
f94cd1ffe6
|
@ -365,7 +365,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const {
|
||||||
case IntegerLiteralClass:
|
case IntegerLiteralClass:
|
||||||
case CharacterLiteralClass:
|
case CharacterLiteralClass:
|
||||||
case ImaginaryLiteralClass:
|
case ImaginaryLiteralClass:
|
||||||
case TypesCompatibleExprClass:
|
case TypesCompatibleExprClass:
|
||||||
|
case CXXBoolLiteralExprClass:
|
||||||
break;
|
break;
|
||||||
case CallExprClass: {
|
case CallExprClass: {
|
||||||
const CallExpr *CE = cast<CallExpr>(this);
|
const CallExpr *CE = cast<CallExpr>(this);
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "CodeGenFunction.h"
|
#include "CodeGenFunction.h"
|
||||||
|
#include "CodeGenModule.h"
|
||||||
#include "clang/AST/AST.h"
|
#include "clang/AST/AST.h"
|
||||||
|
#include "llvm/GlobalVariable.h"
|
||||||
#include "llvm/Type.h"
|
#include "llvm/Type.h"
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
using namespace CodeGen;
|
using namespace CodeGen;
|
||||||
|
@ -50,7 +52,7 @@ void CodeGenFunction::EmitEnumConstantDecl(const EnumConstantDecl &D) {
|
||||||
void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
|
void CodeGenFunction::EmitBlockVarDecl(const BlockVarDecl &D) {
|
||||||
switch (D.getStorageClass()) {
|
switch (D.getStorageClass()) {
|
||||||
case VarDecl::Static:
|
case VarDecl::Static:
|
||||||
assert(0 && "FIXME: local static vars not implemented yet");
|
return EmitStaticBlockVarDecl(D);
|
||||||
case VarDecl::Extern:
|
case VarDecl::Extern:
|
||||||
assert(0 && "FIXME: should call up to codegenmodule");
|
assert(0 && "FIXME: should call up to codegenmodule");
|
||||||
default:
|
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
|
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
|
||||||
/// variable declaration with auto, register, or no storage class specifier.
|
/// variable declaration with auto, register, or no storage class specifier.
|
||||||
/// These turn into simple stack objects.
|
/// These turn into simple stack objects.
|
||||||
|
|
|
@ -304,6 +304,7 @@ public:
|
||||||
void EmitEnumConstantDecl(const EnumConstantDecl &D);
|
void EmitEnumConstantDecl(const EnumConstantDecl &D);
|
||||||
void EmitBlockVarDecl(const BlockVarDecl &D);
|
void EmitBlockVarDecl(const BlockVarDecl &D);
|
||||||
void EmitLocalBlockVarDecl(const BlockVarDecl &D);
|
void EmitLocalBlockVarDecl(const BlockVarDecl &D);
|
||||||
|
void EmitStaticBlockVarDecl(const BlockVarDecl &D);
|
||||||
void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
|
void EmitParmDecl(const ParmVarDecl &D, llvm::Value *Arg);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
|
@ -623,7 +623,8 @@ private:
|
||||||
/// type checking declaration initializers (C99 6.7.8)
|
/// type checking declaration initializers (C99 6.7.8)
|
||||||
bool CheckInitializer(Expr *&simpleInit_or_initList, QualType &declType,
|
bool CheckInitializer(Expr *&simpleInit_or_initList, QualType &declType,
|
||||||
bool isStatic);
|
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 CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
|
||||||
bool isStatic, QualType ElementType);
|
bool isStatic, QualType ElementType);
|
||||||
void CheckVariableInitList(QualType DeclType, InitListExpr *IList,
|
void CheckVariableInitList(QualType DeclType, InitListExpr *IList,
|
||||||
|
|
|
@ -299,9 +299,20 @@ Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
|
||||||
return 0;
|
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;
|
AssignmentCheckResult result;
|
||||||
SourceLocation loc = Init->getLocStart();
|
loc = Init->getLocStart();
|
||||||
// Get the type before calling CheckSingleAssignmentConstraints(), since
|
// Get the type before calling CheckSingleAssignmentConstraints(), since
|
||||||
// it can promote the expression.
|
// it can promote the expression.
|
||||||
QualType rhsType = Init->getType();
|
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.
|
if (isStatic && !expr->isConstantExpr(Context, &loc)) { // C99 6.7.8p4.
|
||||||
Diag(loc, diag::err_init_element_not_constant, expr->getSourceRange());
|
Diag(loc, diag::err_init_element_not_constant, expr->getSourceRange());
|
||||||
return true;
|
return true;
|
||||||
} else if (CheckSingleInitializer(expr, ElementType)) {
|
} else if (CheckSingleInitializer(expr, isStatic, ElementType)) {
|
||||||
return true; // types weren't compatible.
|
return true; // types weren't compatible.
|
||||||
}
|
}
|
||||||
if (savExpr != expr) // The type was promoted, update initializer list.
|
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) {
|
bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {
|
||||||
InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
|
InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
|
||||||
if (!InitList)
|
if (!InitList)
|
||||||
return CheckSingleInitializer(Init, DeclType);
|
return CheckSingleInitializer(Init, isStatic, DeclType);
|
||||||
|
|
||||||
// We have an InitListExpr, make sure we set the type.
|
// We have an InitListExpr, make sure we set the type.
|
||||||
Init->setType(DeclType);
|
Init->setType(DeclType);
|
||||||
|
|
||||||
|
|
|
@ -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}}
|
Loading…
Reference in New Issue