aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-08-01 22:05:33 +0000
committerSteve Naroff <snaroff@apple.com>2007-08-01 22:05:33 +0000
commitd34e915f33224c508ad55fbf975bd10b7876e197 (patch)
tree7e9df18eb5f366db4cc64a3a748f446088d90976
parent9752f25748d954df99087d741ea35db37ff16bea (diff)
Add AST/Sema support for __builtin_types_compatible_p (a GNU extension).
Todo...still need to call the action from the parser... git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40693 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--AST/StmtPrinter.cpp6
-rw-r--r--Parse/ParseExpr.cpp4
-rw-r--r--Sema/Sema.h5
-rw-r--r--Sema/SemaExpr.cpp12
-rw-r--r--include/clang/AST/Expr.h34
-rw-r--r--include/clang/AST/StmtNodes.def7
-rw-r--r--include/clang/Parse/Action.h6
7 files changed, 65 insertions, 9 deletions
diff --git a/AST/StmtPrinter.cpp b/AST/StmtPrinter.cpp
index 18f605be92..9ca17836d1 100644
--- a/AST/StmtPrinter.cpp
+++ b/AST/StmtPrinter.cpp
@@ -481,6 +481,12 @@ void StmtPrinter::VisitStmtExpr(StmtExpr *E) {
OS << ")";
}
+void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
+ OS << "__builtin_types_compatible_p(";
+ OS << Node->getArgType1().getAsString() << ",";
+ OS << Node->getArgType2().getAsString() << ")";
+}
+
// C++
diff --git a/Parse/ParseExpr.cpp b/Parse/ParseExpr.cpp
index de0a2a2d67..15aca62179 100644
--- a/Parse/ParseExpr.cpp
+++ b/Parse/ParseExpr.cpp
@@ -819,12 +819,12 @@ Parser::ExprResult Parser::ParseBuiltinPrimaryExpression() {
Res = ParseAssignmentExpression();
break;
case tok::kw___builtin_types_compatible_p:
- ParseTypeName();
+ TypeTy *Type1 = ParseTypeName();
if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren))
return ExprResult(true);
- ParseTypeName();
+ TypeTy *Type2 = ParseTypeName();
break;
}
diff --git a/Sema/Sema.h b/Sema/Sema.h
index ea724ab44b..86378a4f06 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -280,6 +280,11 @@ public:
virtual ExprResult ParseStmtExpr(SourceLocation LPLoc, StmtTy *SubStmt,
SourceLocation RPLoc); // "({..})"
+
+ // __builtin_types_compatible_p(type1, type2)
+ virtual ExprResult ParseTypesCompatibleExpr(SourceLocation LPLoc,
+ TypeTy *arg1, TypeTy *arg2,
+ SourceLocation RPLoc);
/// ParseCXXCasts - Parse {dynamic,static,reinterpret,const}_cast's.
virtual ExprResult ParseCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 1570f4a8e2..9ef2e67990 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -1565,3 +1565,15 @@ Sema::ExprResult Sema::ParseStmtExpr(SourceLocation LPLoc, StmtTy *substmt,
return new StmtExpr(Compound, Ty, LPLoc, RPLoc);
}
+
+Sema::ExprResult Sema::ParseTypesCompatibleExpr(SourceLocation LPLoc,
+ TypeTy *arg1, TypeTy *arg2,
+ SourceLocation RPLoc) {
+ QualType argT1 = QualType::getFromOpaquePtr(arg1);
+ QualType argT2 = QualType::getFromOpaquePtr(arg2);
+
+ assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
+
+ return new TypesCompatibleExpr(Context.IntTy, LPLoc, argT1, argT2, RPLoc);
+}
+
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 01917dc7a3..568d3e02b7 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -703,10 +703,9 @@ class StmtExpr : public Expr {
CompoundStmt *SubStmt;
SourceLocation LParenLoc, RParenLoc;
public:
- StmtExpr(CompoundStmt *substmt, QualType T,
- SourceLocation lp, SourceLocation rp)
- : Expr(StmtExprClass, T), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) {
- }
+ StmtExpr(CompoundStmt *substmt, QualType T,
+ SourceLocation lp, SourceLocation rp) :
+ Expr(StmtExprClass, T), SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { }
CompoundStmt *getSubStmt() { return SubStmt; }
const CompoundStmt *getSubStmt() const { return SubStmt; }
@@ -722,6 +721,33 @@ public:
static bool classof(const StmtExpr *) { return true; }
};
+/// TypesCompatibleExpr - GNU builtin-in function __builtin_type_compatible_p.
+/// This AST node represents a function that returns 1 if two *types* (not
+/// expressions) are compatible. The result of this built-in function can be
+/// used in integer constant expressions.
+class TypesCompatibleExpr : public Expr {
+ QualType Type1;
+ QualType Type2;
+ SourceLocation LParenLoc, RParenLoc;
+public:
+ TypesCompatibleExpr(QualType ReturnType, SourceLocation LP,
+ QualType t1, QualType t2, SourceLocation RP) :
+ Expr(TypesCompatibleExprClass, ReturnType), Type1(t1), Type2(t2),
+ LParenLoc(LP), RParenLoc(RP) {}
+
+ QualType getArgType1() { return Type1; }
+ QualType getArgType2() { return Type2; }
+
+ virtual SourceRange getSourceRange() const {
+ return SourceRange(LParenLoc, RParenLoc);
+ }
+ virtual void visit(StmtVisitor &Visitor);
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == TypesCompatibleExprClass;
+ }
+ static bool classof(const TypesCompatibleExpr *) { return true; }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/AST/StmtNodes.def b/include/clang/AST/StmtNodes.def
index 4335b51469..375a52bc0d 100644
--- a/include/clang/AST/StmtNodes.def
+++ b/include/clang/AST/StmtNodes.def
@@ -67,11 +67,12 @@ STMT(49, OCUVectorComponent , Expr)
// GNU Extensions.
STMT(50, AddrLabel , Expr)
STMT(51, StmtExpr , Expr)
+STMT(52, TypesCompatibleExpr , Expr)
// C++ Expressions.
-STMT(52, CXXCastExpr , Expr)
-STMT(53, CXXBoolLiteralExpr , Expr)
-LAST_EXPR(53)
+STMT(53, CXXCastExpr , Expr)
+STMT(54, CXXBoolLiteralExpr , Expr)
+LAST_EXPR(54)
#undef STMT
#undef FIRST_STMT
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index d9e3e12c4c..c019a0b22c 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -375,6 +375,12 @@ public:
SourceLocation RPLoc) { // "({..})"
return 0;
}
+ // __builtin_types_compatible_p(type1, type2)
+ virtual ExprResult ParseTypesCompatibleExpr(SourceLocation LPLoc,
+ TypeTy *arg1, TypeTy *arg2,
+ SourceLocation RPLoc) {
+ return 0;
+ }
//===------------------------- C++ Expressions --------------------------===//