pch'ify typeid.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103374 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index c11f55b..e6bc394 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -321,6 +321,14 @@
Operand->isTypeDependent() || Operand->isValueDependent()),
Operand(Operand), Range(R) { }
+ CXXTypeidExpr(EmptyShell Empty, bool isExpr)
+ : Expr(CXXTypeidExprClass, Empty) {
+ if (isExpr)
+ Operand = (Expr*)0;
+ else
+ Operand = (TypeSourceInfo*)0;
+ }
+
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
/// \brief Retrieves the type operand of this typeid() expression after
@@ -332,15 +340,20 @@
assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
return Operand.get<TypeSourceInfo *>();
}
+
+ void setTypeOperandSourceInfo(TypeSourceInfo *TSI) {
+ assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+ Operand = TSI;
+ }
- Expr* getExprOperand() const {
+ Expr *getExprOperand() const {
assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
return static_cast<Expr*>(Operand.get<Stmt *>());
}
-
- virtual SourceRange getSourceRange() const {
- return Range;
- }
+
+ virtual SourceRange getSourceRange() const { return Range; }
+ void setSourceRange(SourceRange R) { Range = R; }
+
static bool classof(const Stmt *T) {
return T->getStmtClass() == CXXTypeidExprClass;
}
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 5d9b027..575881a 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -746,8 +746,9 @@
EXPR_CXX_FUNCTIONAL_CAST,
// \brief A CXXBoolLiteralExpr record.
EXPR_CXX_BOOL_LITERAL,
- // \brief A CXXNullPtrLiteralExpr record.
- EXPR_CXX_NULL_PTR_LITERAL
+ EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr
+ EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr).
+ EXPR_CXX_TYPEID_TYPE // CXXTypeidExpr (of type).
};
/// \brief The kinds of designators that can occur in a
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 394a894..cce2e26 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -126,6 +126,7 @@
unsigned VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
unsigned VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
unsigned VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
+ unsigned VisitCXXTypeidExpr(CXXTypeidExpr *E);
};
}
@@ -992,6 +993,19 @@
return 0;
}
+unsigned PCHStmtReader::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+ VisitExpr(E);
+ E->setSourceRange(Reader.ReadSourceRange(Record, Idx));
+ if (E->isTypeOperand()) { // typeid(int)
+ E->setTypeOperandSourceInfo(Reader.GetTypeSourceInfo(Record, Idx));
+ return 0;
+ }
+
+ // typeid(42+2)
+ return 1;
+}
+
+
// Within the bitstream, expressions are stored in Reverse Polish
// Notation, with each of the subexpressions preceding the
// expression they are stored in. To evaluate expressions, we
@@ -1341,6 +1355,12 @@
case pch::EXPR_CXX_NULL_PTR_LITERAL:
S = new (Context) CXXNullPtrLiteralExpr(Empty);
break;
+ case pch::EXPR_CXX_TYPEID_EXPR:
+ S = new (Context) CXXTypeidExpr(Empty, true);
+ break;
+ case pch::EXPR_CXX_TYPEID_TYPE:
+ S = new (Context) CXXTypeidExpr(Empty, false);
+ break;
}
// We hit a STMT_STOP, so we're done with this expression.
diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp
index 3c2022e..1e272c3 100644
--- a/lib/Frontend/PCHWriterStmt.cpp
+++ b/lib/Frontend/PCHWriterStmt.cpp
@@ -122,6 +122,7 @@
void VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr *E);
void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
void VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
+ void VisitCXXTypeidExpr(CXXTypeidExpr *E);
};
}
@@ -911,6 +912,18 @@
Code = pch::EXPR_CXX_NULL_PTR_LITERAL;
}
+void PCHStmtWriter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+ VisitExpr(E);
+ Writer.AddSourceRange(E->getSourceRange(), Record);
+ if (E->isTypeOperand()) {
+ Writer.AddTypeSourceInfo(E->getTypeOperandSourceInfo(), Record);
+ Code = pch::EXPR_CXX_TYPEID_TYPE;
+ } else {
+ Writer.WriteSubStmt(E->getExprOperand());
+ Code = pch::EXPR_CXX_TYPEID_EXPR;
+ }
+}
+
//===----------------------------------------------------------------------===//
// PCHWriter Implementation
//===----------------------------------------------------------------------===//
diff --git a/test/Makefile b/test/Makefile
index e9d8945..40170e4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -16,9 +16,9 @@
ifndef TESTARGS
ifdef VERBOSE
-TESTARGS = -v
+TESTARGS = -v -j16
else
-TESTARGS = -s -v
+TESTARGS = -s -v -j16
endif
endif
diff --git a/test/PCH/cxx_exprs.cpp b/test/PCH/cxx_exprs.cpp
index 0f0fe88..ec7041b 100644
--- a/test/PCH/cxx_exprs.cpp
+++ b/test/PCH/cxx_exprs.cpp
@@ -33,3 +33,7 @@
// CXXNullPtrLiteralExpr
cxx_null_ptr_result null_ptr = nullptr;
+
+// CXXTypeidExpr
+typeid_result1 typeid_1 = 0;
+typeid_result2 typeid_2 = 0;
\ No newline at end of file
diff --git a/test/PCH/cxx_exprs.h b/test/PCH/cxx_exprs.h
index 6766842..4f01b3a 100644
--- a/test/PCH/cxx_exprs.h
+++ b/test/PCH/cxx_exprs.h
@@ -1,5 +1,6 @@
// Header for PCH test cxx_exprs.cpp
+
// CXXStaticCastExpr
typedef __typeof__(static_cast<void *>(0)) static_cast_result;
@@ -31,4 +32,14 @@
void foo(Derived *P) {
// CXXMemberCallExpr
P->f();
-}
\ No newline at end of file
+}
+
+
+// FIXME: This is a hack until <typeinfo> works completely.
+namespace std {
+ class type_info {};
+}
+
+// CXXTypeidExpr - Both expr and type forms.
+typedef __typeof__(typeid(int))* typeid_result1;
+typedef __typeof__(typeid(2))* typeid_result2;