SemaCXXScopeSpec.cpp revision 3dde5a3fa28cae4b8b2fb060abc0bfc2b4425ed8
1//===--- SemaCXXScopeSpec.cpp - Semantic Analysis for C++ scope specifiers-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements C++ semantic analysis for scope specifiers. 11// 12//===----------------------------------------------------------------------===// 13 14#include "Sema.h" 15#include "clang/AST/ASTContext.h" 16#include "clang/Parse/DeclSpec.h" 17#include "clang/Basic/Diagnostic.h" 18#include "llvm/ADT/STLExtras.h" 19using namespace clang; 20 21 22namespace { 23 Decl *LookupNestedName(DeclContext *LookupCtx, bool LookInParentCtx, 24 DeclarationName Name, bool &IdIsUndeclared, 25 ASTContext &Context) { 26 if (LookupCtx && !LookInParentCtx) { 27 IdIsUndeclared = true; 28 DeclContext::lookup_const_iterator I, E; 29 for (llvm::tie(I, E) = LookupCtx->lookup(Context, Name); I != E; ++I) { 30 IdIsUndeclared = false; 31 if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag) || 32 isa<TypedefDecl>(*I)) 33 return *I; 34 } 35 36 return 0; 37 } 38 39 // FIXME: Decouple this from the IdentifierResolver so that we can 40 // deal with lookups into the semantic parent contexts that aren't 41 // lexical parent contexts. 42 43 IdentifierResolver::iterator 44 I = IdentifierResolver::begin(Name, LookupCtx, LookInParentCtx), 45 E = IdentifierResolver::end(); 46 47 if (I == E) { 48 IdIsUndeclared = true; 49 return 0; 50 } 51 IdIsUndeclared = false; 52 53 // C++ 3.4.3p1 : 54 // During the lookup for a name preceding the :: scope resolution operator, 55 // object, function, and enumerator names are ignored. If the name found is 56 // not a class-name or namespace-name, the program is ill-formed. 57 58 for (; I != E; ++I) { 59 if (isa<TypedefDecl>(*I)) { 60 break; 61 } 62 if (((*I)->getIdentifierNamespace() & Decl::IDNS_Tag)) 63 break; 64 } 65 66 return (I != E ? *I : 0); 67 } 68} // anonymous namespace 69 70/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the 71/// global scope ('::'). 72Sema::CXXScopeTy *Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, 73 SourceLocation CCLoc) { 74 return cast<DeclContext>(Context.getTranslationUnitDecl()); 75} 76 77/// ActOnCXXNestedNameSpecifier - Called during parsing of a 78/// nested-name-specifier. e.g. for "foo::bar::" we parsed "foo::" and now 79/// we want to resolve "bar::". 'SS' is empty or the previously parsed 80/// nested-name part ("foo::"), 'IdLoc' is the source location of 'bar', 81/// 'CCLoc' is the location of '::' and 'II' is the identifier for 'bar'. 82/// Returns a CXXScopeTy* object representing the C++ scope. 83Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, 84 const CXXScopeSpec &SS, 85 SourceLocation IdLoc, 86 SourceLocation CCLoc, 87 IdentifierInfo &II) { 88 DeclContext *DC = static_cast<DeclContext*>(SS.getScopeRep()); 89 Decl *SD; 90 bool IdIsUndeclared; 91 92 if (DC) 93 SD = LookupNestedName(DC, false/*LookInParentCtx*/, &II, IdIsUndeclared, 94 Context); 95 else 96 SD = LookupNestedName(CurContext, true/*LookInParent*/, &II, 97 IdIsUndeclared, Context); 98 99 if (SD) { 100 if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) { 101 if (const RecordType* Record = TD->getUnderlyingType()->getAsRecordType()) 102 return cast<DeclContext>(Record->getDecl()); 103 } else if (isa<NamespaceDecl>(SD) || isa<RecordDecl>(SD)) { 104 return cast<DeclContext>(SD); 105 } 106 107 // Fall through to produce an error: we found something that isn't 108 // a class or a namespace. 109 } 110 111 unsigned DiagID; 112 if (!IdIsUndeclared) 113 DiagID = diag::err_expected_class_or_namespace; 114 else if (DC) 115 DiagID = diag::err_typecheck_no_member; 116 else 117 DiagID = diag::err_undeclared_var_use; 118 119 if (DC) 120 Diag(IdLoc, DiagID) << &II << SS.getRange(); 121 else 122 Diag(IdLoc, DiagID) << &II; 123 124 return 0; 125} 126 127/// ActOnCXXEnterDeclaratorScope - Called when a C++ scope specifier (global 128/// scope or nested-name-specifier) is parsed, part of a declarator-id. 129/// After this method is called, according to [C++ 3.4.3p3], names should be 130/// looked up in the declarator-id's scope, until the declarator is parsed and 131/// ActOnCXXExitDeclaratorScope is called. 132/// The 'SS' should be a non-empty valid CXXScopeSpec. 133void Sema::ActOnCXXEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { 134 assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); 135 assert(PreDeclaratorDC == 0 && "Previous declarator context not popped?"); 136 PreDeclaratorDC = static_cast<DeclContext*>(S->getEntity()); 137 S->setEntity(static_cast<DeclContext*>(SS.getScopeRep())); 138} 139 140/// ActOnCXXExitDeclaratorScope - Called when a declarator that previously 141/// invoked ActOnCXXEnterDeclaratorScope(), is finished. 'SS' is the same 142/// CXXScopeSpec that was passed to ActOnCXXEnterDeclaratorScope as well. 143/// Used to indicate that names should revert to being looked up in the 144/// defining scope. 145void Sema::ActOnCXXExitDeclaratorScope(Scope *S, const CXXScopeSpec &SS) { 146 assert(SS.isSet() && "Parser passed invalid CXXScopeSpec."); 147 assert(S->getEntity() == SS.getScopeRep() && "Context imbalance!"); 148 S->setEntity(PreDeclaratorDC); 149 PreDeclaratorDC = 0; 150} 151