From d34e915f33224c508ad55fbf975bd10b7876e197 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Wed, 1 Aug 2007 22:05:33 +0000 Subject: [PATCH] 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 --- AST/StmtPrinter.cpp | 6 ++++++ Parse/ParseExpr.cpp | 4 ++-- Sema/Sema.h | 5 +++++ Sema/SemaExpr.cpp | 12 ++++++++++++ include/clang/AST/Expr.h | 34 +++++++++++++++++++++++++++++---- include/clang/AST/StmtNodes.def | 7 ++++--- include/clang/Parse/Action.h | 6 ++++++ 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 --------------------------===// -- 2.40.0