bool isSizeof : 1; // true if sizeof, false if alignof.
bool isType : 1; // true if operand is a type, false if an expression
union {
- void *Ty;
+ DeclaratorInfo *Ty;
Stmt *Ex;
} Argument;
SourceLocation OpLoc, RParenLoc;
virtual void DoDestroy(ASTContext& C);
public:
- SizeOfAlignOfExpr(bool issizeof, QualType T,
+ SizeOfAlignOfExpr(bool issizeof, DeclaratorInfo *DInfo,
QualType resultType, SourceLocation op,
SourceLocation rp) :
Expr(SizeOfAlignOfExprClass, resultType,
false, // Never type-dependent (C++ [temp.dep.expr]p3).
// Value-dependent if the argument is type-dependent.
- T->isDependentType()),
+ DInfo->getType()->isDependentType()),
isSizeof(issizeof), isType(true), OpLoc(op), RParenLoc(rp) {
- Argument.Ty = T.getAsOpaquePtr();
+ Argument.Ty = DInfo;
}
SizeOfAlignOfExpr(bool issizeof, Expr *E,
bool isArgumentType() const { return isType; }
QualType getArgumentType() const {
+ return getArgumentTypeInfo()->getType();
+ }
+ DeclaratorInfo *getArgumentTypeInfo() const {
assert(isArgumentType() && "calling getArgumentType() when arg is expr");
- return QualType::getFromOpaquePtr(Argument.Ty);
+ return Argument.Ty;
}
Expr *getArgumentExpr() {
assert(!isArgumentType() && "calling getArgumentExpr() when arg is type");
}
void setArgument(Expr *E) { Argument.Ex = E; isType = false; }
- void setArgument(QualType T) {
- Argument.Ty = T.getAsOpaquePtr();
+ void setArgument(DeclaratorInfo *DInfo) {
+ Argument.Ty = DInfo;
isType = true;
}
E->setArgument(cast<Expr>(StmtStack.back()));
++Idx;
} else {
- E->setArgument(Reader.GetType(Record[Idx++]));
+ E->setArgument(Reader.GetDeclaratorInfo(Record, Idx));
}
E->setOperatorLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
VisitExpr(E);
Record.push_back(E->isSizeOf());
if (E->isArgumentType())
- Writer.AddTypeRef(E->getArgumentType(), Record);
+ Writer.AddDeclaratorInfo(E->getArgumentTypeInfo(), Record);
else {
Record.push_back(0);
Writer.WriteSubStmt(E->getArgumentExpr());
// Build sizeof(returnType)
SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true,
- returnType,
+ Context->getTrivialDeclaratorInfo(returnType),
Context->getSizeType(),
SourceLocation(), SourceLocation());
// (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
StmtLocResolver(ASTContext &ctx, SourceLocation loc, Decl *parent)
: LocResolverBase(ctx, loc), Parent(parent) {}
+ ASTLocation VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node);
ASTLocation VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node);
ASTLocation VisitDeclStmt(DeclStmt *Node);
ASTLocation VisitStmt(Stmt *Node);
} // anonymous namespace
+ASTLocation
+StmtLocResolver::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
+ assert(ContainsLocation(Node) &&
+ "Should visit only after verifying that loc is in range");
+
+ if (Node->isArgumentType()) {
+ DeclaratorInfo *DInfo = Node->getArgumentTypeInfo();
+ if (ContainsLocation(DInfo))
+ return ResolveInDeclarator(Parent, Node, DInfo);
+ } else {
+ Expr *SubNode = Node->getArgumentExpr();
+ if (ContainsLocation(SubNode))
+ return Visit(SubNode);
+ }
+
+ return ASTLocation(Parent, Node);
+}
+
+
ASTLocation
StmtLocResolver::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *Node) {
assert(ContainsLocation(Node) &&
virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Op, ExprArg Input);
- OwningExprResult CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc,
+ OwningExprResult CreateSizeOfAlignOfExpr(DeclaratorInfo *T,
+ SourceLocation OpLoc,
bool isSizeOf, SourceRange R);
OwningExprResult CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
bool isSizeOf, SourceRange R);
return false;
// C99 6.5.3.4p1:
- if (isa<FunctionType>(exprType)) {
+ if (exprType->isFunctionType()) {
// alignof(function) is allowed as an extension.
if (isSizeof)
Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange;
/// \brief Build a sizeof or alignof expression given a type operand.
Action::OwningExprResult
-Sema::CreateSizeOfAlignOfExpr(QualType T, SourceLocation OpLoc,
+Sema::CreateSizeOfAlignOfExpr(DeclaratorInfo *DInfo,
+ SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
- if (T.isNull())
+ if (!DInfo)
return ExprError();
+ QualType T = DInfo->getType();
+
if (!T->isDependentType() &&
CheckSizeOfAlignOfOperand(T, OpLoc, R, isSizeOf))
return ExprError();
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
- return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, T,
+ return Owned(new (Context) SizeOfAlignOfExpr(isSizeOf, DInfo,
Context.getSizeType(), OpLoc,
R.getEnd()));
}
if (TyOrEx == 0) return ExprError();
if (isType) {
- // FIXME: Preserve type source info.
- QualType ArgTy = GetTypeFromParser(TyOrEx);
- return CreateSizeOfAlignOfExpr(ArgTy, OpLoc, isSizeof, ArgRange);
+ DeclaratorInfo *DInfo;
+ (void) GetTypeFromParser(TyOrEx, &DInfo);
+ return CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeof, ArgRange);
}
- // Get the end location.
Expr *ArgEx = (Expr *)TyOrEx;
Action::OwningExprResult Result
= CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
- OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
+ OwningExprResult RebuildSizeOfAlignOf(DeclaratorInfo *DInfo,
+ SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
- return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
+ return getSema().CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeOf, R);
}
/// \brief Build a new sizeof or alignof expression with an expression
TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
bool isAddressOfOperand) {
if (E->isArgumentType()) {
- TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
+ DeclaratorInfo *OldT = E->getArgumentTypeInfo();
- QualType T = getDerived().TransformType(E->getArgumentType());
- if (T.isNull())
+ DeclaratorInfo *NewT = getDerived().TransformType(OldT);
+ if (!NewT)
return SemaRef.ExprError();
- if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
+ if (!getDerived().AlwaysRebuild() && OldT == NewT)
return SemaRef.Owned(E->Retain());
- return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
+ return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
E->isSizeOf(),
E->getSourceRange());
}