aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp73
1 files changed, 45 insertions, 28 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 7be71ca49ea2..3c58f1d19c04 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -372,6 +372,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
}
NamedDecl *IIDecl = nullptr;
+ UsingShadowDecl *FoundUsingShadow = nullptr;
switch (Result.getResultKind()) {
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
@@ -441,8 +442,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
(AllowDeducedTemplate && getAsTypeTemplateDecl(RealRes))) {
if (!IIDecl ||
// Make the selection of the recovery decl deterministic.
- RealRes->getLocation() < IIDecl->getLocation())
+ RealRes->getLocation() < IIDecl->getLocation()) {
IIDecl = RealRes;
+ FoundUsingShadow = dyn_cast<UsingShadowDecl>(*Res);
+ }
}
}
@@ -465,6 +468,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
case LookupResult::Found:
IIDecl = Result.getFoundDecl();
+ FoundUsingShadow = dyn_cast<UsingShadowDecl>(*Result.begin());
break;
}
@@ -491,14 +495,20 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
(void)DiagnoseUseOfDecl(IDecl, NameLoc);
if (!HasTrailingDot)
T = Context.getObjCInterfaceType(IDecl);
+ FoundUsingShadow = nullptr; // FIXME: Target must be a TypeDecl.
} else if (auto *UD = dyn_cast<UnresolvedUsingIfExistsDecl>(IIDecl)) {
(void)DiagnoseUseOfDecl(UD, NameLoc);
// Recover with 'int'
T = Context.IntTy;
+ FoundUsingShadow = nullptr;
} else if (AllowDeducedTemplate) {
- if (auto *TD = getAsTypeTemplateDecl(IIDecl))
+ if (auto *TD = getAsTypeTemplateDecl(IIDecl)) {
+ // FIXME: TemplateName should include FoundUsingShadow sugar.
T = Context.getDeducedTemplateSpecializationType(TemplateName(TD),
QualType(), false);
+ // Don't wrap in a further UsingType.
+ FoundUsingShadow = nullptr;
+ }
}
if (T.isNull()) {
@@ -507,6 +517,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
return nullptr;
}
+ if (FoundUsingShadow)
+ T = Context.getUsingType(FoundUsingShadow, T);
+
// 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).
@@ -843,21 +856,6 @@ static bool isTagTypeWithMissingTag(Sema &SemaRef, LookupResult &Result,
return false;
}
-/// Build a ParsedType for a simple-type-specifier with a nested-name-specifier.
-static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS,
- QualType T, SourceLocation NameLoc) {
- ASTContext &Context = S.Context;
-
- TypeLocBuilder Builder;
- Builder.pushTypeSpec(T).setNameLoc(NameLoc);
-
- T = S.getElaboratedType(ETK_None, SS, T);
- ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
- ElabTL.setElaboratedKeywordLoc(SourceLocation());
- ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
- return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
-}
-
Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
IdentifierInfo *&Name,
SourceLocation NameLoc,
@@ -1134,14 +1132,28 @@ Corrected:
: NameClassification::TypeTemplate(Template);
}
+ auto BuildTypeFor = [&](TypeDecl *Type, NamedDecl *Found) {
+ QualType T = Context.getTypeDeclType(Type);
+ if (const auto *USD = dyn_cast<UsingShadowDecl>(Found))
+ T = Context.getUsingType(USD, T);
+
+ if (SS.isEmpty()) // No elaborated type, trivial location info
+ return ParsedType::make(T);
+
+ TypeLocBuilder Builder;
+ Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+ T = getElaboratedType(ETK_None, SS, T);
+ ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+ ElabTL.setElaboratedKeywordLoc(SourceLocation());
+ ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
+ return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+ };
+
NamedDecl *FirstDecl = (*Result.begin())->getUnderlyingDecl();
if (TypeDecl *Type = dyn_cast<TypeDecl>(FirstDecl)) {
DiagnoseUseOfDecl(Type, NameLoc);
MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
- QualType T = Context.getTypeDeclType(Type);
- if (SS.isNotEmpty())
- return buildNestedType(*this, SS, T, NameLoc);
- return ParsedType::make(T);
+ return BuildTypeFor(Type, *Result.begin());
}
ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(FirstDecl);
@@ -1190,10 +1202,7 @@ Corrected:
isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) {
TypeDecl *Type = Result.getAsSingle<TypeDecl>();
DiagnoseUseOfDecl(Type, NameLoc);
- QualType T = Context.getTypeDeclType(Type);
- if (SS.isNotEmpty())
- return buildNestedType(*this, SS, T, NameLoc);
- return ParsedType::make(T);
+ return BuildTypeFor(Type, *Result.begin());
}
// If we already know which single declaration is referenced, just annotate
@@ -8504,7 +8513,14 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
<< NewFD->getParamDecl(Idx - 1)->getType();
} else if (FDisConst != NewFDisConst) {
SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match)
- << NewFDisConst << FD->getSourceRange().getEnd();
+ << NewFDisConst << FD->getSourceRange().getEnd()
+ << (NewFDisConst
+ ? FixItHint::CreateRemoval(ExtraArgs.D.getFunctionTypeInfo()
+ .getConstQualifierLoc())
+ : FixItHint::CreateInsertion(ExtraArgs.D.getFunctionTypeInfo()
+ .getRParenLoc()
+ .getLocWithOffset(1),
+ " const"));
} else
SemaRef.Diag(FD->getLocation(),
IsMember ? diag::note_member_def_close_match
@@ -9195,6 +9211,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
<< Name << RemoveRange
<< FixItHint::CreateRemoval(RemoveRange)
<< FixItHint::CreateInsertion(InsertLoc, "<>");
+ Invalid = true;
}
}
} else {
@@ -15359,7 +15376,7 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) {
if (BT->isInteger())
return false;
- if (T->isExtIntType())
+ if (T->isBitIntType())
return false;
return Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T;
@@ -18277,7 +18294,7 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
// Emit one note for each of the remaining enum constants with
// the same value.
- for (auto *ECD : llvm::make_range(Vec->begin() + 1, Vec->end()))
+ for (auto *ECD : llvm::drop_begin(*Vec))
S.Diag(ECD->getLocation(), diag::note_duplicate_element)
<< ECD << toString(ECD->getInitVal(), 10)
<< ECD->getSourceRange();