summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-29 04:51:27 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-29 04:51:27 +0000
commit3be4b122d38ebe00bfa585b3f5c99d146398398f (patch)
tree38bc001bafbaf8f777f658cb7f8868b1dd59d461 /clang/lib
parent51ba8d063030e08dc8d9344f6c1cb0c1348dd1a4 (diff)
downloadbcm5719-llvm-3be4b122d38ebe00bfa585b3f5c99d146398398f.tar.gz
bcm5719-llvm-3be4b122d38ebe00bfa585b3f5c99d146398398f.zip
Implement the GNU __null extension
llvm-svn: 60235
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp9
-rw-r--r--clang/lib/AST/StmtPrinter.cpp4
-rw-r--r--clang/lib/AST/StmtSerialization.cpp17
-rw-r--r--clang/lib/Parse/ParseExpr.cpp4
-rw-r--r--clang/lib/Sema/Sema.h3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp12
6 files changed, 48 insertions, 1 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 7a8119c5e3d..3c021c262d6 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1031,8 +1031,11 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const {
= 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 TypesCompatibleExpr::child_end() {
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; }
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index fcebdab05c6..b6f07070538 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -783,6 +783,10 @@ void StmtPrinter::VisitChooseExpr(ChooseExpr *Node) {
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) {
diff --git a/clang/lib/AST/StmtSerialization.cpp b/clang/lib/AST/StmtSerialization.cpp
index 8bf70396856..3cf1f5497fb 100644
--- a/clang/lib/AST/StmtSerialization.cpp
+++ b/clang/lib/AST/StmtSerialization.cpp
@@ -61,6 +61,9 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) {
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 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) {
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 @@ ChooseExpr* ChooseExpr::CreateImpl(llvm::Deserializer& D, ASTContext& C) {
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);
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 66b1d180780..df46612b57d 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -378,6 +378,7 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec) {
/// [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 @@ Parser::ExprResult Parser::ParseCastExpression(bool isUnaryExpression) {
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();
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
index 57caa6ecf24..044bfbd73be 100644
--- a/clang/lib/Sema/Sema.h
+++ b/clang/lib/Sema/Sema.h
@@ -736,6 +736,9 @@ public:
ExprTy *expr, TypeTy *type,
SourceLocation RPLoc);
+ // __null
+ virtual ExprResult ActOnGNUNullExpr(SourceLocation TokenLoc);
+
//===------------------------- "Block" Extension ------------------------===//
/// ActOnBlockStart - This callback is invoked when a block literal is
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index e21047e10d8..fb964692b35 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3603,6 +3603,18 @@ Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
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,
OpenPOWER on IntegriCloud