Clang note: forward declaration of class here (note_forward_class)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: forward declaration of class here
Type Note
Category Semantic Issue
Internal Id note_forward_class
Internal Message forward declaration of class here
Regular Expression note\: forward declaration of class here
First Commit 2010-12-16 7cabbe04ebdd Improve diagnostics when property being looked up

Description

The note is issued by the Clang compiler when a class has been forward-declared but not defined within the visible scope of the file being compiled. Forward declaration is a declaration of a class, function, or variable that tells the compiler about its existence without describing its complete structure or definition at the point of declaration. This practice is commonly used to resolve circular dependencies between classes or to reduce compilation times by omitting unnecessary details.

When the compiler encounters usage of a forward-declared class in a manner that requires knowledge of its complete definition (such as instantiation, member access, or method calls), and the definition is not available, it cannot verify the correctness of such operations. As a result, the compiler generates this note alongside a warning or error to indicate the location of the forward declaration. This information is crucial for developers to understand the context of the diagnostic message and to take the appropriate action, which typically involves including the header file that contains the complete definition of the class, if it exists.

 
AI Generated

Example

In the following example, an Objective-C program is demonstrated where a class, named C, is forward-declared using @class C;. This declaration informs the compiler about the existence of the class C without providing its full definition. During the execution of the main function, an attempt is made to send a message unknownMethod to the class C using [C performSelector:@selector(unknownMethod)];. Since C is only forward-declared and its complete definition is not visible, the compiler cannot verify whether C can respond to the message unknownMethod. As a consequence, the compiler issues a warning indicating that the receiver 'C' is a forward class and the corresponding @interface might not exist. Additionally, a note is generated to point out the location of the forward declaration of class C, and another warning is shown to highlight that the class method '+performSelector:' is not found, with the return type defaulting to 'id'.  
AI Generated


Flags -xobjective-c

[Try out in Compiler Explorer]

Source
@class C;

int main() {
  [C performSelector:@selector(unknownMethod)]; // Forward declaration of C
  return 0;
}
Compiler Output
<source>:4:4: warning: receiver 'C' is a forward class and corresponding @interface may not exist [-Wreceiver-forward-class]
<source>:1:8: note: forward declaration of class here
<source>:4:6: warning: class method '+performSelector:' not found (return type defaults to 'id') [-Wobjc-method-access]


Clang Internals (17.0.6)

Git Commit Message

Improve diagnostics when property being looked up
in a forward @class object. // rdar://8774513

llvm-svn: 121933

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaAvailability.cpp (line 551)

/// Actually emit an availability diagnostic for a reference to an unavailable
/// decl.
///
/// \param Ctx The context that the reference occurred in
/// \param ReferringDecl The exact declaration that was referenced.
/// \param OffendingDecl A related decl to \c ReferringDecl that has an
/// availability attribute corresponding to \c K attached to it. Note that this
/// may not be the same as ReferringDecl, i.e. if an EnumDecl is annotated and
/// we refer to a member EnumConstantDecl, ReferringDecl is the EnumConstantDecl
/// and OffendingDecl is the EnumDecl.
static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K, Decl *Ctx, const NamedDecl *ReferringDecl, const NamedDecl *OffendingDecl, StringRef Message, ArrayRef<SourceLocation> Locs, const ObjCInterfaceDecl *UnknownObjCClass, const ObjCPropertyDecl *ObjCProperty, bool ObjCPropertyAccess) {
  // ...
  if (!Message.empty()) {
  // ...
  } else if (!UnknownObjCClass) {
  // ...
  } else {
    // ...
    S.Diag(UnknownObjCClass->getLocation(), diag::note_forward_class);

clang/lib/Sema/SemaExprObjC.cpp (line 209)

/// Validates ObjCInterfaceDecl availability.
/// ObjCInterfaceDecl, used to create ObjC literals, should be defined
/// if clang not in a debugger mode.
static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl, SourceLocation Loc, Sema::ObjCLiteralKind LiteralKind) {
  if (!Decl) {
  // ...
  } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
    // ...
    S.Diag(Decl->getLocation(), diag::note_forward_class);

clang/lib/Sema/SemaType.cpp (line 9252)

/// The implementation of RequireCompleteType
bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser *Diagnoser) {
  // ...
  // If the Objective-C class was a forward declaration, produce a note.
  if (IFace && !IFace->isInvalidDecl() && !IFace->getLocation().isInvalid())
    Diag(IFace->getLocation(), diag::note_forward_class);

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/SemaObjC/exprs.m

  • clang/test/SemaObjC/exprs.m:36:8: note: forward declaration of class here