r193019 - Be smarter about deciding to add a leading '::' to a
Kaelyn Uhrain
rikka at google.com
Fri Oct 18 17:04:53 PDT 2013
Author: rikka
Date: Fri Oct 18 19:04:52 2013
New Revision: 193019
URL: http://llvm.org/viewvc/llvm-project?rev=193019&view=rev
Log:
Be smarter about deciding to add a leading '::' to a
NestedNameSpecifier that replaces an existing specifier.
Modified:
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp
cfe/trunk/test/SemaCXX/using-decl-1.cpp
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=193019&r1=193018&r2=193019&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Fri Oct 18 19:04:52 2013
@@ -3575,6 +3575,7 @@ typedef SmallVector<SpecifierInfo, 16> S
class NamespaceSpecifierSet {
ASTContext &Context;
DeclContextList CurContextChain;
+ std::string CurNameSpecifier;
SmallVector<const IdentifierInfo*, 4> CurContextIdentifiers;
SmallVector<const IdentifierInfo*, 4> CurNameSpecifierIdentifiers;
bool isSorted;
@@ -3594,9 +3595,13 @@ class NamespaceSpecifierSet {
CXXScopeSpec *CurScopeSpec)
: Context(Context), CurContextChain(BuildContextChain(CurContext)),
isSorted(false) {
- if (CurScopeSpec && CurScopeSpec->getScopeRep())
- getNestedNameSpecifierIdentifiers(CurScopeSpec->getScopeRep(),
- CurNameSpecifierIdentifiers);
+ if (NestedNameSpecifier *NNS =
+ CurScopeSpec ? CurScopeSpec->getScopeRep() : 0) {
+ llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
+ NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+
+ getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
+ }
// Build the list of identifiers that would be used for an absolute
// (from the global context) NestedNameSpecifier referring to the current
// context.
@@ -3659,6 +3664,25 @@ void NamespaceSpecifierSet::SortNamespac
isSorted = true;
}
+static unsigned BuildNestedNameSpecifier(ASTContext &Context,
+ DeclContextList &DeclChain,
+ NestedNameSpecifier *&NNS) {
+ unsigned NumSpecifiers = 0;
+ for (DeclContextList::reverse_iterator C = DeclChain.rbegin(),
+ CEnd = DeclChain.rend();
+ C != CEnd; ++C) {
+ if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C)) {
+ NNS = NestedNameSpecifier::Create(Context, NNS, ND);
+ ++NumSpecifiers;
+ } else if (RecordDecl *RD = dyn_cast_or_null<RecordDecl>(*C)) {
+ NNS = NestedNameSpecifier::Create(Context, NNS, RD->isTemplateDecl(),
+ RD->getTypeForDecl());
+ ++NumSpecifiers;
+ }
+ }
+ return NumSpecifiers;
+}
+
void NamespaceSpecifierSet::AddNameSpecifier(DeclContext *Ctx) {
NestedNameSpecifier *NNS = NULL;
unsigned NumSpecifiers = 0;
@@ -3673,34 +3697,37 @@ void NamespaceSpecifierSet::AddNameSpeci
NamespaceDeclChain.pop_back();
}
+ // Build the NestedNameSpecifier from what is left of the NamespaceDeclChain
+ NumSpecifiers = BuildNestedNameSpecifier(Context, NamespaceDeclChain, NNS);
+
// Add an explicit leading '::' specifier if needed.
if (NamespaceDeclChain.empty()) {
- NamespaceDeclChain = FullNamespaceDeclChain;
+ // Rebuild the NestedNameSpecifier as a globally-qualified specifier.
NNS = NestedNameSpecifier::GlobalSpecifier(Context);
+ NumSpecifiers =
+ BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
} else if (NamedDecl *ND =
dyn_cast_or_null<NamedDecl>(NamespaceDeclChain.back())) {
IdentifierInfo *Name = ND->getIdentifier();
- if (std::find(CurContextIdentifiers.begin(), CurContextIdentifiers.end(),
- Name) != CurContextIdentifiers.end() ||
- std::find(CurNameSpecifierIdentifiers.begin(),
+ bool SameNameSpecifier = false;
+ if (std::find(CurNameSpecifierIdentifiers.begin(),
CurNameSpecifierIdentifiers.end(),
Name) != CurNameSpecifierIdentifiers.end()) {
- NamespaceDeclChain = FullNamespaceDeclChain;
- NNS = NestedNameSpecifier::GlobalSpecifier(Context);
+ std::string NewNameSpecifier;
+ llvm::raw_string_ostream SpecifierOStream(NewNameSpecifier);
+ SmallVector<const IdentifierInfo *, 4> NewNameSpecifierIdentifiers;
+ getNestedNameSpecifierIdentifiers(NNS, NewNameSpecifierIdentifiers);
+ NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+ SpecifierOStream.flush();
+ SameNameSpecifier = NewNameSpecifier == CurNameSpecifier;
}
- }
-
- // Build the NestedNameSpecifier from what is left of the NamespaceDeclChain
- for (DeclContextList::reverse_iterator C = NamespaceDeclChain.rbegin(),
- CEnd = NamespaceDeclChain.rend();
- C != CEnd; ++C) {
- if (NamespaceDecl *ND = dyn_cast_or_null<NamespaceDecl>(*C)) {
- NNS = NestedNameSpecifier::Create(Context, NNS, ND);
- ++NumSpecifiers;
- } else if (RecordDecl *RD = dyn_cast_or_null<RecordDecl>(*C)) {
- NNS = NestedNameSpecifier::Create(Context, NNS, RD->isTemplateDecl(),
- RD->getTypeForDecl());
- ++NumSpecifiers;
+ if (SameNameSpecifier ||
+ std::find(CurContextIdentifiers.begin(), CurContextIdentifiers.end(),
+ Name) != CurContextIdentifiers.end()) {
+ // Rebuild the NestedNameSpecifier as a globally-qualified specifier.
+ NNS = NestedNameSpecifier::GlobalSpecifier(Context);
+ NumSpecifiers =
+ BuildNestedNameSpecifier(Context, FullNamespaceDeclChain, NNS);
}
}
Modified: cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp?rev=193019&r1=193018&r2=193019&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp (original)
+++ cfe/trunk/test/SemaCXX/qualified-id-lookup.cpp Fri Oct 18 19:04:52 2013
@@ -86,13 +86,13 @@ namespace a {
namespace a {
namespace a { // A1
namespace a { // A2
- int i; // expected-note{{'::a::a::a::i' declared here}}
+ int i; // expected-note{{'a::a::a::i' declared here}}
}
}
}
void test_a() {
- a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean '::a::a::a::i'?}}
+ a::a::i = 3; // expected-error{{no member named 'i' in namespace 'a::a'; did you mean 'a::a::a::i'?}}
a::a::a::i = 4;
a::a::j = 3; // expected-error-re{{no member named 'j' in namespace 'a::a'$}}
}
Modified: cfe/trunk/test/SemaCXX/using-decl-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-1.cpp?rev=193019&r1=193018&r2=193019&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/using-decl-1.cpp (original)
+++ cfe/trunk/test/SemaCXX/using-decl-1.cpp Fri Oct 18 19:04:52 2013
@@ -139,24 +139,24 @@ using typename N::FFG; // expected-error
// Currently hints aren't provided to drop out the incorrect M::.
namespace using_suggestion_ty_dropped_nested_specifier {
namespace N {
-class AAA {};
+class AAA {}; // expected-note {{'N::AAA' declared here}}
namespace M { }
}
-using N::M::AAA; // expected-error {{no member named 'AAA' in namespace 'using_suggestion_ty_dropped_nested_specifier::N::M'}}
+using N::M::AAA; // expected-error {{no member named 'AAA' in namespace 'using_suggestion_ty_dropped_nested_specifier::N::M'; did you mean 'N::AAA'?}}
}
namespace using_suggestion_tyname_ty_dropped_nested_specifier {
namespace N {
-class AAA {};
+class AAA {}; // expected-note {{'N::AAA' declared here}}
namespace M { }
}
-using typename N::M::AAA; // expected-error {{no member named 'AAA' in namespace 'using_suggestion_tyname_ty_dropped_nested_specifier::N::M'}}
+using typename N::M::AAA; // expected-error {{no member named 'AAA' in namespace 'using_suggestion_tyname_ty_dropped_nested_specifier::N::M'; did you mean 'N::AAA'?}}
}
namespace using_suggestion_val_dropped_nested_specifier {
namespace N {
-void FFF() {}
+void FFF() {} // expected-note {{'N::FFF' declared here}}
namespace M { }
}
-using N::M::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_nested_specifier::N::M'}}
+using N::M::FFF; // expected-error {{no member named 'FFF' in namespace 'using_suggestion_val_dropped_nested_specifier::N::M'; did you mean 'N::FFF'?}}
}
More information about the cfe-commits
mailing list