OS << ")";
}
+void StmtPrinter::VisitTypesCompatibleExpr(TypesCompatibleExpr *Node) {
+ OS << "__builtin_types_compatible_p(";
+ OS << Node->getArgType1().getAsString() << ",";
+ OS << Node->getArgType2().getAsString() << ")";
+}
+
// C++
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;
}
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,
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);
+}
+
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; }
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
// 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
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 --------------------------===//