[cfe-commits] r59042 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Parse/ lib/AST/ lib/Parse/ lib/Sema/ test/Parser/ test/SemaCXX/ www/
Sebastian Redl
sebastian.redl at getdesigned.at
Tue Nov 11 03:38:03 PST 2008
Author: cornedbee
Date: Tue Nov 11 05:37:55 2008
New Revision: 59042
URL: http://llvm.org/viewvc/llvm-project?rev=59042&view=rev
Log:
Implement C++ 'typeid' parsing and sema.
Added:
cfe/trunk/test/Parser/cxx-typeid.cpp
cfe/trunk/test/SemaCXX/typeid.cpp
Modified:
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/AST/StmtNodes.def
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprCXX.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/StmtSerialization.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/IdentifierResolver.cpp
cfe/trunk/lib/Sema/IdentifierResolver.h
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/www/cxx_status.html
Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Nov 11 05:37:55 2008
@@ -154,6 +154,47 @@
virtual child_iterator child_end();
};
+/// CXXTypeidExpr - A C++ @c typeid expression (C++ [expr.typeid]), which gets
+/// the type_info that corresponds to the supplied type, or the (possibly
+/// dynamic) type of the supplied expression.
+///
+/// This represents code like @c typeid(int) or @c typeid(*objPtr)
+class CXXTypeidExpr : public Expr {
+private:
+ bool isTypeOp : 1;
+ void *Operand;
+ SourceRange Range;
+
+public:
+ CXXTypeidExpr(bool isTypeOp, void *op, QualType Ty, const SourceRange r) :
+ Expr(CXXTypeidExprClass, Ty), isTypeOp(isTypeOp), Operand(op), Range(r) {}
+
+ bool isTypeOperand() const { return isTypeOp; }
+ QualType getTypeOperand() const {
+ assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)");
+ return QualType::getFromOpaquePtr(Operand);
+ }
+ Expr* getExprOperand() const {
+ assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)");
+ return static_cast<Expr*>(Operand);
+ }
+
+ virtual SourceRange getSourceRange() const {
+ return Range;
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == CXXTypeidExprClass;
+ }
+ static bool classof(const CXXTypeidExpr *) { return true; }
+
+ // Iterators
+ virtual child_iterator child_begin();
+ virtual child_iterator child_end();
+
+ virtual void EmitImpl(llvm::Serializer& S) const;
+ static CXXTypeidExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
+};
+
/// CXXThisExpr - Represents the "this" expression in C++, which is a
/// pointer to the object on which the current member function is
/// executing (C++ [expr.prim]p3). Example:
Modified: cfe/trunk/include/clang/AST/StmtNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtNodes.def?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/StmtNodes.def (original)
+++ cfe/trunk/include/clang/AST/StmtNodes.def Tue Nov 11 05:37:55 2008
@@ -96,12 +96,13 @@
STMT(63, CXXReinterpretCastExpr , CXXNamedCastExpr)
STMT(64, CXXConstCastExpr , CXXNamedCastExpr)
STMT(65, CXXFunctionalCastExpr , Expr)
-STMT(66, CXXBoolLiteralExpr , Expr)
-STMT(67, CXXThisExpr , Expr)
-STMT(68, CXXThrowExpr , Expr)
-STMT(69, CXXDefaultArgExpr , Expr)
-STMT(70, CXXZeroInitValueExpr , Expr)
-STMT(71, CXXConditionDeclExpr , DeclRefExpr)
+STMT(66, CXXTypeidExpr , Expr)
+STMT(67, CXXBoolLiteralExpr , Expr)
+STMT(68, CXXThisExpr , Expr)
+STMT(69, CXXThrowExpr , Expr)
+STMT(70, CXXDefaultArgExpr , Expr)
+STMT(71, CXXZeroInitValueExpr , Expr)
+STMT(72, CXXConditionDeclExpr , DeclRefExpr)
// Obj-C Expressions.
STMT(80, ObjCStringLiteral , Expr)
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Tue Nov 11 05:37:55 2008
@@ -1157,6 +1157,10 @@
DIAG(err_static_downcast_via_virtual, ERROR,
"cannot cast '%0' to '%1' via virtual base '%2'")
+// Other C++ expressions
+DIAG(err_need_header_before_typeid, ERROR,
+ "you need to include <typeinfo> before using the 'typeid' operator")
+
DIAG(err_invalid_use_of_function_type, ERROR,
"a function type is not allowed here")
DIAG(err_invalid_use_of_array_type, ERROR,
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Nov 11 05:37:55 2008
@@ -676,6 +676,13 @@
return 0;
}
+ /// ActOnCXXTypeidOfType - Parse typeid( type-id ).
+ virtual ExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+ SourceLocation LParenLoc, bool isType,
+ void *TyOrExpr, SourceLocation RParenLoc) {
+ return 0;
+ }
+
/// ActOnCXXThis - Parse the C++ 'this' pointer.
virtual ExprResult ActOnCXXThis(SourceLocation ThisLoc) {
return 0;
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Nov 11 05:37:55 2008
@@ -505,6 +505,10 @@
ExprResult ParseCXXCasts();
//===--------------------------------------------------------------------===//
+ // C++ 5.2p1: C++ Type Identification
+ ExprResult ParseCXXTypeid();
+
+ //===--------------------------------------------------------------------===//
// C++ 9.3.2: C++ 'this' pointer
ExprResult ParseCXXThis();
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Nov 11 05:37:55 2008
@@ -437,6 +437,9 @@
if (cast<ExplicitCastExpr>(this)->getTypeAsWritten()->isReferenceType())
return LV_Valid;
break;
+ case CXXTypeidExprClass:
+ // C++ 5.2.8p1: The result of a typeid expression is an lvalue of ...
+ return LV_Valid;
case CXXThisExprClass:
return LV_InvalidExpression;
default:
Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Nov 11 05:37:55 2008
@@ -24,6 +24,13 @@
// Child Iterators for iterating over subexpressions/substatements
//===----------------------------------------------------------------------===//
+// CXXTypeidExpr - has child iterators if the operand is an expression
+Stmt::child_iterator CXXTypeidExpr::child_begin() {
+ return isTypeOperand() ? child_iterator() : (Stmt**)&Operand;
+}
+Stmt::child_iterator CXXTypeidExpr::child_end() {
+ return isTypeOperand() ? child_iterator() : (Stmt**)&Operand+1;
+}
// CXXBoolLiteralExpr
Stmt::child_iterator CXXBoolLiteralExpr::child_begin() {
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Nov 11 05:37:55 2008
@@ -832,6 +832,16 @@
VisitCXXNamedCastExpr(Node);
}
+void StmtPrinter::VisitCXXTypeidExpr(CXXTypeidExpr *Node) {
+ OS << "typeid(";
+ if (Node->isTypeOperand()) {
+ OS << Node->getTypeOperand().getAsString();
+ } else {
+ PrintExpr(Node->getExprOperand());
+ }
+ OS << ")";
+}
+
void StmtPrinter::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) {
OS << (Node->getValue() ? "true" : "false");
}
Modified: cfe/trunk/lib/AST/StmtSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtSerialization.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtSerialization.cpp (original)
+++ cfe/trunk/lib/AST/StmtSerialization.cpp Tue Nov 11 05:37:55 2008
@@ -216,6 +216,9 @@
case CXXConstCastExprClass:
return CXXConstCastExpr::CreateImpl(D, C, SC);
+ case CXXTypeidExprClass:
+ return CXXTypeidExpr::CreateImpl(D, C);
+
case CXXThisExprClass:
return CXXThisExpr::CreateImpl(D, C);
@@ -1346,6 +1349,31 @@
}
}
+void CXXTypeidExpr::EmitImpl(llvm::Serializer& S) const {
+ S.Emit(getType());
+ S.Emit(isTypeOperand());
+ if (isTypeOperand()) {
+ S.Emit(getTypeOperand());
+ } else {
+ S.EmitOwnedPtr(getExprOperand());
+ }
+ S.Emit(Range);
+}
+
+CXXTypeidExpr*
+CXXTypeidExpr::CreateImpl(llvm::Deserializer& D, ASTContext& C) {
+ QualType Ty = QualType::ReadVal(D);
+ bool isTypeOp = D.ReadBool();
+ void *Operand;
+ if (isTypeOp) {
+ Operand = QualType::ReadVal(D).getAsOpaquePtr();
+ } else {
+ Operand = D.ReadOwnedPtr<Expr>(C);
+ }
+ SourceRange Range = SourceRange::ReadVal(D);
+ return new CXXTypeidExpr(isTypeOp, Operand, Ty, Range);
+}
+
void CXXThisExpr::EmitImpl(llvm::Serializer& S) const {
S.Emit(getType());
S.Emit(Loc);
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Nov 11 05:37:55 2008
@@ -357,7 +357,7 @@
///
/// primary-expression: [C99 6.5.1]
/// [C99] identifier
-// [C++] id-expression
+/// [C++] id-expression
/// constant
/// string-literal
/// [C++] boolean-literal [C++ 2.13.5]
@@ -382,6 +382,8 @@
/// [C++] 'dynamic_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++] 'reinterpret_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
/// [C++] 'static_cast' '<' type-name '>' '(' expression ')' [C++ 5.2p1]
+/// [C++] 'typeid' '(' expression ')' [C++ 5.2p1]
+/// [C++] 'typeid' '(' type-id ')' [C++ 5.2p1]
/// [C++] 'this' [C++ 9.3.2]
/// [clang] '^' block-literal
///
@@ -567,6 +569,10 @@
Res = ParseCXXCasts();
// These can be followed by postfix-expr pieces.
return ParsePostfixExpressionSuffix(Res);
+ case tok::kw_typeid:
+ Res = ParseCXXTypeid();
+ // This can be followed by postfix-expr pieces.
+ return ParsePostfixExpressionSuffix(Res);
case tok::kw_this:
Res = ParseCXXThis();
// This can be followed by postfix-expr pieces.
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Nov 11 05:37:55 2008
@@ -216,6 +216,54 @@
return Result;
}
+/// ParseCXXTypeid - This handles the C++ typeid expression.
+///
+/// postfix-expression: [C++ 5.2p1]
+/// 'typeid' '(' expression ')'
+/// 'typeid' '(' type-id ')'
+///
+Parser::ExprResult Parser::ParseCXXTypeid() {
+ assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!");
+
+ SourceLocation OpLoc = ConsumeToken();
+ SourceLocation LParenLoc = Tok.getLocation();
+ SourceLocation RParenLoc;
+
+ // typeid expressions are always parenthesized.
+ if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+ "typeid"))
+ return ExprResult(true);
+
+ Parser::ExprResult Result;
+
+ if (isTypeIdInParens()) {
+ TypeTy *Ty = ParseTypeName();
+
+ // Match the ')'.
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+ if (!Ty)
+ return ExprResult(true);
+
+ Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true,
+ Ty, RParenLoc);
+ } else {
+ Result = ParseExpression();
+
+ // Match the ')'.
+ if (Result.isInvalid)
+ SkipUntil(tok::r_paren);
+ else {
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
+
+ Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/false,
+ Result.Val, RParenLoc);
+ }
+ }
+
+ return Result;
+}
+
/// ParseCXXBoolLiteral - This handles the C++ Boolean literals.
///
/// boolean-literal: [C++ 2.13.5]
Modified: cfe/trunk/lib/Sema/IdentifierResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.cpp (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.cpp Tue Nov 11 05:37:55 2008
@@ -243,7 +243,7 @@
/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
/// decls of parent declaration contexts too.
IdentifierResolver::iterator
-IdentifierResolver::begin(const IdentifierInfo *II, DeclContext *Ctx,
+IdentifierResolver::begin(const IdentifierInfo *II, const DeclContext *Ctx,
bool LookInParentCtx) {
assert(Ctx && "null param passed");
Modified: cfe/trunk/lib/Sema/IdentifierResolver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/IdentifierResolver.h?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/IdentifierResolver.h (original)
+++ cfe/trunk/lib/Sema/IdentifierResolver.h Tue Nov 11 05:37:55 2008
@@ -31,7 +31,7 @@
/// ScopedDecls, LookupContext can be used with all decls (assumes
/// translation unit context for non ScopedDecls).
class LookupContext {
- DeclContext *Ctx;
+ const DeclContext *Ctx;
/// TUCtx - Provides a common value for translation unit context for all
/// decls.
@@ -49,7 +49,7 @@
LookupContext(Decl *D) {
Ctx = getContext(D);
}
- LookupContext(DeclContext *DC) {
+ LookupContext(const DeclContext *DC) {
if (!DC || isa<TranslationUnitDecl>(DC))
Ctx = TUCtx();
else
@@ -196,7 +196,7 @@
/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
/// decls of parent declaration contexts too.
/// Default for 'LookInParentCtx is true.
- static iterator begin(const IdentifierInfo *II, DeclContext *Ctx,
+ static iterator begin(const IdentifierInfo *II, const DeclContext *Ctx,
bool LookInParentCtx = true);
/// end - Returns an iterator that has 'finished'.
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Nov 11 05:37:55 2008
@@ -113,6 +113,10 @@
Ident_SEL = &IT.get("SEL");
Ident_Protocol = &IT.get("Protocol");
+ Ident_StdNs = &IT.get("std");
+ Ident_TypeInfo = 0;
+ StdNamespace = 0;
+
TUScope = 0;
if (getLangOptions().CPlusPlus)
FieldCollector.reset(new CXXFieldCollector());
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 11 05:37:55 2008
@@ -199,10 +199,18 @@
IdentifierInfo *Ident_id, *Ident_Class; // "id", "Class"
IdentifierInfo *Ident_SEL, *Ident_Protocol; // "SEL", "Protocol"
+ /// Identifiers used by the C++ language
+ IdentifierInfo *Ident_StdNs; // "std"
+ IdentifierInfo *Ident_TypeInfo; // "type_info" - lazily created
+
/// Translation Unit Scope - useful to Objective-C actions that need
/// to lookup file scope declarations in the "ordinary" C decl namespace.
/// For example, user-defined classes, built-in "id" type, etc.
Scope *TUScope;
+
+ /// The C++ "std" namespace, where the standard library resides. Cached here
+ /// by GetStdNamespace
+ NamespaceDecl *StdNamespace;
/// ObjCMethodList - a linked list of methods with different signatures.
struct ObjCMethodList {
@@ -450,7 +458,7 @@
/// More parsing and symbol table subroutines...
Decl *LookupDecl(const IdentifierInfo *II, unsigned NSI, Scope *S,
- DeclContext *LookupCtx = 0,
+ const DeclContext *LookupCtx = 0,
bool enableLazyBuiltinCreation = true);
ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *Id);
ScopedDecl *LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID,
@@ -463,6 +471,8 @@
void WarnUndefinedMethod(SourceLocation ImpLoc, ObjCMethodDecl *method,
bool &IncompleteImpl);
+
+ NamespaceDecl *GetStdNamespace();
/// CheckProtocolMethodDefs - This routine checks unimpletented
/// methods declared in protocol, and those referenced by it.
@@ -751,6 +761,11 @@
SourceLocation LParenLoc, ExprTy *E,
SourceLocation RParenLoc);
+ /// ActOnCXXTypeidOfType - Parse typeid( type-id ).
+ virtual ExprResult ActOnCXXTypeid(SourceLocation OpLoc,
+ SourceLocation LParenLoc, bool isType,
+ void *TyOrExpr, SourceLocation RParenLoc);
+
//// ActOnCXXThis - Parse 'this' pointer.
virtual ExprResult ActOnCXXThis(SourceLocation ThisLoc);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Nov 11 05:37:55 2008
@@ -193,7 +193,8 @@
/// LookupDecl - Look up the inner-most declaration in the specified
/// namespace.
Decl *Sema::LookupDecl(const IdentifierInfo *II, unsigned NSI, Scope *S,
- DeclContext *LookupCtx, bool enableLazyBuiltinCreation) {
+ const DeclContext *LookupCtx,
+ bool enableLazyBuiltinCreation) {
if (II == 0) return 0;
unsigned NS = NSI;
if (getLangOptions().CPlusPlus && (NS & Decl::IDNS_Ordinary))
@@ -278,6 +279,18 @@
return New;
}
+/// GetStdNamespace - This method gets the C++ "std" namespace. This is where
+/// everything from the standard library is defined.
+NamespaceDecl *Sema::GetStdNamespace() {
+ if (!StdNamespace) {
+ DeclContext *Global = Context.getTranslationUnitDecl();
+ Decl *Std = LookupDecl(Ident_StdNs, Decl::IDNS_Tag | Decl::IDNS_Ordinary,
+ 0, Global, /*enableLazyBuiltinCreation=*/false);
+ StdNamespace = dyn_cast_or_null<NamespaceDecl>(Std);
+ }
+ return StdNamespace;
+}
+
/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
/// and scope as a previous declaration 'Old'. Figure out how to resolve this
/// situation, merging decls or emitting diagnostics as appropriate.
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov 11 05:37:55 2008
@@ -19,6 +19,34 @@
#include "clang/Basic/Diagnostic.h"
using namespace clang;
+
+/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
+Action::ExprResult
+Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
+ bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
+ const NamespaceDecl *StdNs = GetStdNamespace();
+ if (!StdNs) {
+ Diag(OpLoc, diag::err_need_header_before_typeid);
+ return ExprResult(true);
+ }
+ if (!Ident_TypeInfo) {
+ Ident_TypeInfo = &PP.getIdentifierTable().get("type_info");
+ }
+ Decl *TypeInfoDecl = LookupDecl(Ident_TypeInfo,
+ Decl::IDNS_Tag | Decl::IDNS_Ordinary,
+ 0, StdNs, /*createBuiltins=*/false);
+ RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null<RecordDecl>(TypeInfoDecl);
+ if (!TypeInfoRecordDecl) {
+ Diag(OpLoc, diag::err_need_header_before_typeid);
+ return ExprResult(true);
+ }
+
+ QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl);
+
+ return new CXXTypeidExpr(isType, TyOrExpr, TypeInfoType.withConst(),
+ SourceRange(OpLoc, RParenLoc));
+}
+
/// ActOnCXXBoolLiteral - Parse {true,false} literals.
Action::ExprResult
Sema::ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind) {
Added: cfe/trunk/test/Parser/cxx-typeid.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-typeid.cpp?rev=59042&view=auto
==============================================================================
--- cfe/trunk/test/Parser/cxx-typeid.cpp (added)
+++ cfe/trunk/test/Parser/cxx-typeid.cpp Tue Nov 11 05:37:55 2008
@@ -0,0 +1,13 @@
+// RUN: clang -fsyntax-only -verify %s
+
+// FIXME: This should really include <typeinfo>, but we don't have that yet.
+namespace std {
+ class type_info;
+}
+
+void f()
+{
+ (void)typeid(int);
+ (void)typeid(0);
+ (void)typeid 1; // expected-error {{error: expected '(' after 'typeid'}}
+}
Added: cfe/trunk/test/SemaCXX/typeid.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typeid.cpp?rev=59042&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/typeid.cpp (added)
+++ cfe/trunk/test/SemaCXX/typeid.cpp Tue Nov 11 05:37:55 2008
@@ -0,0 +1,16 @@
+// RUN: clang -fsyntax-only -verify %s
+
+void f()
+{
+ (void)typeid(int); // expected-error {{error: you need to include <typeinfo> before using the 'typeid' operator}}
+}
+
+// FIXME: This should really include <typeinfo>, but we don't have that yet.
+namespace std {
+ class type_info;
+}
+
+void g()
+{
+ (void)typeid(int);
+}
Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=59042&r1=59041&r2=59042&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Tue Nov 11 05:37:55 2008
@@ -466,9 +466,9 @@
</tr>
<tr>
<td> 5.2.8 [expr.typeid]</td>
- <td></td>
- <td></td>
- <td></td>
+ <td class="complete" align="center">✓</td>
+ <td class="complete" align="center">✓</td>
+ <td class="complete" align="center">✓</td>
<td></td>
<td></td>
</tr>
More information about the cfe-commits
mailing list