diff options
author | Steve Naroff <snaroff@apple.com> | 2007-08-30 01:06:46 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-08-30 01:06:46 +0000 |
commit | fb22d96692c5240fb8d611290dbf7eeed3759c73 (patch) | |
tree | 436250f2d163b6d3f4ecd02a482649442e24b108 /include/clang | |
parent | 17a1a72e70dcbd6257dde644c790a3013113174f (diff) |
Fix the following redefinition errors submitted by Keith Bauer...
[dylan:~/llvm/tools/clang] admin% cat tentative_decls.c
// incorrectly generates redefinition error
extern int array[3];
int array[3];
// incorrectly generates a redefinition error
extern void nup(int a[3]);
void nup(int a[3]) {}
It turns out that this exposed a fairly major flaw in the type system,
array types were never getting uniqued! This is because all array types
contained an expression, which aren't unique.
To solve this, we now have 2 array types, ConstantArrayType and
VariableArrayType. ConstantArrayType's are unique, VAT's aren't.
This is a fairly extensive set of fundamental changes. Fortunately,
all the tests pass. Nevertheless, there may be some collateral damage:-)
If so, let me know!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41592 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/ASTContext.h | 11 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 87 |
2 files changed, 66 insertions, 32 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 782b2fcfca..372109a8f8 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -31,7 +31,7 @@ class ASTContext { llvm::FoldingSet<ComplexType> ComplexTypes; llvm::FoldingSet<PointerType> PointerTypes; llvm::FoldingSet<ReferenceType> ReferenceTypes; - llvm::FoldingSet<ArrayType> ArrayTypes; + llvm::FoldingSet<ConstantArrayType> ArrayTypes; llvm::FoldingSet<VectorType> VectorTypes; llvm::FoldingSet<FunctionTypeNoProto> FunctionTypeNoProtos; llvm::FoldingSet<FunctionTypeProto> FunctionTypeProtos; @@ -77,10 +77,15 @@ public: /// reference to the specified type. QualType getReferenceType(QualType T); - /// getArrayType - Return the unique reference to the type for an array of the - /// specified element type. + /// getArrayType - If NumElts is a constant expression, we return a unique + /// reference to an AST node of type ConstantArrayType. If NumElts is not + /// a constant expression, we return an instance of VaribleLengthArrayType. QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM, unsigned EltTypeQuals, Expr *NumElts); + + /// getConstantArrayType - Return the unique reference to the type for an + /// array of the specified element type. + QualType getConstantArrayType(QualType EltTy, const llvm::APInt &Sz); /// getVectorType - Return the unique reference to a vector type of /// the specified element type and size. VectorType must be a built-in type. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 54cc77c55b..58b3f4af51 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -16,6 +16,7 @@ #include "llvm/Support/Casting.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/APSInt.h" using llvm::isa; using llvm::cast; @@ -195,7 +196,9 @@ namespace clang { class Type { public: enum TypeClass { - Builtin, Complex, Pointer, Reference, Array, Vector, OCUVector, + Builtin, Complex, Pointer, Reference, + ConstantArray, VariableArray, + Vector, OCUVector, FunctionNoProto, FunctionProto, TypeName, Tagged, TypeOfExp, TypeOfTyp // GNU typeof extension. @@ -430,15 +433,58 @@ public: /// ArrayType - C99 6.7.5.2 - Array Declarators. /// -class ArrayType : public Type, public llvm::FoldingSetNode { +class ArrayType : public Type { public: /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4]) /// an array with a static size (e.g. int X[static 4]), or with a star size - /// (e.g. int X[*]). + /// (e.g. int X[*]). FIXME: consider moving this down to VLAArayType. enum ArraySizeModifier { Normal, Static, Star }; private: + /// ElementType - The element type of the array. + QualType ElementType; +protected: + ArrayType(TypeClass tc, QualType et, QualType can) + : Type(tc, can), ElementType(et) {} + friend class ASTContext; // ASTContext creates these. +public: + QualType getElementType() const { return ElementType; } + + static bool classof(const Type *T) { + return T->getTypeClass() == ConstantArray || + T->getTypeClass() == VariableArray; + } + static bool classof(const ArrayType *) { return true; } +}; + +class ConstantArrayType : public ArrayType, public llvm::FoldingSetNode { + llvm::APInt Size; // Allows us to unique the type. + + ConstantArrayType(QualType et, QualType can, llvm::APInt sz) + : ArrayType(ConstantArray, et, can), Size(sz) {} + friend class ASTContext; // ASTContext creates these. +public: + llvm::APInt getSize() const { return Size; } + + virtual void getAsStringInternal(std::string &InnerString) const; + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getElementType(), getSize()); + } + static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, + llvm::APInt ArraySize) { + ID.AddPointer(ET.getAsOpaquePtr()); + ID.AddInteger(ArraySize.getZExtValue()); + } + static bool classof(const Type *T) { + return T->getTypeClass() == ConstantArray; + } + static bool classof(const ConstantArrayType *) { return true; } +}; + +// FIXME: VariableArrayType's aren't uniqued (since expressions aren't). +class VariableArrayType : public ArrayType { /// NOTE: These fields are packed into the bitfields space in the Type class. ArraySizeModifier SizeModifier : 2; @@ -446,43 +492,26 @@ private: /// 'int X[static restrict 4]'. unsigned IndexTypeQuals : 3; - /// ElementType - The element type of the array. - QualType ElementType; - - /// SizeExpr - The size is either a constant or assignment expression (for - /// Variable Length Arrays). VLA's are only permitted within a function block. + /// SizeExpr - An assignment expression. VLA's are only permitted within + /// a function block. Expr *SizeExpr; - ArrayType(QualType et, ArraySizeModifier sm, unsigned tq, QualType can, - Expr *e) - : Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et), - SizeExpr(e) {} + VariableArrayType(QualType et, ArraySizeModifier sm, unsigned tq, + QualType can, Expr *e) + : ArrayType(VariableArray, et, can), + SizeModifier(sm), IndexTypeQuals(tq), SizeExpr(e) {} friend class ASTContext; // ASTContext creates these. public: - - QualType getElementType() const { return ElementType; } ArraySizeModifier getSizeModifier() const { return SizeModifier; } unsigned getIndexTypeQualifier() const { return IndexTypeQuals; } Expr *getSizeExpr() const { return SizeExpr; } virtual void getAsStringInternal(std::string &InnerString) const; - void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType(), - getSizeExpr()); - } - static void Profile(llvm::FoldingSetNodeID &ID, - ArraySizeModifier SizeModifier, - unsigned IndexTypeQuals, QualType ElementType, - Expr *SizeExpr) { - ID.AddInteger(SizeModifier); - ID.AddInteger(IndexTypeQuals); - ID.AddPointer(ElementType.getAsOpaquePtr()); - ID.AddPointer(SizeExpr); + static bool classof(const Type *T) { + return T->getTypeClass() == VariableArray; } - - static bool classof(const Type *T) { return T->getTypeClass() == Array; } - static bool classof(const ArrayType *) { return true; } + static bool classof(const VariableArrayType *) { return true; } }; /// VectorType - GCC generic vector type. This type is created using |