diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-11-11 11:37:55 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-11-11 11:37:55 +0000 |
commit | c42e1183846228a7fa5143ad76507d6d60f5c6f3 (patch) | |
tree | 04bcf44fb748f6c8e9296e4601dcdb64edc7258b /lib/Sema | |
parent | d57a871339c7c98d58d93108b806f59bdf4e13e2 (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.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/IdentifierResolver.h | 6 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 28 |
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) { |