Avoid redundant NNS qualification in constructor/destructor names.

llvm-svn: 149124
This commit is contained in:
Abramo Bagnara 2012-01-27 08:46:19 +00:00
parent 8823d12a53
commit 4244b43b60
7 changed files with 43 additions and 26 deletions

View File

@ -851,6 +851,7 @@ public:
bool isClassName = false, bool isClassName = false,
bool HasTrailingDot = false, bool HasTrailingDot = false,
ParsedType ObjectType = ParsedType(), ParsedType ObjectType = ParsedType(),
bool IsCtorOrDtorName = false,
bool WantNontrivialTypeSourceInfo = false, bool WantNontrivialTypeSourceInfo = false,
IdentifierInfo **CorrectedII = 0); IdentifierInfo **CorrectedII = 0);
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S); TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
@ -3941,7 +3942,8 @@ public:
TemplateTy Template, SourceLocation TemplateLoc, TemplateTy Template, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs, ASTTemplateArgsPtr TemplateArgs,
SourceLocation RAngleLoc); SourceLocation RAngleLoc,
bool IsCtorOrDtorName = false);
/// \brief Parsed an elaborated-type-specifier that refers to a template-id, /// \brief Parsed an elaborated-type-specifier that refers to a template-id,
/// such as \c class T::template apply<U>. /// such as \c class T::template apply<U>.

View File

@ -1846,6 +1846,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
Next.getLocation(), Next.getLocation(),
getCurScope(), &SS, getCurScope(), &SS,
false, false, ParsedType(), false, false, ParsedType(),
/*IsCtorOrDtorName=*/false,
/*NonTrivialSourceInfo=*/true); /*NonTrivialSourceInfo=*/true);
// If the referenced identifier is not a type, then this declspec is // If the referenced identifier is not a type, then this declspec is

View File

@ -857,6 +857,7 @@ Parser::TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
// We have an identifier; check whether it is actually a type. // We have an identifier; check whether it is actually a type.
ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true, ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), &SS, true,
false, ParsedType(), false, ParsedType(),
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo=*/true); /*NonTrivialTypeSourceInfo=*/true);
if (!Type) { if (!Type) {
Diag(IdLoc, diag::err_expected_class_name); Diag(IdLoc, diag::err_expected_class_name);

View File

@ -1647,12 +1647,12 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
// Bundle the template arguments together. // Bundle the template arguments together.
ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(), ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
TemplateArgs.size()); TemplateArgs.size());
// Constructor and destructor names. // Constructor and destructor names.
TypeResult Type TypeResult Type
= Actions.ActOnTemplateIdType(SS, Template, NameLoc, = Actions.ActOnTemplateIdType(SS, Template, NameLoc,
LAngleLoc, TemplateArgsPtr, LAngleLoc, TemplateArgsPtr, RAngleLoc,
RAngleLoc); /*IsCtorOrDtorName=*/true);
if (Type.isInvalid()) if (Type.isInvalid())
return true; return true;
@ -1910,11 +1910,12 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
if (AllowConstructorName && if (AllowConstructorName &&
Actions.isCurrentClassName(*Id, getCurScope(), &SS)) { Actions.isCurrentClassName(*Id, getCurScope(), &SS)) {
// We have parsed a constructor name. // We have parsed a constructor name.
Result.setConstructorName(Actions.getTypeName(*Id, IdLoc, getCurScope(), ParsedType Ty = Actions.getTypeName(*Id, IdLoc, getCurScope(),
&SS, false, false, &SS, false, false,
ParsedType(), ParsedType(),
/*NonTrivialTypeSourceInfo=*/true), /*IsCtorOrDtorName=*/true,
IdLoc, IdLoc); /*NonTrivialTypeSourceInfo=*/true);
Result.setConstructorName(Ty, IdLoc, IdLoc);
} else { } else {
// We have parsed an identifier. // We have parsed an identifier.
Result.setIdentifier(Id, IdLoc); Result.setIdentifier(Id, IdLoc);
@ -1947,13 +1948,14 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
<< TemplateId->Name << TemplateId->Name
<< FixItHint::CreateRemoval( << FixItHint::CreateRemoval(
SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)); SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc));
Result.setConstructorName(Actions.getTypeName(*TemplateId->Name, ParsedType Ty = Actions.getTypeName(*TemplateId->Name,
TemplateId->TemplateNameLoc, TemplateId->TemplateNameLoc,
getCurScope(), getCurScope(),
&SS, false, false, &SS, false, false,
ParsedType(), ParsedType(),
/*NontrivialTypeSourceInfo=*/true), /*IsCtorOrDtorName=*/true,
TemplateId->TemplateNameLoc, /*NontrivialTypeSourceInfo=*/true);
Result.setConstructorName(Ty, TemplateId->TemplateNameLoc,
TemplateId->RAngleLoc); TemplateId->RAngleLoc);
ConsumeToken(); ConsumeToken();
return false; return false;

View File

@ -1279,6 +1279,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
&SS, false, &SS, false,
NextToken().is(tok::period), NextToken().is(tok::period),
ParsedType(), ParsedType(),
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo*/true, /*NonTrivialTypeSourceInfo*/true,
NeedType ? &CorrectedII : NULL)) { NeedType ? &CorrectedII : NULL)) {
// A FixIt was applied as a result of typo correction // A FixIt was applied as a result of typo correction

View File

@ -94,6 +94,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec *SS, Scope *S, CXXScopeSpec *SS,
bool isClassName, bool HasTrailingDot, bool isClassName, bool HasTrailingDot,
ParsedType ObjectTypePtr, ParsedType ObjectTypePtr,
bool IsCtorOrDtorName,
bool WantNontrivialTypeSourceInfo, bool WantNontrivialTypeSourceInfo,
IdentifierInfo **CorrectedII) { IdentifierInfo **CorrectedII) {
// Determine where we will perform name lookup. // Determine where we will perform name lookup.
@ -194,6 +195,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
false, Template, MemberOfUnknownSpecialization))) { false, Template, MemberOfUnknownSpecialization))) {
ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr, ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr,
isClassName, HasTrailingDot, ObjectTypePtr, isClassName, HasTrailingDot, ObjectTypePtr,
IsCtorOrDtorName,
WantNontrivialTypeSourceInfo); WantNontrivialTypeSourceInfo);
if (Ty) { if (Ty) {
std::string CorrectedStr(Correction.getAsString(getLangOptions())); std::string CorrectedStr(Correction.getAsString(getLangOptions()));
@ -272,8 +274,11 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc,
if (T.isNull()) if (T.isNull())
T = Context.getTypeDeclType(TD); T = Context.getTypeDeclType(TD);
if (SS && SS->isNotEmpty()) { // NOTE: avoid constructing an ElaboratedType(Loc) if this is a
// constructor or destructor name (in such a case, the scope specifier
// will be attached to the enclosing Expr or Decl node).
if (SS && SS->isNotEmpty() && !IsCtorOrDtorName) {
if (WantNontrivialTypeSourceInfo) { if (WantNontrivialTypeSourceInfo) {
// Construct a type with type-source information. // Construct a type with type-source information.
TypeLocBuilder Builder; TypeLocBuilder Builder;
@ -394,6 +399,7 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS, SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS,
false, false, ParsedType(), false, false, ParsedType(),
/*IsCtorOrDtorName=*/false,
/*NonTrivialTypeSourceInfo=*/true); /*NonTrivialTypeSourceInfo=*/true);
} }
return true; return true;

View File

@ -2045,7 +2045,8 @@ Sema::ActOnTemplateIdType(CXXScopeSpec &SS,
TemplateTy TemplateD, SourceLocation TemplateLoc, TemplateTy TemplateD, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn, ASTTemplateArgsPtr TemplateArgsIn,
SourceLocation RAngleLoc) { SourceLocation RAngleLoc,
bool IsCtorOrDtorName) {
if (SS.isInvalid()) if (SS.isInvalid())
return true; return true;
@ -2056,12 +2057,12 @@ Sema::ActOnTemplateIdType(CXXScopeSpec &SS,
translateTemplateArguments(TemplateArgsIn, TemplateArgs); translateTemplateArguments(TemplateArgsIn, TemplateArgs);
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
QualType T = Context.getDependentTemplateSpecializationType(ETK_None, QualType T
DTN->getQualifier(), = Context.getDependentTemplateSpecializationType(ETK_None,
DTN->getIdentifier(), DTN->getQualifier(),
TemplateArgs); DTN->getIdentifier(),
TemplateArgs);
// Build type-source information. // Build type-source information.
TypeLocBuilder TLB; TypeLocBuilder TLB;
DependentTemplateSpecializationTypeLoc SpecTL DependentTemplateSpecializationTypeLoc SpecTL
= TLB.push<DependentTemplateSpecializationTypeLoc>(T); = TLB.push<DependentTemplateSpecializationTypeLoc>(T);
@ -2091,7 +2092,10 @@ Sema::ActOnTemplateIdType(CXXScopeSpec &SS,
for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i)
SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
if (SS.isNotEmpty()) { // NOTE: avoid constructing an ElaboratedTypeLoc if this is a
// constructor or destructor name (in such a case, the scope specifier
// will be attached to the enclosing Decl or Expr node).
if (SS.isNotEmpty() && !IsCtorOrDtorName) {
// Create an elaborated-type-specifier containing the nested-name-specifier. // Create an elaborated-type-specifier containing the nested-name-specifier.
Result = Context.getElaboratedType(ETK_None, SS.getScopeRep(), Result); Result = Context.getElaboratedType(ETK_None, SS.getScopeRep(), Result);
ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result);