r339187 - Clean up and simplify RequireCompleteType.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 7 14:35:41 PDT 2018
Author: rsmith
Date: Tue Aug 7 14:35:41 2018
New Revision: 339187
URL: http://llvm.org/viewvc/llvm-project?rev=339187&view=rev
Log:
Clean up and simplify RequireCompleteType.
No functional change intended, except that we will now produce more
"declared here" notes.
Modified:
cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
cfe/trunk/test/SemaObjC/arc.m
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=339187&r1=339186&r2=339187&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Tue Aug 7 14:35:41 2018
@@ -209,11 +209,13 @@ bool Sema::RequireCompleteDeclContext(CX
if (!tag || tag->isDependentContext())
return false;
+ // Grab the tag definition, if there is one.
+ QualType type = Context.getTypeDeclType(tag);
+ tag = type->getAsTagDecl();
+
// If we're currently defining this type, then lookup into the
// type is okay: don't complain that it isn't complete yet.
- QualType type = Context.getTypeDeclType(tag);
- const TagType *tagType = type->getAs<TagType>();
- if (tagType && tagType->isBeingDefined())
+ if (tag->isBeingDefined())
return false;
SourceLocation loc = SS.getLastQualifierNameLoc();
@@ -229,13 +231,13 @@ bool Sema::RequireCompleteDeclContext(CX
// Fixed enum types are complete, but they aren't valid as scopes
// until we see a definition, so awkwardly pull out this special
// case.
- const EnumType *enumType = dyn_cast_or_null<EnumType>(tagType);
- if (!enumType)
+ auto *EnumD = dyn_cast<EnumDecl>(tag);
+ if (!EnumD)
return false;
- if (enumType->getDecl()->isCompleteDefinition()) {
+ if (EnumD->isCompleteDefinition()) {
// If we know about the definition but it is not visible, complain.
NamedDecl *SuggestedDef = nullptr;
- if (!hasVisibleDefinition(enumType->getDecl(), &SuggestedDef,
+ if (!hasVisibleDefinition(EnumD, &SuggestedDef,
/*OnlyNeedComplete*/false)) {
// If the user is going to see an error here, recover by making the
// definition visible.
@@ -249,11 +251,11 @@ bool Sema::RequireCompleteDeclContext(CX
// Try to instantiate the definition, if this is a specialization of an
// enumeration temploid.
- EnumDecl *ED = enumType->getDecl();
- if (EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
- MemberSpecializationInfo *MSI = ED->getMemberSpecializationInfo();
+ if (EnumDecl *Pattern = EnumD->getInstantiatedFromMemberEnum()) {
+ MemberSpecializationInfo *MSI = EnumD->getMemberSpecializationInfo();
if (MSI->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) {
- if (InstantiateEnum(loc, ED, Pattern, getTemplateInstantiationArgs(ED),
+ if (InstantiateEnum(loc, EnumD, Pattern,
+ getTemplateInstantiationArgs(EnumD),
TSK_ImplicitInstantiation)) {
SS.SetInvalid(SS.getRange());
return true;
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=339187&r1=339186&r2=339187&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Aug 7 14:35:41 2018
@@ -7684,39 +7684,24 @@ bool Sema::RequireCompleteTypeImpl(Sourc
return false;
}
- const TagType *Tag = T->getAs<TagType>();
- const ObjCInterfaceType *IFace = T->getAs<ObjCInterfaceType>();
+ TagDecl *Tag = dyn_cast_or_null<TagDecl>(Def);
+ ObjCInterfaceDecl *IFace = dyn_cast_or_null<ObjCInterfaceDecl>(Def);
- // If there's an unimported definition of this type in a module (for
- // instance, because we forward declared it, then imported the definition),
- // import that definition now.
- //
- // FIXME: What about other cases where an import extends a redeclaration
- // chain for a declaration that can be accessed through a mechanism other
- // than name lookup (eg, referenced in a template, or a variable whose type
- // could be completed by the module)?
- //
- // FIXME: Should we map through to the base array element type before
- // checking for a tag type?
+ // Give the external source a chance to provide a definition of the type.
+ // This is kept separate from completing the redeclaration chain so that
+ // external sources such as LLDB can avoid synthesizing a type definition
+ // unless it's actually needed.
if (Tag || IFace) {
- NamedDecl *D =
- Tag ? static_cast<NamedDecl *>(Tag->getDecl()) : IFace->getDecl();
-
// Avoid diagnosing invalid decls as incomplete.
- if (D->isInvalidDecl())
+ if (Def->isInvalidDecl())
return true;
// Give the external AST source a chance to complete the type.
if (auto *Source = Context.getExternalSource()) {
- if (Tag) {
- TagDecl *TagD = Tag->getDecl();
- if (TagD->hasExternalLexicalStorage())
- Source->CompleteType(TagD);
- } else {
- ObjCInterfaceDecl *IFaceD = IFace->getDecl();
- if (IFaceD->hasExternalLexicalStorage())
- Source->CompleteType(IFace->getDecl());
- }
+ if (Tag && Tag->hasExternalLexicalStorage())
+ Source->CompleteType(Tag);
+ if (IFace && IFace->hasExternalLexicalStorage())
+ Source->CompleteType(IFace);
// If the external source completed the type, go through the motions
// again to ensure we're allowed to use the completed type.
if (!T->isIncompleteType())
@@ -7727,32 +7712,31 @@ bool Sema::RequireCompleteTypeImpl(Sourc
// If we have a class template specialization or a class member of a
// class template specialization, or an array with known size of such,
// try to instantiate it.
- QualType MaybeTemplate = T;
- while (const ConstantArrayType *Array
- = Context.getAsConstantArrayType(MaybeTemplate))
- MaybeTemplate = Array->getElementType();
- if (const RecordType *Record = MaybeTemplate->getAs<RecordType>()) {
+ if (auto *RD = dyn_cast_or_null<CXXRecordDecl>(Tag)) {
bool Instantiated = false;
bool Diagnosed = false;
- if (ClassTemplateSpecializationDecl *ClassTemplateSpec
- = dyn_cast<ClassTemplateSpecializationDecl>(Record->getDecl())) {
+ if (RD->isDependentContext()) {
+ // Don't try to instantiate a dependent class (eg, a member template of
+ // an instantiated class template specialization).
+ // FIXME: Can this ever happen?
+ } else if (auto *ClassTemplateSpec =
+ dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
if (ClassTemplateSpec->getSpecializationKind() == TSK_Undeclared) {
Diagnosed = InstantiateClassTemplateSpecialization(
Loc, ClassTemplateSpec, TSK_ImplicitInstantiation,
/*Complain=*/Diagnoser);
Instantiated = true;
}
- } else if (CXXRecordDecl *Rec
- = dyn_cast<CXXRecordDecl>(Record->getDecl())) {
- CXXRecordDecl *Pattern = Rec->getInstantiatedFromMemberClass();
- if (!Rec->isBeingDefined() && Pattern) {
- MemberSpecializationInfo *MSI = Rec->getMemberSpecializationInfo();
+ } else {
+ CXXRecordDecl *Pattern = RD->getInstantiatedFromMemberClass();
+ if (!RD->isBeingDefined() && Pattern) {
+ MemberSpecializationInfo *MSI = RD->getMemberSpecializationInfo();
assert(MSI && "Missing member specialization information?");
// This record was instantiated from a class within a template.
if (MSI->getTemplateSpecializationKind() !=
TSK_ExplicitSpecialization) {
- Diagnosed = InstantiateClass(Loc, Rec, Pattern,
- getTemplateInstantiationArgs(Rec),
+ Diagnosed = InstantiateClass(Loc, RD, Pattern,
+ getTemplateInstantiationArgs(RD),
TSK_ImplicitInstantiation,
/*Complain=*/Diagnoser);
Instantiated = true;
@@ -7783,15 +7767,15 @@ bool Sema::RequireCompleteTypeImpl(Sourc
// If the type was a forward declaration of a class/struct/union
// type, produce a note.
- if (Tag && !Tag->getDecl()->isInvalidDecl())
- Diag(Tag->getDecl()->getLocation(),
+ if (Tag && !Tag->isInvalidDecl())
+ Diag(Tag->getLocation(),
Tag->isBeingDefined() ? diag::note_type_being_defined
: diag::note_forward_declaration)
- << QualType(Tag, 0);
+ << Context.getTagDeclType(Tag);
// If the Objective-C class was a forward declaration, produce a note.
- if (IFace && !IFace->getDecl()->isInvalidDecl())
- Diag(IFace->getDecl()->getLocation(), diag::note_forward_class);
+ if (IFace && !IFace->isInvalidDecl())
+ Diag(IFace->getLocation(), diag::note_forward_class);
// If we have external information that we can use to suggest a fix,
// produce a note.
Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp?rev=339187&r1=339186&r2=339187&view=diff
==============================================================================
--- cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp (original)
+++ cfe/trunk/test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp Tue Aug 7 14:35:41 2018
@@ -108,7 +108,7 @@ void g() {
extern int incomplete[];
for (auto a : incomplete) // expected-error {{cannot use incomplete type 'int []' as a range}}
;
- extern struct Incomplete also_incomplete[2]; // expected-note {{forward declaration}}
+ extern struct Incomplete also_incomplete[2]; // expected-note 2{{forward declaration}}
for (auto &a : also_incomplete) // expected-error {{cannot use incomplete type 'struct Incomplete [2]' as a range}}
;
Modified: cfe/trunk/test/SemaObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc.m?rev=339187&r1=339186&r2=339187&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc.m (original)
+++ cfe/trunk/test/SemaObjC/arc.m Tue Aug 7 14:35:41 2018
@@ -410,7 +410,7 @@ void test16(void) {
[v test16_6: 0];
}
- at class Test17; // expected-note 2{{forward declaration of class here}}
+ at class Test17; // expected-note 3{{forward declaration of class here}}
@protocol Test17p
- (void) test17;
+ (void) test17;
More information about the cfe-commits
mailing list