[cfe-commits] r58916 - in /cfe/trunk: include/clang/AST/DeclBase.h include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticKinds.def lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaCXXScopeSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp test/SemaCXX/nested-name-spec.cpp
Argiris Kirtzidis
akyrtzi at gmail.com
Fri Nov 14 14:26:32 PST 2008
Douglas Gregor wrote:
>
>> + bool isFileContext() const {
>> + return DeclKind == Decl::TranslationUnit || DeclKind ==
>> Decl::Namespace;
>> + }
>
> isFileContext seems like a weird name for this function... I would
> have called it isNamespaceContext, since the translation unit context
> is the same as the global namespace context for name lookup's purposes.
isFileContext makes it more language-neutral (namespace is a C++ thing),
similar e.g. to VarDecl::isFileVarDecl.
But I don't particularly care, let me know if you still think I should
change it.
>
>> +DIAG(err_not_tag_in_scope, ERROR,
>> + "'%0' does not name a tag member in the specified scope")
>
> The term "tag" is very much a compiler-writers term. Could we replace
> tag with '%1' and fill in the appropriate tag kind (struct, class,
> union, enum)?
'tag' is mentioned by GCC, Comeau, and Clang in other diags ("use of
'%0' with tag type that does not match previous declaration").
Again, let me know about changing it or not.
>
>> + /// PreDeclaratorDC - Keeps the declaration context before
>> switching to the
>> + /// context of a declarator's nested-name-specifier.
>> + DeclContext *PreDeclaratorDC;
>
> I assume that we'll eventually need this to be a stack of DeclContext
> *'s, to deal with something like:
>
> ::foo::bar<wibble::wonka>::type
>
> Perhaps we should just make it a stack now so we're ready for the future.
I prefer to avoid a stack, if it's possible, in favor of stricter
invariants of how DeclContext changes.
In your particular example I don't think a stack is required, it's just
nested-name-specifier parsing which doesn't change Sema's CurContext
(wibble::wonka isn't looked up in the context of ::foo, right ?)
>
>> +namespace {
>> + Decl *LookupNestedName(DeclContext *LookupCtx, bool LookInParentCtx,
>> + const IdentifierInfo &II, bool
>> &IdIsUndeclared) {
>>
>> + IdentifierResolver::iterator
>> + I = IdentifierResolver::begin(&II, LookupCtx, LookInParentCtx),
>> + E = IdentifierResolver::end();
>> +
>> + if (I == E) {
>> + IdIsUndeclared = true;
>> + return 0;
>> + }
>> + IdIsUndeclared = false;
>> +
>> + // C++ 3.4.3p1 :
>> + // During the lookup for a name preceding the :: scope
>> resolution operator,
>> + // object, function, and enumerator names are ignored. If the
>> name found is
>> + // not a class-name or namespace-name, the program is ill-formed.
>> +
>> + for (; I != E; ++I) {
>> + if (TypedefDecl *TD = dyn_cast<TypedefDecl>(*I)) {
>> + if (TD->getUnderlyingType()->isRecordType())
>> + break;
>> + continue;
>> + }
>> + if (((*I)->getIdentifierNamespace()&Decl::IDNS_Tag) &&
>> !isa<EnumDecl>(*I))
>> + break;
>> + }
>
> I don't think this is quite right for C++03. The standard says that we
> ignore enumerator names (e.g., an EnumConstantDecl), but the check in
> the "if" is skipping enumeration names (EnumDecl). Here's an example
> where it matters:
>
> namespace N {
> struct C {
> static float X;
> };
>
> typedef C Typedef;
>
> namespace M {
> enum E {
> X = 17
> };
>
> typedef E Typedef;
>
> void test() {
> float& f = Typedef::X;
> }
> }
> }
>
> GCC rejects this example:
>
> /Users/dgregor/foo.C: In function ‘void N::M::test()’:
> /Users/dgregor/foo.C:16: error: ‘Typedef’ is not a class or namespace
>
> Interestingly, EDG accepts the example, and so does Clang, but I'm
> pretty certain that both are wrong. Qualified name lookup should find
> the typedef for the enumeration 'E', and then fail because we can't do
> qualified name lookup into an enumeration type in C++03.
MSVC and Comeau also accept the example. I find this weird, I thought
EDG and Comeau have a high standard-conformance reputation; and that the
enumeration is ignored because enumerations don't participate in
qualified name lookup.
> In C++0x, we *can* do qualified name lookup into an enumeration, so
> the example fails because we can't bind an 'int' to a reference to a
> 'float'.
I was under the impression that this happens to 'enum class' which is
different from 'enum'. You can do qualified name lookup even with simple
enums (not 'enum class') ?
-Argiris
More information about the cfe-commits
mailing list