[cfe-commits] r68251 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp lib/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaInherit.cpp lib/Sema/SemaInherit.h lib/Sema/SemaLookup.cpp lib/Sema/SemaTemplate.cpp test/SemaCXX/member-name-lookup.cpp test/SemaCXX/using-directive.cpp test/SemaTemplate/nested-name-spec-template.cpp
Douglas Gregor
dgregor at apple.com
Wed Apr 1 14:51:27 PDT 2009
Author: dgregor
Date: Wed Apr 1 16:51:26 2009
New Revision: 68251
URL: http://llvm.org/viewvc/llvm-project?rev=68251&view=rev
Log:
Make parsing a semantic analysis a little more robust following Sema
failures that involve malformed types, e.g., "typename X::foo" where
"foo" isn't a type, or "std::vector<void>" that doens't instantiate
properly.
Similarly, be a bit smarter in our handling of ambiguities that occur
in Sema::getTypeName, to eliminate duplicate error messages about
ambiguous name lookup.
This eliminates two XFAILs in test/SemaCXX, one of which was crying
out to us, trying to tell us that we were producing repeated error
messages.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaInherit.cpp
cfe/trunk/lib/Sema/SemaInherit.h
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaCXX/member-name-lookup.cpp
cfe/trunk/test/SemaCXX/using-directive.cpp
cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Apr 1 16:51:26 2009
@@ -1005,8 +1005,8 @@
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
- TypeTy *ParseClassName(SourceLocation &EndLocation,
- const CXXScopeSpec *SS = 0);
+ TypeResult ParseClassName(SourceLocation &EndLocation,
+ const CXXScopeSpec *SS = 0);
void ParseClassSpecifier(DeclSpec &DS,
TemplateParameterLists *TemplateParams = 0,
AccessSpecifier AS = AS_none);
@@ -1065,7 +1065,7 @@
const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
- bool AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
+ void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs,
TemplateArgIsTypeList &TemplateArgIsType,
TemplateArgLocationList &TemplateArgLocations);
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Apr 1 16:51:26 2009
@@ -558,8 +558,11 @@
}
case tok::annot_typename: {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- Tok.getAnnotationValue());
+ if (Tok.getAnnotationValue())
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+ Tok.getAnnotationValue());
+ else
+ DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeToken(); // The typename
@@ -648,9 +651,7 @@
// Turn the template-id annotation token into a type annotation
// token, then try again to parse it as a type-specifier.
- if (AnnotateTemplateIdTokenAsType())
- DS.SetTypeSpecError();
-
+ AnnotateTemplateIdTokenAsType();
continue;
}
@@ -915,8 +916,11 @@
// simple-type-specifier:
case tok::annot_typename: {
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
- Tok.getAnnotationValue());
+ if (Tok.getAnnotationValue())
+ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec,
+ Tok.getAnnotationValue());
+ else
+ DS.SetTypeSpecError();
DS.SetRangeEnd(Tok.getAnnotationEndLoc());
ConsumeToken(); // The typename
@@ -1893,11 +1897,11 @@
// FIXME: Inaccurate.
SourceLocation NameLoc = Tok.getLocation();
SourceLocation EndLoc;
- if (TypeTy *Type = ParseClassName(EndLoc)) {
- D.setDestructor(Type, TildeLoc, NameLoc);
- } else {
+ TypeResult Type = ParseClassName(EndLoc);
+ if (Type.isInvalid())
D.SetIdentifier(0, TildeLoc);
- }
+ else
+ D.setDestructor(Type.get(), TildeLoc, NameLoc);
} else {
Diag(Tok, diag::err_expected_class_name);
D.SetIdentifier(0, TildeLoc);
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Apr 1 16:51:26 2009
@@ -301,21 +301,23 @@
/// identifier
/// simple-template-id
///
-Parser::TypeTy *Parser::ParseClassName(SourceLocation &EndLocation,
- const CXXScopeSpec *SS) {
+Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation,
+ const CXXScopeSpec *SS) {
// Check whether we have a template-id that names a type.
if (Tok.is(tok::annot_template_id)) {
TemplateIdAnnotation *TemplateId
= static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
if (TemplateId->Kind == TNK_Type_template) {
- if (AnnotateTemplateIdTokenAsType(SS))
- return 0;
+ AnnotateTemplateIdTokenAsType(SS);
assert(Tok.is(tok::annot_typename) && "template-id -> type failed");
TypeTy *Type = Tok.getAnnotationValue();
EndLocation = Tok.getAnnotationEndLoc();
ConsumeToken();
- return Type;
+
+ if (Type)
+ return Type;
+ return true;
}
// Fall through to produce an error below.
@@ -323,7 +325,7 @@
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected_class_name);
- return 0;
+ return true;
}
// We have an identifier; check whether it is actually a type.
@@ -331,7 +333,7 @@
Tok.getLocation(), CurScope, SS);
if (!Type) {
Diag(Tok, diag::err_expected_class_name);
- return 0;
+ return true;
}
// Consume the identifier.
@@ -592,7 +594,7 @@
if (IsVirtual) {
// Complain about duplicate 'virtual'
Diag(VirtualLoc, diag::err_dup_virtual)
- << SourceRange(VirtualLoc, VirtualLoc);
+ << CodeModificationHint::CreateRemoval(SourceRange(VirtualLoc));
}
IsVirtual = true;
@@ -607,8 +609,8 @@
// Parse the class-name.
SourceLocation EndLocation;
- TypeTy *BaseType = ParseClassName(EndLocation, &SS);
- if (!BaseType)
+ TypeResult BaseType = ParseClassName(EndLocation, &SS);
+ if (BaseType.isInvalid())
return true;
// Find the complete source range for the base-specifier.
@@ -617,7 +619,7 @@
// Notify semantic analysis that we have parsed a complete
// base-specifier.
return Actions.ActOnBaseSpecifier(ClassDecl, Range, IsVirtual, Access,
- BaseType, BaseLoc);
+ BaseType.get(), BaseLoc);
}
/// getAccessSpecifierIfPresent - Determine whether the next token is
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed Apr 1 16:51:26 2009
@@ -148,12 +148,11 @@
if (TemplateId->Kind == TNK_Type_template ||
TemplateId->Kind == TNK_Dependent_template_name) {
- if (AnnotateTemplateIdTokenAsType(&SS))
- SS.clear();
+ AnnotateTemplateIdTokenAsType(&SS);
+ SS.clear();
assert(Tok.is(tok::annot_typename) &&
"AnnotateTemplateIdTokenAsType isn't working");
-
Token TypeToken = Tok;
ConsumeToken();
assert(Tok.is(tok::coloncolon) && "NextToken() not working properly!");
@@ -163,12 +162,15 @@
SS.setBeginLoc(TypeToken.getLocation());
HasScopeSpecifier = true;
}
-
- SS.setScopeRep(
- Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
- TypeToken.getAnnotationValue(),
- TypeToken.getAnnotationRange(),
- CCLoc));
+
+ if (TypeToken.getAnnotationValue())
+ SS.setScopeRep(
+ Actions.ActOnCXXNestedNameSpecifier(CurScope, SS,
+ TypeToken.getAnnotationValue(),
+ TypeToken.getAnnotationRange(),
+ CCLoc));
+ else
+ SS.setScopeRep(0);
SS.setEndLoc(CCLoc);
continue;
} else
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Wed Apr 1 16:51:26 2009
@@ -588,8 +588,10 @@
/// \brief Replaces a template-id annotation token with a type
/// annotation token.
///
-/// \returns true if there was an error, false otherwise.
-bool Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
+/// If there was a failure when forming the type from the template-id,
+/// a type annotation token will still be created, but will have a
+/// NULL type pointer to signify an error.
+void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) {
assert(Tok.is(tok::annot_template_id) && "Requires template-id tokens");
TemplateIdAnnotation *TemplateId
@@ -610,16 +612,9 @@
TemplateArgsPtr,
TemplateId->getTemplateArgLocations(),
TemplateId->RAngleLoc);
- if (Type.isInvalid()) {
- // FIXME: better recovery?
- ConsumeToken();
- TemplateId->Destroy();
- return true;
- }
-
// Create the new "type" annotation token.
Tok.setKind(tok::annot_typename);
- Tok.setAnnotationValue(Type.get());
+ Tok.setAnnotationValue(Type.isInvalid()? 0 : Type.get());
if (SS && SS->isNotEmpty()) // it was a C++ qualified type name.
Tok.setLocation(SS->getBeginLoc());
@@ -629,8 +624,6 @@
// class template specialization again.
PP.ReplaceLastTokenWithAnnotation(Tok);
TemplateId->Destroy();
-
- return false;
}
/// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Wed Apr 1 16:51:26 2009
@@ -851,22 +851,22 @@
return false;
}
- if (AnnotateTemplateIdTokenAsType(0))
- return false;
-
+ AnnotateTemplateIdTokenAsType(0);
assert(Tok.is(tok::annot_typename) &&
"AnnotateTemplateIdTokenAsType isn't working properly");
- Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
- Tok.getAnnotationValue());
+ if (Tok.getAnnotationValue())
+ Ty = Actions.ActOnTypenameType(TypenameLoc, SS, SourceLocation(),
+ Tok.getAnnotationValue());
+ else
+ Ty = true;
} else {
Diag(Tok, diag::err_expected_type_name_after_typename)
<< SS.getRange();
return false;
}
- // FIXME: better error recovery!
Tok.setKind(tok::annot_typename);
- Tok.setAnnotationValue(Ty.get());
+ Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get());
Tok.setAnnotationEndLoc(Tok.getLocation());
Tok.setLocation(TypenameLoc);
PP.AnnotateCachedTokens(Tok);
@@ -925,7 +925,8 @@
// template-id annotation in a context where we weren't allowed
// to produce a type annotation token. Update the template-id
// annotation token to a type annotation token now.
- return !AnnotateTemplateIdTokenAsType(&SS);
+ AnnotateTemplateIdTokenAsType(&SS);
+ return true;
}
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Apr 1 16:51:26 2009
@@ -755,7 +755,6 @@
/// pointers used to reconstruct new'ed Decl*[] array containing
/// found ambiguous decls. LookupResult is owner of this array.
AmbiguousLookupStoresDecls
-
} StoredKind;
/// The first lookup result, whose contents depend on the kind of
@@ -939,6 +938,9 @@
iterator begin();
iterator end();
+
+ /// \brief Free the memory associated with this lookup.
+ void Destroy();
};
private:
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Apr 1 16:51:26 2009
@@ -80,9 +80,34 @@
case LookupResult::AmbiguousBaseSubobjectTypes:
case LookupResult::AmbiguousBaseSubobjects:
- case LookupResult::AmbiguousReference:
+ case LookupResult::AmbiguousReference: {
+ // Look to see if we have a type anywhere in the list of results.
+ for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end();
+ Res != ResEnd; ++Res) {
+ if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res)) {
+ IIDecl = *Res;
+ break;
+ }
+ }
+
+ if (!IIDecl) {
+ // None of the entities we found is a type, so there is no way
+ // to even assume that the result is a type. In this case, don't
+ // complain about the ambiguity. The parser will either try to
+ // perform this lookup again (e.g., as an object name), which
+ // will produce the ambiguity, or will complain that it expected
+ // a type name.
+ Result.Destroy();
+ return 0;
+ }
+
+ // We found a type within the ambiguous lookup; diagnose the
+ // ambiguity and then return that type. This might be the right
+ // answer, or it might not be, but it suppresses any attempt to
+ // perform the name lookup again.
DiagnoseAmbiguousLookup(Result, DeclarationName(&II), NameLoc);
- return 0;
+ break;
+ }
case LookupResult::Found:
IIDecl = Result.getAsDecl();
@@ -3153,7 +3178,7 @@
//
// struct S s;
//
- // causes needless err_ovl_no_viable_function_in_init latter.
+ // causes needless "incomplete type" error later.
Name = 0;
PrevDecl = 0;
Invalid = true;
Modified: cfe/trunk/lib/Sema/SemaInherit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInherit.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInherit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInherit.cpp Wed Apr 1 16:51:26 2009
@@ -25,6 +25,34 @@
using namespace clang;
+/// \brief Computes the set of declarations referenced by these base
+/// paths.
+void BasePaths::ComputeDeclsFound() {
+ assert(NumDeclsFound == 0 && !DeclsFound &&
+ "Already computed the set of declarations");
+
+ std::set<NamedDecl *> Decls;
+ for (BasePaths::paths_iterator Path = begin(), PathEnd = end();
+ Path != PathEnd; ++Path)
+ Decls.insert(*Path->Decls.first);
+
+ NumDeclsFound = Decls.size();
+ DeclsFound = new NamedDecl * [NumDeclsFound];
+ std::copy(Decls.begin(), Decls.end(), DeclsFound);
+}
+
+NamedDecl **BasePaths::found_decls_begin() {
+ if (NumDeclsFound == 0)
+ ComputeDeclsFound();
+ return DeclsFound;
+}
+
+NamedDecl **BasePaths::found_decls_end() {
+ if (NumDeclsFound == 0)
+ ComputeDeclsFound();
+ return DeclsFound + NumDeclsFound;
+}
+
/// isAmbiguous - Determines whether the set of paths provided is
/// ambiguous, i.e., there are two or more paths that refer to
/// different base class subobjects of the same type. BaseType must be
Modified: cfe/trunk/lib/Sema/SemaInherit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInherit.h?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInherit.h (original)
+++ cfe/trunk/lib/Sema/SemaInherit.h Wed Apr 1 16:51:26 2009
@@ -132,8 +132,16 @@
/// DetectedVirtual - The base class that is virtual.
const RecordType *DetectedVirtual;
+ /// \brief Array of the declarations that have been found. This
+ /// array is constructed only if needed, e.g., to iterate over the
+ /// results within LookupResult.
+ NamedDecl **DeclsFound;
+ unsigned NumDeclsFound;
+
friend class Sema;
+ void ComputeDeclsFound();
+
public:
typedef std::list<BasePath>::const_iterator paths_iterator;
@@ -143,15 +151,21 @@
bool RecordPaths = true,
bool DetectVirtual = true)
: FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
- DetectVirtual(DetectVirtual), DetectedVirtual(0)
+ DetectVirtual(DetectVirtual), DetectedVirtual(0), DeclsFound(0),
+ NumDeclsFound(0)
{}
+ ~BasePaths() { delete [] DeclsFound; }
+
paths_iterator begin() const { return Paths.begin(); }
paths_iterator end() const { return Paths.end(); }
BasePath& front() { return Paths.front(); }
const BasePath& front() const { return Paths.front(); }
+ NamedDecl **found_decls_begin();
+ NamedDecl **found_decls_end();
+
bool isAmbiguous(QualType BaseType);
/// isFindingAmbiguities - Whether we are finding multiple paths
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Apr 1 16:51:26 2009
@@ -437,13 +437,16 @@
case OverloadedDeclFromIdResolver:
return *IdentifierResolver::iterator::getFromOpaqueValue(Current);
+ case AmbiguousLookupStoresBasePaths:
+ if (Result->Last)
+ return *reinterpret_cast<NamedDecl**>(Current);
+
+ // Fall through to handle the DeclContext::lookup_iterator we're
+ // storing.
+
case OverloadedDeclFromDeclContext:
- return *reinterpret_cast<DeclContext::lookup_iterator>(Current);
-
case AmbiguousLookupStoresDecls:
- case AmbiguousLookupStoresBasePaths:
- assert(false && "Cannot look into ambiguous lookup results");
- break;
+ return *reinterpret_cast<DeclContext::lookup_iterator>(Current);
}
return 0;
@@ -470,39 +473,90 @@
break;
}
- case OverloadedDeclFromDeclContext: {
+ case AmbiguousLookupStoresBasePaths:
+ if (Result->Last) {
+ NamedDecl ** I = reinterpret_cast<NamedDecl**>(Current);
+ ++I;
+ Current = reinterpret_cast<uintptr_t>(I);
+ break;
+ }
+ // Fall through to handle the DeclContext::lookup_iterator we're
+ // storing.
+
+ case OverloadedDeclFromDeclContext:
+ case AmbiguousLookupStoresDecls: {
DeclContext::lookup_iterator I
= reinterpret_cast<DeclContext::lookup_iterator>(Current);
++I;
Current = reinterpret_cast<uintptr_t>(I);
break;
}
-
- case AmbiguousLookupStoresDecls:
- case AmbiguousLookupStoresBasePaths:
- assert(false && "Cannot look into ambiguous lookup results");
- break;
}
return *this;
}
Sema::LookupResult::iterator Sema::LookupResult::begin() {
- assert(!isAmbiguous() && "Lookup into an ambiguous result");
- if (StoredKind != OverloadedDeclSingleDecl)
+ switch (StoredKind) {
+ case SingleDecl:
+ case OverloadedDeclFromIdResolver:
+ case OverloadedDeclFromDeclContext:
+ case AmbiguousLookupStoresDecls:
return iterator(this, First);
- OverloadedFunctionDecl * Ovl =
- reinterpret_cast<OverloadedFunctionDecl*>(First);
- return iterator(this, reinterpret_cast<uintptr_t>(&(*Ovl->function_begin())));
+
+ case OverloadedDeclSingleDecl: {
+ OverloadedFunctionDecl * Ovl =
+ reinterpret_cast<OverloadedFunctionDecl*>(First);
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(&(*Ovl->function_begin())));
+ }
+
+ case AmbiguousLookupStoresBasePaths:
+ if (Last)
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(getBasePaths()->found_decls_begin()));
+ else
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(getBasePaths()->front().Decls.first));
+ }
+
+ // Required to suppress GCC warning.
+ return iterator();
}
Sema::LookupResult::iterator Sema::LookupResult::end() {
- assert(!isAmbiguous() && "Lookup into an ambiguous result");
- if (StoredKind != OverloadedDeclSingleDecl)
+ switch (StoredKind) {
+ case SingleDecl:
+ case OverloadedDeclFromIdResolver:
+ case OverloadedDeclFromDeclContext:
+ case AmbiguousLookupStoresDecls:
return iterator(this, Last);
- OverloadedFunctionDecl * Ovl =
- reinterpret_cast<OverloadedFunctionDecl*>(First);
- return iterator(this, reinterpret_cast<uintptr_t>(&(*Ovl->function_end())));
+
+ case OverloadedDeclSingleDecl: {
+ OverloadedFunctionDecl * Ovl =
+ reinterpret_cast<OverloadedFunctionDecl*>(First);
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(&(*Ovl->function_end())));
+ }
+
+ case AmbiguousLookupStoresBasePaths:
+ if (Last)
+ return iterator(this,
+ reinterpret_cast<uintptr_t>(getBasePaths()->found_decls_end()));
+ else
+ return iterator(this, reinterpret_cast<uintptr_t>(
+ getBasePaths()->front().Decls.second));
+ }
+
+ // Required to suppress GCC warning.
+ return iterator();
+}
+
+void Sema::LookupResult::Destroy() {
+ if (BasePaths *Paths = getBasePaths())
+ delete Paths;
+ else if (getKind() == AmbiguousReference)
+ delete[] reinterpret_cast<NamedDecl **>(First);
}
static void
@@ -1071,8 +1125,7 @@
SourceRange LookupRange) {
assert(Result.isAmbiguous() && "Lookup result must be ambiguous");
- if (BasePaths *Paths = Result.getBasePaths())
- {
+ if (BasePaths *Paths = Result.getBasePaths()) {
if (Result.getKind() == LookupResult::AmbiguousBaseSubobjects) {
QualType SubobjectType = Paths->front().back().Base->getType();
Diag(NameLoc, diag::err_ambiguous_member_multiple_subobjects)
@@ -1080,11 +1133,13 @@
<< LookupRange;
DeclContext::lookup_iterator Found = Paths->front().Decls.first;
- while (isa<CXXMethodDecl>(*Found) && cast<CXXMethodDecl>(*Found)->isStatic())
+ while (isa<CXXMethodDecl>(*Found) &&
+ cast<CXXMethodDecl>(*Found)->isStatic())
++Found;
Diag((*Found)->getLocation(), diag::note_ambiguous_member_found);
+ Result.Destroy();
return true;
}
@@ -1102,20 +1157,18 @@
Diag(D->getLocation(), diag::note_ambiguous_member_found);
}
- delete Paths;
+ Result.Destroy();
return true;
} else if (Result.getKind() == LookupResult::AmbiguousReference) {
-
Diag(NameLoc, diag::err_ambiguous_reference) << Name << LookupRange;
NamedDecl **DI = reinterpret_cast<NamedDecl **>(Result.First),
- **DEnd = reinterpret_cast<NamedDecl **>(Result.Last);
+ **DEnd = reinterpret_cast<NamedDecl **>(Result.Last);
for (; DI != DEnd; ++DI)
Diag((*DI)->getLocation(), diag::note_ambiguous_candidate) << *DI;
- delete[] reinterpret_cast<NamedDecl **>(Result.First);
-
+ Result.Destroy();
return true;
}
@@ -1466,7 +1519,6 @@
AssociatedNamespaces, AssociatedClasses);
// C++ [basic.lookup.argdep]p3:
- //
// Let X be the lookup set produced by unqualified lookup (3.4.1)
// and let Y be the lookup set produced by argument dependent
// lookup (defined as follows). If X contains [...] then Y is
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 1 16:51:26 2009
@@ -870,8 +870,11 @@
QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
&TemplateArgs[0], TemplateArgs.size(),
RAngleLoc);
-
TemplateArgsIn.release();
+
+ if (Result.isNull())
+ return true;
+
return Result.getAsOpaquePtr();
}
@@ -2102,6 +2105,8 @@
return true;
QualType T = CheckTypenameType(NNS, II, SourceRange(TypenameLoc, IdLoc));
+ if (T.isNull())
+ return true;
return T.getAsOpaquePtr();
}
Modified: cfe/trunk/test/SemaCXX/member-name-lookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-name-lookup.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/member-name-lookup.cpp (original)
+++ cfe/trunk/test/SemaCXX/member-name-lookup.cpp Wed Apr 1 16:51:26 2009
@@ -1,36 +1,33 @@
// RUN: clang-cc -fsyntax-only -verify %s
-// XFAIL
-// fails due to exact diagnostic matching
-
struct A {
- int a; // expected-note{{member found by ambiguous name lookup}}
+ int a; // expected-note 4{{member found by ambiguous name lookup}}
static int b;
- static int c; // expected-note{{member found by ambiguous name lookup}}
+ static int c; // expected-note 4{{member found by ambiguous name lookup}}
enum E { enumerator };
typedef int type;
static void f(int);
- void f(float); // expected-note{{member found by ambiguous name lookup}}
+ void f(float); // expected-note 2{{member found by ambiguous name lookup}}
static void static_f(int);
static void static_f(double);
};
struct B : A {
- int d; // expected-note{{member found by ambiguous name lookup}}
+ int d; // expected-note 2{{member found by ambiguous name lookup}}
enum E2 { enumerator2 };
- enum E3 { enumerator3 }; // expected-note{{member found by ambiguous name lookup}}
+ enum E3 { enumerator3 }; // expected-note 2{{member found by ambiguous name lookup}}
};
struct C : A {
- int c; // expected-note{{member found by ambiguous name lookup}}
- int d; // expected-note{{member found by ambiguous name lookup}}
+ int c; // expected-note 2{{member found by ambiguous name lookup}}
+ int d; // expected-note 2{{member found by ambiguous name lookup}}
- enum E3 { enumerator3_2 }; // expected-note{{member found by ambiguous name lookup}}
+ enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
};
struct D : B, C {
@@ -50,7 +47,7 @@
D::E2 e2 = D::enumerator2; // okay
- D::E3 e3; // expected-error{{member 'E3' found in multiple base classes of different types}}
+ D::E3 e3; // expected-error{{multiple base classes}}
}
void D::test_lookup() {
@@ -70,18 +67,18 @@
}
struct B2 : virtual A {
- int d; // expected-note{{member found by ambiguous name lookup}}
+ int d; // expected-note 2{{member found by ambiguous name lookup}}
enum E2 { enumerator2 };
- enum E3 { enumerator3 }; // expected-note{{member found by ambiguous name lookup}}
+ enum E3 { enumerator3 }; // expected-note 2 {{member found by ambiguous name lookup}}
};
struct C2 : virtual A {
- int c; // expected-note{{member found by ambiguous name lookup}}
- int d; // expected-note{{member found by ambiguous name lookup}}
+ int c; // expected-note 2{{member found by ambiguous name lookup}}
+ int d; // expected-note 2{{member found by ambiguous name lookup}}
- enum E3 { enumerator3_2 }; // expected-note{{member found by ambiguous name lookup}}
+ enum E3 { enumerator3_2 }; // expected-note 2{{member found by ambiguous name lookup}}
};
struct D2 : B2, C2 {
@@ -147,6 +144,5 @@
};
struct UsesAmbigMemberType : HasMemberType1, HasMemberType2 {
- type t; // expected-error{{member 'type' found in multiple base classes of different types}} \
- // expected-error{{expected ';' at end of declaration list}}
+ type t; // expected-error{{member 'type' found in multiple base classes of different types}}
};
Modified: cfe/trunk/test/SemaCXX/using-directive.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-directive.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/using-directive.cpp (original)
+++ cfe/trunk/test/SemaCXX/using-directive.cpp Wed Apr 1 16:51:26 2009
@@ -1,9 +1,7 @@
// RUN: clang-cc -fsyntax-only -verify %s
-// XFAIL
-// fails due to exact diagnostic matching
namespace A {
- short i; // expected-note{{candidate found by name lookup is 'A::i'}}
+ short i; // expected-note 2{{candidate found by name lookup is 'A::i'}}
namespace B {
long i; // expected-note{{candidate found by name lookup is 'A::B::i'}}
void f() {} // expected-note{{candidate function}}
@@ -58,7 +56,7 @@
// FIXME: Do we want err_ovl_no_viable_function_in_init here?
struct K2 k2; // expected-error{{reference to 'K2' is ambiguous}} \
- expected-error{{no matching constructor}}
+ expected-error{{incomplete type}}
// FIXME: This case is incorrectly diagnosed!
//K2 k3;
@@ -66,7 +64,7 @@
class X { // expected-note{{candidate found by name lookup is 'X'}}
// FIXME: produce a suitable error message for this
- using namespace A; // expected-error{{expected unqualified-id}}
+ using namespace A; // expected-error{{expected member name or}}
};
namespace N {
@@ -96,7 +94,8 @@
}
namespace TwoTag {
- struct X; // expected-note{{candidate found by name lookup is 'TwoTag::X'}}
+ struct X; // expected-note{{candidate found by name lookup is 'TwoTag::X'}} \
+ // expected-note{{forward declaration}}
}
namespace FuncHidesTagAmbiguity {
@@ -105,6 +104,7 @@
using namespace TwoTag;
void test() {
- (void)X(); // expected-error{{reference to 'X' is ambiguous}}
+ (void)X(); // expected-error{{reference to 'X' is ambiguous}} \
+ // FIXME: expected-error{{invalid use of incomplete type}}
}
}
Modified: cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp?rev=68251&r1=68250&r2=68251&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp Wed Apr 1 16:51:26 2009
@@ -52,7 +52,7 @@
#if 0
// FIXME: the following crashes the parser, because Sema has no way to
-// community that the "dependent" template-name N::template B doesn't
+// communicate that the "dependent" template-name N::template B doesn't
// actually refer to a template.
template<typename T>
struct TestA {
More information about the cfe-commits
mailing list