aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2008-11-11 11:37:55 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2008-11-11 11:37:55 +0000
commitc42e1183846228a7fa5143ad76507d6d60f5c6f3 (patch)
tree04bcf44fb748f6c8e9296e4601dcdb64edc7258b /lib/Sema
parentd57a871339c7c98d58d93108b806f59bdf4e13e2 (diff)
Implement C++ 'typeid' parsing and sema.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59042 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/IdentifierResolver.cpp2
-rw-r--r--lib/Sema/IdentifierResolver.h6
-rw-r--r--lib/Sema/Sema.cpp4
-rw-r--r--lib/Sema/Sema.h17
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--lib/Sema/SemaExprCXX.cpp28
6 files changed, 66 insertions, 6 deletions
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 8375720e55..82f95bf108 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -243,7 +243,7 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) {
/// 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");
diff --git a/lib/Sema/IdentifierResolver.h b/lib/Sema/IdentifierResolver.h
index c661145d89..e76bec6ee2 100644
--- a/lib/Sema/IdentifierResolver.h
+++ b/lib/Sema/IdentifierResolver.h
@@ -31,7 +31,7 @@ class IdentifierResolver {
/// 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 @@ class IdentifierResolver {
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 @@ public:
/// 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'.
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 532be59cd4..9c8d0c8bcb 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -113,6 +113,10 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer)
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());
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3b187f2099..7f72928064 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -199,10 +199,18 @@ public:
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 @@ public:
/// 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 @@ public:
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 @@ public:
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);
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 879a79b633..b595ad7f31 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -193,7 +193,8 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
/// 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 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
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.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index a6a62a9e37..e420ce5991 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -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) {