[cfe-commits] r60235 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/StmtNodes.def include/clang/Parse/Action.h lib/AST/Expr.cpp lib/AST/StmtPrinter.cpp lib/AST/StmtSerialization.cpp lib/Parse/ParseExpr.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp
Douglas Gregor
doug.gregor at gmail.com
Fri Nov 28 20:51:29 PST 2008
Author: dgregor
Date: Fri Nov 28 22:51:27 2008
New Revision: 60235
URL: http://llvm.org/viewvc/llvm-project?rev=60235&view=rev
Log:
Implement the GNU __null extension
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/StmtNodes.def
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/StmtSerialization.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Nov 28 22:51:27 2008
@@ -1295,7 +1295,7 @@
/// ChooseExpr - GNU builtin-in function __builtin_choose_expr.
/// This AST node is similar to the conditional operator (?:) in C, with
/// the following exceptions:
-/// - the test expression much be a constant expression.
+/// - the test expression must be a constant expression.
/// - the expression returned has it's type unaltered by promotion rules.
/// - does not evaluate the expression that was not chosen.
class ChooseExpr : public Expr {
@@ -1336,6 +1336,39 @@
static ChooseExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
};
+/// GNUNullExpr - Implements the GNU __null extension, which is a name
+/// for a null pointer constant that has integral type (e.g., int or
+/// long) and is the same size and alignment as a pointer. The __null
+/// extension is typically only used by system headers, which define
+/// NULL as __null in C++ rather than using 0 (which is an integer
+/// that may not match the size of a pointer).
+class GNUNullExpr : public Expr {
+ /// TokenLoc - The location of the __null keyword.
+ SourceLocation TokenLoc;
+
+public:
+ GNUNullExpr(QualType Ty, SourceLocation Loc)
+ : Expr(GNUNullExprClass, Ty), TokenLoc(Loc) { }
+
+ /// getTokenLocation - The location of the __null token.
+ SourceLocation getTokenLocation() const { return TokenLoc; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(TokenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == GNUNullExprClass;
+ }
+ static bool classof(const GNUNullExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ virtual void EmitImpl(llvm::Serializer& S) const;
+ static GNUNullExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+};
+
/// OverloadExpr - Clang builtin function __builtin_overload.
/// This AST node provides a way to overload functions in C.
///
Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Fri Nov 28 22:51:27 2008
@@ -88,6 +88,7 @@
STMT(StmtExpr , Expr)
STMT(TypesCompatibleExpr , Expr)
STMT(ChooseExpr , Expr)
+STMT(GNUNullExpr , Expr)
// C++ Expressions.
STMT(CXXOperatorCallExpr , CallExpr)
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Fri Nov 28 22:51:27 2008
@@ -638,6 +638,12 @@
return 0;
}
+ /// ActOnGNUNullExpr - Parsed the GNU __null expression, the token
+ /// for which is at position TokenLoc.
+ virtual ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ return 0;
+ }
+
//===------------------------- "Block" Extension ------------------------===//
/// ActOnBlockStart - This callback is invoked when a block literal is
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Nov 28 22:51:27 2008
@@ -1031,8 +1031,11 @@
= dyn_cast<CXXDefaultArgExpr>(this)) {
// See through default argument expressions
return DefaultArg->getExpr()->isNullPointerConstant(Ctx);
+ } else if (isa<GNUNullExpr>(this)) {
+ // The GNU __null extension is always a null pointer constant.
+ return true;
}
-
+
// This expression must be an integer type.
if (!getType()->isIntegerType())
return false;
@@ -1383,6 +1386,10 @@
Stmt::child_iterator ChooseExpr::child_begin() { return &SubExprs[0]; }
Stmt::child_iterator ChooseExpr::child_end() { return &SubExprs[0]+END_EXPR; }
+// GNUNullExpr
+Stmt::child_iterator GNUNullExpr::child_begin() { return child_iterator(); }
+Stmt::child_iterator GNUNullExpr::child_end() { return child_iterator(); }
+
// OverloadExpr
Stmt::child_iterator OverloadExpr::child_begin() { return &SubExprs[0]; }
Stmt::child_iterator OverloadExpr::child_end() { return &SubExprs[0]+NumExprs; }
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Fri Nov 28 22:51:27 2008
@@ -783,6 +783,10 @@
OS << ")";
}
+void StmtPrinter::VisitGNUNullExpr(GNUNullExpr *) {
+ OS << "__null";
+}
+
void StmtPrinter::VisitOverloadExpr(OverloadExpr *Node) {
OS << "__builtin_overload(";
for (unsigned i = 0, e = Node->getNumSubExprs(); i != e; ++i) {
Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Fri Nov 28 22:51:27 2008
@@ -61,6 +61,9 @@
case CharacterLiteralClass:
return CharacterLiteral::CreateImpl(D, C);
+ case ChooseExprClass:
+ return ChooseExpr::CreateImpl(D, C);
+
case CompoundAssignOperatorClass:
return CompoundAssignOperator::CreateImpl(D, C);
@@ -94,6 +97,9 @@
case ForStmtClass:
return ForStmt::CreateImpl(D, C);
+ case GNUNullExprClass:
+ return GNUNullExpr::CreateImpl(D, C);
+
case GotoStmtClass:
return GotoStmt::CreateImpl(D, C);
@@ -904,6 +910,17 @@
return CE;
}
+void GNUNullExpr::EmitImpl(llvm::Serializer &S) const {
+ S.Emit(getType());
+ S.Emit(TokenLoc);
+}
+
+GNUNullExpr *GNUNullExpr::CreateImpl(llvm::Deserializer &D, ASTContext &C) {
+ QualType T = QualType::ReadVal(D);
+ SourceLocation TL = SourceLocation::ReadVal(D);
+ return new GNUNullExpr(T, TL);
+}
+
void OverloadExpr::EmitImpl(llvm::Serializer& S) const {
S.Emit(getType());
S.Emit(BuiltinLoc);
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Fri Nov 28 22:51:27 2008
@@ -378,6 +378,7 @@
/// [GNU] '__builtin_choose_expr' '(' assign-expr ',' assign-expr ','
/// assign-expr ')'
/// [GNU] '__builtin_types_compatible_p' '(' type-name ',' type-name ')'
+/// [GNU] '__null'
/// [OBJC] '[' objc-message-expr ']'
/// [OBJC] '@selector' '(' objc-selector-arg ')'
/// [OBJC] '@protocol' '(' identifier ')'
@@ -531,6 +532,9 @@
case tok::kw___builtin_overload:
case tok::kw___builtin_types_compatible_p:
return ParseBuiltinPrimaryExpression();
+ case tok::kw___null:
+ return Actions.ActOnGNUNullExpr(ConsumeToken());
+ break;
case tok::plusplus: // unary-expression: '++' unary-expression
case tok::minusminus: { // unary-expression: '--' unary-expression
SourceLocation SavedLoc = ConsumeToken();
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Nov 28 22:51:27 2008
@@ -736,6 +736,9 @@
ExprTy *expr, TypeTy *type,
SourceLocation RPLoc);
+ // __null
+ virtual ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
+
//===------------------------- "Block" Extension ------------------------===//
/// ActOnBlockStart - This callback is invoked when a block literal is
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=60235&r1=60234&r2=60235&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Nov 28 22:51:27 2008
@@ -3603,6 +3603,18 @@
return new VAArgExpr(BuiltinLoc, E, T.getNonReferenceType(), RPLoc);
}
+Sema::ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ // The type of __null will be int or long, depending on the size of
+ // pointers on the target.
+ QualType Ty;
+ if (Context.Target.getPointerWidth(0) == Context.Target.getIntWidth())
+ Ty = Context.IntTy;
+ else
+ Ty = Context.LongTy;
+
+ return new GNUNullExpr(Ty, TokenLoc);
+}
+
bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
SourceLocation Loc,
QualType DstType, QualType SrcType,
More information about the cfe-commits
mailing list