)cpp",
"TypedefTypeLoc"},
- {R"cpp(
- namespace ns { class Foo {}; }
- using ns::Foo;
- class [[^Foo]] foo;
- )cpp",
- "UsingTypeLoc"},
-
// lambda captured var-decl
{R"cpp(
void test(int bar) {
}
using ns::$explicit^Y;)cpp",
"^Y<int> x;");
- testWalk(R"cpp(
- namespace ns { class Foo {}; }
- )cpp", "using ns::$explicit^Foo; class ^Foo foo;");
}
TEST(WalkAST, Namespaces) {
assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
return TypeRep;
}
- // Returns the underlying decl, if any.
Decl *getRepAsDecl() const {
- auto *D = getRepAsFoundDecl();
- if (const auto *Using = dyn_cast_or_null<UsingShadowDecl>(D))
- return Using->getTargetDecl();
- return D;
- }
- // Returns the originally found decl, if any.
- Decl *getRepAsFoundDecl() const {
- assert(isDeclRep((TST)TypeSpecType) && "DeclSpec does not store a decl");
+ assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl");
return DeclRep;
}
Expr *getRepAsExpr() const {
SourceLocation ScopedEnumKWLoc,
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- OffsetOfKind OOK,
- UsingShadowDecl*& FoundUsingShadow,
- SkipBodyInfo *SkipBody = nullptr);
+ OffsetOfKind OOK, SkipBodyInfo *SkipBody = nullptr);
DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
unsigned TagSpec, SourceLocation TagLoc,
bool IsDependent = false;
const char *PrevSpec = nullptr;
unsigned DiagID;
- UsingShadowDecl* FoundUsing = nullptr;
Decl *TagDecl =
Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS,
Name, NameLoc, attrs, AS, DS.getModulePrivateSpecLoc(),
BaseType, DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
- OffsetOfState, FoundUsing, &SkipBody).get();
+ OffsetOfState, &SkipBody).get();
if (SkipBody.ShouldSkip) {
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
T.skipToEnd();
if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
- NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
- DiagID, FoundUsing ? FoundUsing : TagDecl, Owned,
+ NameLoc.isValid() ? NameLoc : StartLoc,
+ PrevSpec, DiagID, TagDecl, Owned,
Actions.getASTContext().getPrintingPolicy()))
Diag(StartLoc, DiagID) << PrevSpec;
return;
}
if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
- NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
- DiagID, FoundUsing ? FoundUsing : TagDecl, Owned,
+ NameLoc.isValid() ? NameLoc : StartLoc,
+ PrevSpec, DiagID, TagDecl, Owned,
Actions.getASTContext().getPrintingPolicy()))
Diag(StartLoc, DiagID) << PrevSpec;
}
// Create the tag portion of the class or class template.
DeclResult TagOrTempResult = true; // invalid
TypeResult TypeResult = true; // invalid
- UsingShadowDecl *FoundUsing = nullptr;
bool Owned = false;
Sema::SkipBodyInfo SkipBody;
DSC == DeclSpecContext::DSC_type_specifier,
DSC == DeclSpecContext::DSC_template_param ||
DSC == DeclSpecContext::DSC_template_type_arg,
- OffsetOfState, FoundUsing, &SkipBody);
+ OffsetOfState, &SkipBody);
// If ActOnTag said the type was dependent, try again with the
// less common call.
} else if (!TagOrTempResult.isInvalid()) {
Result = DS.SetTypeSpecType(
TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
- DiagID, FoundUsing ? FoundUsing : TagOrTempResult.get(), Owned, Policy);
+ DiagID, TagOrTempResult.get(), Owned, Policy);
} else {
DS.SetTypeSpecError();
return;
bool &IsDependent, SourceLocation ScopedEnumKWLoc,
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
- OffsetOfKind OOK, UsingShadowDecl *&FoundUsingShadow,
- SkipBodyInfo *SkipBody) {
+ OffsetOfKind OOK, SkipBodyInfo *SkipBody) {
// If this is not a definition, it must have a name.
IdentifierInfo *OrigName = Name;
assert((Name != nullptr || TUK == TUK_Definition) &&
// redefinition if either context is within the other.
if (auto *Shadow = dyn_cast<UsingShadowDecl>(DirectPrevDecl)) {
auto *OldTag = dyn_cast<TagDecl>(PrevDecl);
- FoundUsingShadow = Shadow;
if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend &&
isDeclInScope(Shadow, SearchDC, S, isMemberSpecialization) &&
!(OldTag && isAcceptableTagRedeclContext(
if (SS.isEmpty()) {
bool Owned = false;
bool IsDependent = false;
- UsingShadowDecl* FoundUsing = nullptr;
return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr,
AS_public,
/*ModulePrivateLoc=*/SourceLocation(),
/*ScopedEnumUsesClassTag=*/false,
/*UnderlyingType=*/TypeResult(),
/*IsTypeSpecifier=*/false,
- /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside, FoundUsing);
+ /*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside);
}
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
bool Owned = false;
bool IsDependent = false;
- UsingShadowDecl* FoundUsing = nullptr;
- Decl *TagD =
- ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr,
- AS_none, /*ModulePrivateLoc=*/SourceLocation(),
+ Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name,
+ NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(),
MultiTemplateParamsArg(), Owned, IsDependent, SourceLocation(),
false, TypeResult(), /*IsTypeSpecifier*/ false,
- /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside, FoundUsing)
- .get();
+ /*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside).get();
assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
if (!TagD)
// TypeQuals handled by caller.
Result = Context.getTypeDeclType(D);
- if (const auto *Using =
- dyn_cast_or_null<UsingShadowDecl>(DS.getRepAsFoundDecl()))
- Result = Context.getUsingType(Using, Result);
// In both C and C++, make an ElaboratedType.
ElaboratedTypeKeyword Keyword
void VisitTagTypeLoc(TagTypeLoc TL) {
TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
}
- void VisitUsingTypeLoc(UsingTypeLoc TL) {
- TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
- }
void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
// An AtomicTypeLoc can come from either an _Atomic(...) type specifier
// or an _Atomic qualifier.
}
struct B::V {}; // expected-error {{no struct named 'V'}}
struct B::W {};
- struct B::X {}; // expected-error {{forward declaration of struct cannot have}}
+ struct B::X {}; // FIXME: ill-formed
enum B::Y e; // ok per dr417
class B::Z z; // ok per dr417
};
struct D::V {}; // expected-error {{no struct named 'V'}}
struct D::W {};
- struct D::X {}; // expected-error {{forward declaration of struct cannot have}}
+ struct D::X {}; // FIXME: ill-formed
enum D::Y e2; // ok per dr417
class D::Z z2; // ok per dr417
}
struct F;
struct H;
}
+ // FIXME: This is ill-formed.
using N::D;
- struct dr417::D {}; // expected-error {{forward declaration of struct cannot}} expected-warning {{extra qualification}}
+ struct dr417::D {}; // expected-warning {{extra qualification}}
using namespace N;
struct dr417::E {}; // expected-warning {{extra qualification}} expected-error {{no struct named 'E'}}
struct N::F {};