Small optimization: avoid redundant checks of whether a type is an array

when checking an initialization.

llvm-svn: 126115
This commit is contained in:
John McCall
2011-02-21 07:22:22 +00:00
parent 701417a0ac
commit 66884dd93c

View File

@@ -31,10 +31,8 @@ using namespace clang;
// Sema Initialization Checking
//===----------------------------------------------------------------------===//
static Expr *IsStringInit(Expr *Init, QualType DeclType, ASTContext &Context) {
const ArrayType *AT = Context.getAsArrayType(DeclType);
if (!AT) return 0;
static Expr *IsStringInit(Expr *Init, const ArrayType *AT,
ASTContext &Context) {
if (!isa<ConstantArrayType>(AT) && !isa<IncompleteArrayType>(AT))
return 0;
@@ -66,6 +64,13 @@ static Expr *IsStringInit(Expr *Init, QualType DeclType, ASTContext &Context) {
return 0;
}
static Expr *IsStringInit(Expr *init, QualType declType, ASTContext &Context) {
const ArrayType *arrayType = Context.getAsArrayType(declType);
if (!arrayType) return 0;
return IsStringInit(init, arrayType, Context);
}
static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) {
// Get the length of the string as parsed.
uint64_t StrLength =
@@ -936,9 +941,11 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
unsigned &Index,
InitListExpr *StructuredList,
unsigned &StructuredIndex) {
const ArrayType *arrayType = SemaRef.Context.getAsArrayType(DeclType);
// Check for the special-case of initializing an array with a string.
if (Index < IList->getNumInits()) {
if (Expr *Str = IsStringInit(IList->getInit(Index), DeclType,
if (Expr *Str = IsStringInit(IList->getInit(Index), arrayType,
SemaRef.Context)) {
CheckStringInit(Str, DeclType, SemaRef);
// We place the string literal directly into the resulting
@@ -952,8 +959,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
return;
}
}
if (const VariableArrayType *VAT =
SemaRef.Context.getAsVariableArrayType(DeclType)) {
if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(arrayType)) {
// Check for VLAs; in standard C it would be possible to check this
// earlier, but I don't know where clang accepts VLAs (gcc accepts
// them in all sorts of strange places).
@@ -970,16 +976,14 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity,
llvm::APSInt maxElements(elementIndex.getBitWidth(),
elementIndex.isUnsigned());
bool maxElementsKnown = false;
if (const ConstantArrayType *CAT =
SemaRef.Context.getAsConstantArrayType(DeclType)) {
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(arrayType)) {
maxElements = CAT->getSize();
elementIndex = elementIndex.extOrTrunc(maxElements.getBitWidth());
elementIndex.setIsUnsigned(maxElements.isUnsigned());
maxElementsKnown = true;
}
QualType elementType = SemaRef.Context.getAsArrayType(DeclType)
->getElementType();
QualType elementType = arrayType->getElementType();
while (Index < IList->getNumInits()) {
Expr *Init = IList->getInit(Index);
if (DesignatedInitExpr *DIE = dyn_cast<DesignatedInitExpr>(Init)) {
@@ -3109,14 +3113,6 @@ InitializationSequence::InitializationSequence(Sema &S,
return;
}
// - If the destination type is an array of characters, an array of
// char16_t, an array of char32_t, or an array of wchar_t, and the
// initializer is a string literal, see 8.5.2.
if (Initializer && IsStringInit(Initializer, DestType, Context)) {
TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this);
return;
}
// - If the initializer is (), the object is value-initialized.
if (Kind.getKind() == InitializationKind::IK_Value ||
(Kind.getKind() == InitializationKind::IK_Direct && NumArgs == 0)) {
@@ -3130,10 +3126,18 @@ InitializationSequence::InitializationSequence(Sema &S,
return;
}
// - If the destination type is an array of characters, an array of
// char16_t, an array of char32_t, or an array of wchar_t, and the
// initializer is a string literal, see 8.5.2.
// - Otherwise, if the destination type is an array, the program is
// ill-formed.
if (const ArrayType *AT = Context.getAsArrayType(DestType)) {
if (AT->getElementType()->isAnyCharacterType())
if (const ArrayType *arrayType = Context.getAsArrayType(DestType)) {
if (Initializer && IsStringInit(Initializer, arrayType, Context)) {
TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this);
return;
}
if (arrayType->getElementType()->isAnyCharacterType())
SetFailed(FK_ArrayNeedsInitListOrStringLiteral);
else
SetFailed(FK_ArrayNeedsInitList);