[cfe-commits] r89493 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/MinimalAction.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp test/SemaCXX/pseudo-destructors.cpp
Douglas Gregor
dgregor at apple.com
Fri Nov 20 14:03:39 PST 2009
Author: dgregor
Date: Fri Nov 20 16:03:38 2009
New Revision: 89493
URL: http://llvm.org/viewvc/llvm-project?rev=89493&view=rev
Log:
Implement C++ [basic.lookup.classref]p3, which states how the type
name 'T' is looked up in the expression
t.~T()
Previously, we weren't looking into the type of "t", and therefore
would fail when T actually referred to an injected-class-name. Fixes
PR5530.
Modified:
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/Parse/MinimalAction.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=89493&r1=89492&r2=89493&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Fri Nov 20 16:03:38 2009
@@ -203,11 +203,15 @@
/// this occurs when deriving from "std::vector<T>::allocator_type", where T
/// is a template parameter.
///
+ /// \param ObjectType if we're checking whether an identifier is a type
+ /// within a C++ member access expression, this will be the type of the
+ ///
/// \returns the type referred to by this identifier, or NULL if the type
/// does not name an identifier.
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS = 0,
- bool isClassName = false) = 0;
+ bool isClassName = false,
+ TypeTy *ObjectType = 0) = 0;
/// isTagName() - This method is called *for error recovery purposes only*
/// to determine if the specified name is a valid tag name ("struct foo"). If
@@ -2518,7 +2522,8 @@
/// does not name an identifier.
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS,
- bool isClassName = false);
+ bool isClassName = false,
+ TypeTy *ObjectType = 0);
/// isCurrentClassName - Always returns false, because MinimalAction
/// does not support C++ classes with constructors.
Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=89493&r1=89492&r2=89493&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Fri Nov 20 16:03:38 2009
@@ -144,7 +144,7 @@
Action::TypeTy *
MinimalAction::getTypeName(IdentifierInfo &II, SourceLocation Loc,
Scope *S, const CXXScopeSpec *SS,
- bool isClassName) {
+ bool isClassName, TypeTy *ObjectType) {
if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>())
if (TI->isTypeName)
return TI;
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=89493&r1=89492&r2=89493&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri Nov 20 16:03:38 2009
@@ -1010,7 +1010,7 @@
// Parse the type-specifier-seq.
DeclSpec DS;
- if (ParseCXXTypeSpecifierSeq(DS))
+ if (ParseCXXTypeSpecifierSeq(DS)) // FIXME: ObjectType?
return true;
// Parse the conversion-declarator, which is merely a sequence of
@@ -1152,7 +1152,7 @@
// Note that this is a destructor name.
Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc,
- CurScope, &SS);
+ CurScope, &SS, false, ObjectType);
if (!Ty) {
if (ObjectType)
Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89493&r1=89492&r2=89493&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Nov 20 16:03:38 2009
@@ -533,7 +533,8 @@
virtual TypeTy *getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS,
- bool isClassName = false);
+ bool isClassName = false,
+ TypeTy *ObjectType = 0);
virtual DeclSpec::TST isTagName(IdentifierInfo &II, Scope *S);
virtual bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
SourceLocation IILoc,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=89493&r1=89492&r2=89493&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Nov 20 16:03:38 2009
@@ -66,31 +66,68 @@
/// and then return NULL.
Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, const CXXScopeSpec *SS,
- bool isClassName) {
- // C++ [temp.res]p3:
- // A qualified-id that refers to a type and in which the
- // nested-name-specifier depends on a template-parameter (14.6.2)
- // shall be prefixed by the keyword typename to indicate that the
- // qualified-id denotes a type, forming an
- // elaborated-type-specifier (7.1.5.3).
- //
- // We therefore do not perform any name lookup if the result would
- // refer to a member of an unknown specialization.
- if (SS && isUnknownSpecialization(*SS)) {
- if (!isClassName)
+ bool isClassName,
+ TypeTy *ObjectTypePtr) {
+ // Determine where we will perform name lookup.
+ DeclContext *LookupCtx = 0;
+ if (ObjectTypePtr) {
+ QualType ObjectType = QualType::getFromOpaquePtr(ObjectTypePtr);
+ if (ObjectType->isRecordType())
+ LookupCtx = computeDeclContext(ObjectType);
+ } else if (SS && SS->isSet()) {
+ LookupCtx = computeDeclContext(*SS, false);
+
+ if (!LookupCtx) {
+ if (isDependentScopeSpecifier(*SS)) {
+ // C++ [temp.res]p3:
+ // A qualified-id that refers to a type and in which the
+ // nested-name-specifier depends on a template-parameter (14.6.2)
+ // shall be prefixed by the keyword typename to indicate that the
+ // qualified-id denotes a type, forming an
+ // elaborated-type-specifier (7.1.5.3).
+ //
+ // We therefore do not perform any name lookup if the result would
+ // refer to a member of an unknown specialization.
+ if (!isClassName)
+ return 0;
+
+ // We know from the grammar that this name refers to a type, so build a
+ // TypenameType node to describe the type.
+ // FIXME: Record somewhere that this TypenameType node has no "typename"
+ // keyword associated with it.
+ return CheckTypenameType((NestedNameSpecifier *)SS->getScopeRep(),
+ II, SS->getRange()).getAsOpaquePtr();
+ }
+
+ return 0;
+ }
+
+ if (!LookupCtx->isDependentContext() && RequireCompleteDeclContext(*SS))
return 0;
-
- // We know from the grammar that this name refers to a type, so build a
- // TypenameType node to describe the type.
- // FIXME: Record somewhere that this TypenameType node has no "typename"
- // keyword associated with it.
- return CheckTypenameType((NestedNameSpecifier *)SS->getScopeRep(),
- II, SS->getRange()).getAsOpaquePtr();
}
-
+
LookupResult Result(*this, &II, NameLoc, LookupOrdinaryName);
- LookupParsedName(Result, S, SS, false);
-
+ if (LookupCtx) {
+ // Perform "qualified" name lookup into the declaration context we
+ // computed, which is either the type of the base of a member access
+ // expression or the declaration context associated with a prior
+ // nested-name-specifier.
+ LookupQualifiedName(Result, LookupCtx);
+
+ if (ObjectTypePtr && Result.empty()) {
+ // C++ [basic.lookup.classref]p3:
+ // If the unqualified-id is ~type-name, the type-name is looked up
+ // in the context of the entire postfix-expression. If the type T of
+ // the object expression is of a class type C, the type-name is also
+ // looked up in the scope of class C. At least one of the lookups shall
+ // find a name that refers to (possibly cv-qualified) T.
+ LookupName(Result, S);
+ }
+ } else {
+ // Perform unqualified name lookup.
+ LookupName(Result, S);
+ }
+
NamedDecl *IIDecl = 0;
switch (Result.getResultKind()) {
case LookupResult::NotFound:
Modified: cfe/trunk/test/SemaCXX/pseudo-destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pseudo-destructors.cpp?rev=89493&r1=89492&r2=89493&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/pseudo-destructors.cpp (original)
+++ cfe/trunk/test/SemaCXX/pseudo-destructors.cpp Fri Nov 20 16:03:38 2009
@@ -38,3 +38,12 @@
void destroy_without_call(int *ip) {
ip->~Integer; // expected-error{{called immediately}}
}
+
+// PR5530
+namespace N1 {
+ class X0 { };
+}
+
+void test_X0(N1::X0 &x0) {
+ x0.~X0();
+}
More information about the cfe-commits
mailing list