[cfe-commits] r49100 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenTypes.cpp lib/Sema/SemaType.cpp
Chris Lattner
sabre at nondot.org
Wed Apr 2 10:35:07 PDT 2008
Author: lattner
Date: Wed Apr 2 12:35:06 2008
New Revision: 49100
URL: http://llvm.org/viewvc/llvm-project?rev=49100&view=rev
Log:
add a common base class "PointerLikeType" for PointerType and ReferenceType,
allowing them to be treated the same in some contexts. A suggestion for a
better name is welcome :)
Modified:
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=49100&r1=49099&r2=49100&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Apr 2 12:35:06 2008
@@ -38,6 +38,7 @@
class ObjCMethodDecl;
class Expr;
class SourceLocation;
+ class PointerLikeType;
class PointerType;
class ReferenceType;
class VectorType;
@@ -303,9 +304,10 @@
// Type Predicates: Check to see if this type is structurally the specified
// type, ignoring typedefs and qualifiers.
bool isFunctionType() const;
+ bool isPointerLikeType() const; // Pointer or Reference.
bool isPointerType() const;
- bool isFunctionPointerType() const;
bool isReferenceType() const;
+ bool isFunctionPointerType() const;
bool isArrayType() const;
bool isRecordType() const;
bool isStructureType() const;
@@ -321,6 +323,7 @@
// the best type we can.
const BuiltinType *getAsBuiltinType() const;
const FunctionType *getAsFunctionType() const;
+ const PointerLikeType *getAsPointerLikeType() const; // Pointer or Reference.
const PointerType *getAsPointerType() const;
const ReferenceType *getAsReferenceType() const;
const ArrayType *getAsArrayType() const;
@@ -488,22 +491,35 @@
friend class Type;
};
+/// PointerLikeType - Common base class for pointers and references.
+///
+class PointerLikeType : public Type {
+ QualType PointeeType;
+protected:
+ PointerLikeType(TypeClass K, QualType Pointee, QualType CanonicalPtr) :
+ Type(K, CanonicalPtr), PointeeType(Pointee) {
+ }
+public:
+
+ QualType getPointeeType() const { return PointeeType; }
+
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == Pointer || T->getTypeClass() == Reference;
+ }
+ static bool classof(const PointerLikeType *) { return true; }
+};
/// PointerType - C99 6.7.5.1 - Pointer Declarators.
///
-class PointerType : public Type, public llvm::FoldingSetNode {
- QualType PointeeType;
+class PointerType : public PointerLikeType, public llvm::FoldingSetNode {
PointerType(QualType Pointee, QualType CanonicalPtr) :
- Type(Pointer, CanonicalPtr), PointeeType(Pointee) {
+ PointerLikeType(Pointer, Pointee, CanonicalPtr) {
}
friend class ASTContext; // ASTContext creates these.
public:
-
- QualType getPointeeType() const { return PointeeType; }
virtual void getAsStringInternal(std::string &InnerString) const;
-
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType());
}
@@ -522,19 +538,16 @@
/// ReferenceType - C++ 8.3.2 - Reference Declarators.
///
-class ReferenceType : public Type, public llvm::FoldingSetNode {
- QualType ReferenceeType;
+class ReferenceType : public PointerLikeType, public llvm::FoldingSetNode {
ReferenceType(QualType Referencee, QualType CanonicalRef) :
- Type(Reference, CanonicalRef), ReferenceeType(Referencee) {
+ PointerLikeType(Reference, Referencee, CanonicalRef) {
}
friend class ASTContext; // ASTContext creates these.
public:
virtual void getAsStringInternal(std::string &InnerString) const;
- QualType getReferenceeType() const { return ReferenceeType; }
-
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getReferenceeType());
+ Profile(ID, getPointeeType());
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) {
ID.AddPointer(Referencee.getAsOpaquePtr());
@@ -1139,15 +1152,18 @@
inline bool Type::isPointerType() const {
return isa<PointerType>(CanonicalType.getUnqualifiedType());
}
+inline bool Type::isReferenceType() const {
+ return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
+}
+inline bool Type::isPointerLikeType() const {
+ return isa<PointerLikeType>(CanonicalType.getUnqualifiedType());
+}
inline bool Type::isFunctionPointerType() const {
if (const PointerType* T = getAsPointerType())
return T->getPointeeType()->isFunctionType();
else
return false;
}
-inline bool Type::isReferenceType() const {
- return isa<ReferenceType>(CanonicalType.getUnqualifiedType());
-}
inline bool Type::isArrayType() const {
return isa<ArrayType>(CanonicalType.getUnqualifiedType());
}
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=49100&r1=49099&r2=49100&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Apr 2 12:35:06 2008
@@ -281,7 +281,7 @@
// of the referenced type." C++98 5.3.3p2: expr.sizeof.
// FIXME: This is wrong for struct layout: a reference in a struct has
// pointer size.
- return getTypeInfo(cast<ReferenceType>(T)->getReferenceeType());
+ return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::Complex: {
// Complex types have the same alignment as their elements, but twice the
@@ -1725,12 +1725,12 @@
QualType ltype = lhs;
if (lhs->isReferenceType())
- ltype = cast<ReferenceType>(lhs.getCanonicalType())->getReferenceeType();
+ ltype = cast<ReferenceType>(lhs.getCanonicalType())->getPointeeType();
QualType rtype = rhs;
if (rhs->isReferenceType())
- rtype = cast<ReferenceType>(rhs.getCanonicalType())->getReferenceeType();
+ rtype = cast<ReferenceType>(rhs.getCanonicalType())->getPointeeType();
return typesAreCompatible(ltype, rtype);
}
@@ -1817,9 +1817,9 @@
// designates the object or function denoted by the reference, and the
// expression is an lvalue.
if (ReferenceType *RT = dyn_cast<ReferenceType>(lcanon))
- lcanon = RT->getReferenceeType();
+ lcanon = RT->getPointeeType();
if (ReferenceType *RT = dyn_cast<ReferenceType>(rcanon))
- rcanon = RT->getReferenceeType();
+ rcanon = RT->getPointeeType();
Type::TypeClass LHSClass = lcanon->getTypeClass();
Type::TypeClass RHSClass = rcanon->getTypeClass();
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=49100&r1=49099&r2=49100&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Wed Apr 2 12:35:06 2008
@@ -155,6 +155,24 @@
return getDesugaredType()->getAsFunctionType();
}
+const PointerLikeType *Type::getAsPointerLikeType() const {
+ // If this is directly a pointer-like type, return it.
+ if (const PointerLikeType *PTy = dyn_cast<PointerLikeType>(this))
+ return PTy;
+
+ // If the canonical form of this type isn't the right kind, reject it.
+ if (!isa<PointerLikeType>(CanonicalType)) {
+ // Look through type qualifiers
+ if (isa<PointerLikeType>(CanonicalType.getUnqualifiedType()))
+ return CanonicalType.getUnqualifiedType()->getAsPointerLikeType();
+ return 0;
+ }
+
+ // If this is a typedef for a pointer type, strip the typedef off without
+ // losing all typedef information.
+ return getDesugaredType()->getAsPointerLikeType();
+}
+
const PointerType *Type::getAsPointerType() const {
// If this is directly a pointer type, return it.
if (const PointerType *PTy = dyn_cast<PointerType>(this))
@@ -796,10 +814,10 @@
// Handle things like 'int (*A)[4];' correctly.
// FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(PointeeType.getTypePtr()))
+ if (isa<ArrayType>(getPointeeType()))
S = '(' + S + ')';
- PointeeType.getAsStringInternal(S);
+ getPointeeType().getAsStringInternal(S);
}
void ReferenceType::getAsStringInternal(std::string &S) const {
@@ -807,10 +825,10 @@
// Handle things like 'int (&A)[4];' correctly.
// FIXME: this should include vectors, but vectors use attributes I guess.
- if (isa<ArrayType>(ReferenceeType.getTypePtr()))
+ if (isa<ArrayType>(getPointeeType()))
S = '(' + S + ')';
- ReferenceeType.getAsStringInternal(S);
+ getPointeeType().getAsStringInternal(S);
}
void ConstantArrayType::getAsStringInternal(std::string &S) const {
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=49100&r1=49099&r2=49100&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Apr 2 12:35:06 2008
@@ -213,7 +213,7 @@
return EmitSizeAlignOf(E->getSubExpr()->getType(), E->getType(), false);
}
Value *EmitSizeAlignOf(QualType TypeToSize, QualType RetType,
- bool isSizeOf);
+ bool isSizeOf);
Value *VisitUnaryReal (const UnaryOperator *E);
Value *VisitUnaryImag (const UnaryOperator *E);
Value *VisitUnaryExtension(const UnaryOperator *E) {
@@ -537,7 +537,7 @@
} else if (E->getType()->isReferenceType()) {
assert(cast<ReferenceType>(E->getType().getCanonicalType())->
- getReferenceeType() ==
+ getPointeeType() ==
Op->getType().getCanonicalType() && "Incompatible types!");
return EmitLValue(Op).getAddress();
Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=49100&r1=49099&r2=49100&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Wed Apr 2 12:35:06 2008
@@ -206,15 +206,11 @@
ConvertType(cast<ComplexType>(Ty).getElementType());
return llvm::StructType::get(EltTy, EltTy, NULL);
}
+ case Type::Reference:
case Type::Pointer: {
- const PointerType &P = cast<PointerType>(Ty);
- QualType ETy = P.getPointeeType();
+ QualType ETy = cast<PointerLikeType>(Ty).getPointeeType();
return llvm::PointerType::get(ConvertType(ETy), ETy.getAddressSpace());
}
- case Type::Reference: {
- const ReferenceType &R = cast<ReferenceType>(Ty);
- return llvm::PointerType::getUnqual(ConvertType(R.getReferenceeType()));
- }
case Type::VariableArray: {
const VariableArrayType &A = cast<VariableArrayType>(Ty);
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=49100&r1=49099&r2=49100&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Apr 2 12:35:06 2008
@@ -154,28 +154,23 @@
// or incomplete types shall not be restrict-qualified." C++ also allows
// restrict-qualified references.
if (TypeQuals & QualType::Restrict) {
- QualType EltTy;
- if (const PointerType *PT = Result->getAsPointerType())
- EltTy = PT->getPointeeType();
- else if (const ReferenceType *RT = Result->getAsReferenceType())
- EltTy = RT->getReferenceeType();
- else {
+ if (const PointerLikeType *PT = Result->getAsPointerLikeType()) {
+ QualType EltTy = PT->getPointeeType();
+
+ // If we have a pointer or reference, the pointee must have an object or
+ // incomplete type.
+ if (!EltTy->isIncompleteOrObjectType()) {
+ Diag(DS.getRestrictSpecLoc(),
+ diag::err_typecheck_invalid_restrict_invalid_pointee,
+ EltTy.getAsString(), DS.getSourceRange());
+ TypeQuals &= ~QualType::Restrict; // Remove the restrict qualifier.
+ }
+ } else {
Diag(DS.getRestrictSpecLoc(),
diag::err_typecheck_invalid_restrict_not_pointer,
Result.getAsString(), DS.getSourceRange());
+ TypeQuals &= ~QualType::Restrict; // Remove the restrict qualifier.
}
-
- // If we have a pointer or reference, the pointee must have an object or
- // incomplete type.
- if (!EltTy.isNull() && !EltTy->isIncompleteOrObjectType()) {
- Diag(DS.getRestrictSpecLoc(),
- diag::err_typecheck_invalid_restrict_invalid_pointee,
- EltTy.getAsString(), DS.getSourceRange());
- EltTy = QualType();
- }
-
- if (EltTy.isNull()) // Invalid restrict: remove the restrict qualifier.
- TypeQuals &= ~QualType::Restrict;
}
// Warn about CV qualifiers on functions: C99 6.7.3p8: "If the specification
@@ -249,7 +244,7 @@
Diag(DeclType.Loc, diag::err_illegal_decl_reference_to_reference,
D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
D.setInvalidType(true);
- T = RT->getReferenceeType();
+ T = RT->getPointeeType();
}
// Enforce C99 6.7.3p2: "Types other than pointer types derived from
@@ -299,7 +294,7 @@
// C++ 8.3.2p4: There shall be no ... arrays of references ...
Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references,
D.getIdentifier() ? D.getIdentifier()->getName() : "type name");
- T = RT->getReferenceeType();
+ T = RT->getPointeeType();
D.setInvalidType(true);
} else if (const RecordType *EltTy = T->getAsRecordType()) {
// If the element type is a struct or union that contains a variadic
More information about the cfe-commits
mailing list