From: Steve Naroff Date: Tue, 4 Sep 2007 21:13:33 +0000 (+0000) Subject: Simplified initializer semantic analysis by adding the following 2 methods: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7cf8c444320313f0e5b8a483daa996ba844b11ff;p=clang Simplified initializer semantic analysis by adding the following 2 methods: - ArrayType::getBaseType(), and - ConstantArrayType::getMaximumElements(). Wanted to do this cleanup before adding structure support, which will add more complexity. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41715 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index b178e099ba..f2a8f4d8ec 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -313,15 +313,7 @@ void Sema::CheckVariableInitList(QualType DeclType, InitListExpr *IList, if (InitListExpr *InitList = dyn_cast(expr)) { if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) { - QualType ElmtType = CAT->getElementType(); - int maxElements = CAT->getSize().getZExtValue(); - - // If we have a multi-dimensional array, navigate to the base type. Also - // compute the absolute array, so we can detect excess elements. - while ((CAT = ElmtType->getAsConstantArrayType())) { - ElmtType = CAT->getElementType(); - maxElements *= CAT->getSize().getZExtValue(); - } + int maxElements = CAT->getMaximumElements(); CheckConstantInitList(DeclType, InitList, ElementType, isStatic, maxElements, hadError); } @@ -342,19 +334,9 @@ void Sema::CheckConstantInitList(QualType DeclType, InitListExpr *IList, if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) { // We have a constant array type, compute maxElements *at this level*. - QualType ElmtType = CAT->getElementType(); - maxElementsAtThisLevel = CAT->getSize().getZExtValue(); - - // Set DeclType, important for correctly handling multi-dimensional arrays. - DeclType = ElmtType; - - // If we have a multi-dimensional array, navigate to the base type. Also - // compute the absolute size of the array *at this level* array, so we can - // detect excess elements. - while ((CAT = ElmtType->getAsConstantArrayType())) { - ElmtType = CAT->getElementType(); - maxElementsAtThisLevel *= CAT->getSize().getZExtValue(); - } + maxElementsAtThisLevel = CAT->getMaximumElements(); + // Set DeclType, used below to recurse (for multi-dimensional arrays). + DeclType = CAT->getElementType(); } else if (DeclType->isScalarType()) { Diag(IList->getLocStart(), diag::warn_braces_around_scalar_init, IList->getSourceRange()); @@ -410,22 +392,11 @@ bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) { return Diag(expr->getLocStart(), diag::err_variable_object_no_init, expr->getSourceRange()); - // We have a VariableArrayType with unknown size. - QualType ElmtType = VAT->getElementType(); - - // Set DeclType, important for correctly handling multi-dimensional arrays. - DeclType = ElmtType; - - // If we have a multi-dimensional array, navigate to the base type. - // Use getAsArrayType(), since it is illegal for an array to have an - // incomplete element type. For example, "int [][]" is illegal. - const ArrayType *ATY; - while ((ATY = ElmtType->getAsArrayType())) { - ElmtType = ATY->getElementType(); - } + // We have a VariableArrayType with unknown size. Note that only the first + // array can have unknown size. For example, "int [][]" is illegal. int numInits = 0; - CheckVariableInitList(DeclType, InitList, ElmtType, isStatic, numInits, - hadError); + CheckVariableInitList(VAT->getElementType(), InitList, VAT->getBaseType(), + isStatic, numInits, hadError); if (!hadError) { // Return a new array type from the number of initializers (C99 6.7.8p22). llvm::APSInt ConstVal(32); @@ -436,17 +407,9 @@ bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) { return hadError; } if (const ConstantArrayType *CAT = DeclType->getAsConstantArrayType()) { - QualType ElmtType = CAT->getElementType(); - int maxElements = CAT->getSize().getZExtValue(); - - // If we have a multi-dimensional array, navigate to the base type. Also - // compute the absolute size of the array, so we can detect excess elements. - while ((CAT = ElmtType->getAsConstantArrayType())) { - ElmtType = CAT->getElementType(); - maxElements *= CAT->getSize().getZExtValue(); - } - CheckConstantInitList(DeclType, InitList, ElmtType, isStatic, maxElements, - hadError); + int maxElements = CAT->getMaximumElements(); + CheckConstantInitList(DeclType, InitList, CAT->getBaseType(), + isStatic, maxElements, hadError); return hadError; } if (DeclType->isScalarType()) { // C99 6.7.8p11: Allow "int x = { 1, 2 };" diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index ceddc1fe51..c793c5f0cf 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -211,7 +211,7 @@ 3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = ""; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = ""; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; }; - 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; + 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = ""; }; DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = ""; }; DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = ""; }; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index c61cc69d6f..170580688b 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -471,6 +471,14 @@ public: ArraySizeModifier getSizeModifier() const { return SizeModifier; } unsigned getIndexTypeQualifier() const { return IndexTypeQuals; } + QualType getBaseType() const { + const ArrayType *AT; + QualType ElmtType = getElementType(); + // If we have a multi-dimensional array, navigate to the base type. + while ((AT = ElmtType->getAsArrayType())) + ElmtType = AT->getElementType(); + return ElmtType; + } static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray || T->getTypeClass() == VariableArray; @@ -487,7 +495,18 @@ class ConstantArrayType : public ArrayType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. public: llvm::APInt getSize() const { return Size; } - + int getMaximumElements() const { + QualType ElmtType = getElementType(); + int maxElements = getSize().getZExtValue(); + + const ConstantArrayType *CAT; + // If we have a multi-dimensional array, include it's elements. + while ((CAT = ElmtType->getAsConstantArrayType())) { + ElmtType = CAT->getElementType(); + maxElements *= CAT->getSize().getZExtValue(); + } + return maxElements; + } virtual void getAsStringInternal(std::string &InnerString) const; void Profile(llvm::FoldingSetNodeID &ID) {