зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
adc9b13208
Коммит
1a86b33c18
|
@ -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);
|
||||
|
|
|
@ -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,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);
|
||||
|
||||
|
|
|
@ -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}}
|
Загрузка…
Ссылка в новой задаче