зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
e992af01d1
Коммит
7cf8c44432
|
@ -313,15 +313,7 @@ void Sema::CheckVariableInitList(QualType DeclType, InitListExpr *IList,
|
|||
|
||||
if (InitListExpr *InitList = dyn_cast<InitListExpr>(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 };"
|
||||
|
|
|
@ -211,7 +211,7 @@
|
|||
3547129D0C88881300B3E1D5 /* PrettyPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PrettyPrinter.h; path = clang/AST/PrettyPrinter.h; sourceTree = "<group>"; };
|
||||
84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
|
||||
84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
|
||||
DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
|
||||
|
|
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче