зеркало из https://github.com/microsoft/clang-1.git
- Add Sema::CheckStringLiteralInit, Sema::IsStringLiteralInit.
- Use previous hooks to simplify Sema::CheckInitializerTypes()... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46235 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
ca107309ff
Коммит
a49e1fa209
|
@ -43,6 +43,7 @@ namespace clang {
|
|||
struct LangOptions;
|
||||
class Token;
|
||||
class IntegerLiteral;
|
||||
class StringLiteral;
|
||||
class ArrayType;
|
||||
class LabelStmt;
|
||||
class SwitchStmt;
|
||||
|
@ -751,6 +752,9 @@ private:
|
|||
bool &hadError);
|
||||
bool CheckForConstantInitializer(Expr *e, QualType t);
|
||||
|
||||
StringLiteral *IsStringLiteralInit(Expr *Init, QualType DeclType);
|
||||
bool CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT);
|
||||
|
||||
// CheckVectorCast - check type constraints for vectors.
|
||||
// Since vectors are an extension, there are no C standard reference for this.
|
||||
// We allow casting between vectors and integer datatypes of the same size.
|
||||
|
|
|
@ -510,6 +510,38 @@ void Sema::CheckConstantInitList(QualType DeclType, InitListExpr *IList,
|
|||
}
|
||||
}
|
||||
|
||||
bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) {
|
||||
if (const VariableArrayType *VAT = DeclT->getAsIncompleteArrayType()) {
|
||||
// C99 6.7.8p14. We have an array of character type with unknown size
|
||||
// being initialized to a string literal.
|
||||
llvm::APSInt ConstVal(32);
|
||||
ConstVal = strLiteral->getByteLength() + 1;
|
||||
// Return a new array type (C99 6.7.8p22).
|
||||
DeclT = Context.getConstantArrayType(VAT->getElementType(), ConstVal,
|
||||
ArrayType::Normal, 0);
|
||||
} else if (const ConstantArrayType *CAT = DeclT->getAsConstantArrayType()) {
|
||||
// C99 6.7.8p14. We have an array of character type with known size.
|
||||
if (strLiteral->getByteLength() > (unsigned)CAT->getMaximumElements())
|
||||
Diag(strLiteral->getSourceRange().getBegin(),
|
||||
diag::warn_initializer_string_for_char_array_too_long,
|
||||
strLiteral->getSourceRange());
|
||||
} else {
|
||||
assert(0 && "HandleStringLiteralInit(): Invalid array type");
|
||||
}
|
||||
// Set type from "char *" to "constant array of char".
|
||||
strLiteral->setType(DeclT);
|
||||
// For now, we always return false (meaning success).
|
||||
return false;
|
||||
}
|
||||
|
||||
StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) {
|
||||
StringLiteral *strLiteral = dyn_cast<StringLiteral>(Init);
|
||||
const ArrayType *AT = DeclType->getAsArrayType();
|
||||
if (strLiteral && (AT && AT->getElementType()->isCharType()))
|
||||
return strLiteral;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {
|
||||
bool hadError = false;
|
||||
|
||||
|
@ -522,34 +554,9 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType) {
|
|||
|
||||
InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
|
||||
if (!InitList) {
|
||||
if (StringLiteral *strLiteral = dyn_cast<StringLiteral>(Init)) {
|
||||
const VariableArrayType *VAT = DeclType->getAsVariableArrayType();
|
||||
// FIXME: Handle wide strings
|
||||
if (VAT && VAT->getElementType()->isCharType()) {
|
||||
// C99 6.7.8p14. We have an array of character type with unknown size
|
||||
// being initialized to a string literal.
|
||||
llvm::APSInt ConstVal(32);
|
||||
ConstVal = strLiteral->getByteLength() + 1;
|
||||
// Return a new array type (C99 6.7.8p22).
|
||||
DeclType = Context.getConstantArrayType(VAT->getElementType(), ConstVal,
|
||||
ArrayType::Normal, 0);
|
||||
// set type from "char *" to "constant array of char".
|
||||
strLiteral->setType(DeclType);
|
||||
return hadError;
|
||||
}
|
||||
const ConstantArrayType *CAT = DeclType->getAsConstantArrayType();
|
||||
if (CAT && CAT->getElementType()->isCharType()) {
|
||||
// C99 6.7.8p14. We have an array of character type with known size.
|
||||
if (strLiteral->getByteLength() > (unsigned)CAT->getMaximumElements()) {
|
||||
Diag(strLiteral->getSourceRange().getBegin(),
|
||||
diag::warn_initializer_string_for_char_array_too_long,
|
||||
strLiteral->getSourceRange());
|
||||
}
|
||||
// set type from "char *" to "constant array of char".
|
||||
strLiteral->setType(DeclType);
|
||||
return hadError;
|
||||
}
|
||||
}
|
||||
// FIXME: Handle wide strings
|
||||
if (StringLiteral *strLiteral = IsStringLiteralInit(Init, DeclType))
|
||||
return CheckStringLiteralInit(strLiteral, DeclType);
|
||||
return CheckSingleInitializer(Init, DeclType);
|
||||
}
|
||||
// We have an InitListExpr, make sure we set the type.
|
||||
|
|
Загрузка…
Ссылка в новой задаче