diff options
author | John McCall <rjmccall@apple.com> | 2009-11-04 07:28:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-11-04 07:28:41 +0000 |
commit | 5ab75172051a6d2ea71a80a79e81c65519fd3462 (patch) | |
tree | e03271bc6d106935276fbc951192f7e85b3f1a5b | |
parent | c86a6e988184867b09aa17a619402d0e81d0fda0 (diff) |
Preserve type source information in sizeof/alignof expressions, and pass it
through to indexing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@86018 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 17 | ||||
-rw-r--r-- | lib/Frontend/PCHReaderStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/PCHWriterStmt.cpp | 2 | ||||
-rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 2 | ||||
-rw-r--r-- | lib/Index/ResolveLocation.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 15 |
8 files changed, 53 insertions, 26 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 27d2ba72f2..2a87f58835 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -976,7 +976,7 @@ class SizeOfAlignOfExpr : public Expr { 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; @@ -985,15 +985,15 @@ protected: 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, @@ -1016,8 +1016,11 @@ public: 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"); @@ -1028,8 +1031,8 @@ public: } 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; } diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index 60f6d19600..01af67dd50 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -424,7 +424,7 @@ unsigned PCHStmtReader::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { 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++])); diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index afed7fae58..78a56db7ed 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -384,7 +384,7 @@ void PCHStmtWriter::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { 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()); diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index a00326267e..24ad69e3e0 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -2569,7 +2569,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) { // 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(...)) diff --git a/lib/Index/ResolveLocation.cpp b/lib/Index/ResolveLocation.cpp index ec8c1dcb38..73b584b520 100644 --- a/lib/Index/ResolveLocation.cpp +++ b/lib/Index/ResolveLocation.cpp @@ -92,6 +92,7 @@ public: 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); @@ -136,6 +137,25 @@ public: } // 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) && "Should visit only after verifying that loc is in range"); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index bb59e1c9f4..0f84b46ed4 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1670,7 +1670,8 @@ public: 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); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2c54a792c1..ac7cced2ea 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1290,7 +1290,7 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, 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; @@ -1348,17 +1348,20 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, /// \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())); } @@ -1400,12 +1403,11 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, 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()); diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 9a6b851d63..5713da9fa5 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -884,9 +884,10 @@ public: /// /// 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 @@ -3532,16 +3533,16 @@ Sema::OwningExprResult 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()); } |