forked from OSchip/llvm-project
Various improvements to Sema::ParseMemberReferenceExpr().
- Added source range support to Diag's. - Used the new type predicate API to remove dealing with the canonical type explicitly. - Added Type::isRecordType(). - Removed some casts. - Removed a const qualifier from RecordType::getDecl(). llvm-svn: 40508
This commit is contained in:
parent
6e082ad617
commit
185616f293
|
@ -96,6 +96,17 @@ const ArrayType *Type::isArrayType() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
const RecordType *Type::isRecordType() const {
|
||||
// If this is directly a reference type, return it.
|
||||
if (const RecordType *RTy = dyn_cast<RecordType>(this))
|
||||
return RTy;
|
||||
|
||||
// If this is a typedef for an record type, strip the typedef off without
|
||||
// losing all typedef information.
|
||||
if (isa<RecordType>(CanonicalType))
|
||||
return cast<RecordType>(cast<TypedefType>(this)->LookThroughTypedefs());
|
||||
}
|
||||
|
||||
bool Type::isStructureType() const {
|
||||
if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
|
||||
if (TT->getDecl()->getKind() == Decl::Struct)
|
||||
|
|
|
@ -343,34 +343,35 @@ Action::ExprResult Sema::
|
|||
ParseMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc,
|
||||
tok::TokenKind OpKind, SourceLocation MemberLoc,
|
||||
IdentifierInfo &Member) {
|
||||
QualType qualifiedType = ((Expr *)Base)->getType();
|
||||
Expr *BaseExpr = static_cast<Expr *>(Base);
|
||||
assert(BaseExpr && "no record expression");
|
||||
|
||||
assert(!qualifiedType.isNull() && "no type for member expression");
|
||||
QualType BaseType = BaseExpr->getType();
|
||||
assert(!BaseType.isNull() && "no type for member expression");
|
||||
|
||||
QualType canonType = qualifiedType.getCanonicalType();
|
||||
|
||||
if (OpKind == tok::arrow) {
|
||||
if (PointerType *PT = dyn_cast<PointerType>(canonType)) {
|
||||
qualifiedType = PT->getPointeeType();
|
||||
canonType = qualifiedType.getCanonicalType();
|
||||
} else
|
||||
return Diag(OpLoc, diag::err_typecheck_member_reference_arrow);
|
||||
if (const PointerType *PT = BaseType->isPointerType())
|
||||
BaseType = PT->getPointeeType();
|
||||
else
|
||||
return Diag(OpLoc, diag::err_typecheck_member_reference_arrow,
|
||||
SourceRange(MemberLoc));
|
||||
}
|
||||
if (!isa<RecordType>(canonType))
|
||||
return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion);
|
||||
// Get the member decl from the struct/union definition.
|
||||
FieldDecl *MemberDecl;
|
||||
if (const RecordType *RTy = BaseType->isRecordType()) {
|
||||
RecordDecl *RDecl = RTy->getDecl();
|
||||
if (RTy->isIncompleteType())
|
||||
return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RDecl->getName(),
|
||||
BaseExpr->getSourceRange());
|
||||
// The record definition is complete, now make sure the member is valid.
|
||||
if (!(MemberDecl = RDecl->getMember(&Member)))
|
||||
return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName(),
|
||||
SourceRange(MemberLoc));
|
||||
} else
|
||||
return Diag(OpLoc, diag::err_typecheck_member_reference_structUnion,
|
||||
SourceRange(MemberLoc));
|
||||
|
||||
// get the struct/union definition from the type.
|
||||
RecordDecl *RD = cast<RecordType>(canonType)->getDecl();
|
||||
|
||||
if (canonType->isIncompleteType())
|
||||
return Diag(OpLoc, diag::err_typecheck_incomplete_tag, RD->getName());
|
||||
|
||||
FieldDecl *MemberDecl = RD->getMember(&Member);
|
||||
if (!MemberDecl)
|
||||
return Diag(OpLoc, diag::err_typecheck_no_member, Member.getName());
|
||||
|
||||
return new MemberExpr((Expr*)Base, OpKind == tok::arrow,
|
||||
MemberDecl, MemberLoc);
|
||||
return new MemberExpr(BaseExpr, OpKind == tok::arrow, MemberDecl, MemberLoc);
|
||||
}
|
||||
|
||||
/// ParseCallExpr - Handle a call to Fn with the specified array of arguments.
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace clang {
|
|||
class ReferenceType;
|
||||
class VectorType;
|
||||
class ArrayType;
|
||||
class RecordType;
|
||||
|
||||
/// QualType - For efficiency, we don't store CVR-qualified types as nodes on
|
||||
/// their own: instead each reference to a type stores the qualifiers. This
|
||||
|
@ -239,6 +240,7 @@ public:
|
|||
const PointerType *isPointerType() const;
|
||||
const ReferenceType *isReferenceType() const;
|
||||
const ArrayType *isArrayType() const;
|
||||
const RecordType *isRecordType() const;
|
||||
bool isStructureType() const;
|
||||
bool isUnionType() const;
|
||||
|
||||
|
@ -650,10 +652,10 @@ class RecordType : public TagType {
|
|||
RecordType(); // DO NOT IMPLEMENT
|
||||
public:
|
||||
|
||||
const RecordDecl *getDecl() const {
|
||||
const RecordDecl *getDecl() {
|
||||
return reinterpret_cast<RecordDecl*>(TagType::getDecl());
|
||||
}
|
||||
RecordDecl *getDecl() {
|
||||
RecordDecl *getDecl() const {
|
||||
return reinterpret_cast<RecordDecl*>(TagType::getDecl());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue