[clang] [clang][ExtractAPI] Fix up casting from CXXClassRecord (PR #110983)
Daniel Grumberg via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 3 03:59:56 PDT 2024
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/110983
`RecordRecord::classOfKind` and `TagRecord::classofKind` didn't correctly capture `RK_CXXClass` and derived variants, e.g. `RK_ClassTemplate`. This materialized by anonymous C++ tag types not being correctly detected when they need to be merged with another record.
>From 0d94b2e151a3d2abde1139841100aef2e141ff94 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg <dgrumberg at apple.com>
Date: Thu, 3 Oct 2024 11:52:34 +0100
Subject: [PATCH] [clang][ExtractAPI] Fix up casting from CXXClassRecord
`RecordRecord::classOfKind` and `TagRecord::classofKind` didn't
correctly capture `RK_CXXClass` and derived variants, e.g.
`RK_ClassTemplate`. This materialized by anonymous C++ tag types not
being correctly detected when they need to be merged with another
record.
---
clang/include/clang/ExtractAPI/API.h | 37 +++++++++++++++-
.../ExtractAPI/anonymous_record_no_typedef.c | 44 +++++++++++++------
.../ExtractAPI/typedef_anonymous_record.c | 27 +++++++-----
3 files changed, 82 insertions(+), 26 deletions(-)
diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h
index 4f34fcc575e807..c30e6fac66d6ba 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -26,6 +26,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/TargetParser/Triple.h"
#include <cstddef>
#include <iterator>
@@ -615,7 +616,24 @@ struct TagRecord : APIRecord, RecordContext {
return classofKind(Record->getKind());
}
static bool classofKind(RecordKind K) {
- return K == RK_Struct || K == RK_Union || K == RK_Enum;
+ switch (K) {
+ case RK_Enum:
+ LLVM_FALLTHROUGH;
+ case RK_Struct:
+ LLVM_FALLTHROUGH;
+ case RK_Union:
+ LLVM_FALLTHROUGH;
+ case RK_CXXClass:
+ LLVM_FALLTHROUGH;
+ case RK_ClassTemplate:
+ LLVM_FALLTHROUGH;
+ case RK_ClassTemplateSpecialization:
+ LLVM_FALLTHROUGH;
+ case RK_ClassTemplatePartialSpecialization:
+ return true;
+ default:
+ return false;
+ }
}
bool IsEmbeddedInVarDeclarator;
@@ -684,7 +702,22 @@ struct RecordRecord : TagRecord {
return classofKind(Record->getKind());
}
static bool classofKind(RecordKind K) {
- return K == RK_Struct || K == RK_Union;
+ switch (K) {
+ case RK_Struct:
+ LLVM_FALLTHROUGH;
+ case RK_Union:
+ LLVM_FALLTHROUGH;
+ case RK_CXXClass:
+ LLVM_FALLTHROUGH;
+ case RK_ClassTemplate:
+ LLVM_FALLTHROUGH;
+ case RK_ClassTemplateSpecialization:
+ LLVM_FALLTHROUGH;
+ case RK_ClassTemplatePartialSpecialization:
+ return true;
+ default:
+ return false;
+ }
}
bool isAnonymousWithNoTypedef() { return Name.empty(); }
diff --git a/clang/test/ExtractAPI/anonymous_record_no_typedef.c b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
index 064c223ad56e73..c0c76ef1f06b57 100644
--- a/clang/test/ExtractAPI/anonymous_record_no_typedef.c
+++ b/clang/test/ExtractAPI/anonymous_record_no_typedef.c
@@ -1,11 +1,18 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
// RUN: -triple arm64-apple-macosx -isystem %S -fretain-comments-from-system-headers \
-// RUN: -x c-header %s -o %t/output.symbols.json -verify
+// RUN: -x c-header %s -o %t/output-c.symbols.json -verify
+//
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
+// RUN: -triple arm64-apple-macosx -isystem %S -fretain-comments-from-system-headers \
+// RUN: -x c++-header %s -o %t/output-cxx.symbols.json -verify
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBAL
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix PREFIX
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix CONTENT
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix GLOBAL
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix PREFIX
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix CONTENT
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix GLOBAL
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix PREFIX
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix CONTENT
/// A global variable with an anonymous struct type.
struct { char *prefix; char *content; } global;
// GLOBAL-LABEL: "!testLabel": "c:@global"
@@ -30,7 +37,7 @@ struct { char *prefix; char *content; } global;
// GLOBAL: "text": "A global variable with an anonymous struct type."
// GLOBAL: "kind": {
// GLOBAL-NEXT: "displayName": "Global Variable",
-// GLOBAL-NEXT: "identifier": "c.var"
+// GLOBAL-NEXT: "identifier": "c{{(\+\+)?}}.var"
// GLOBAL: "title": "global"
// GLOBAL: "pathComponents": [
// GLOBAL-NEXT: "global"
@@ -54,9 +61,12 @@ struct { char *prefix; char *content; } global;
/// A Vehicle
struct Vehicle {
- // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TYPE
- // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix BICYCLE
- // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix CAR
+ // RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix TYPE
+ // RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix BICYCLE
+ // RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix CAR
+ // RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix TYPE
+ // RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix BICYCLE
+ // RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix CAR
/// The type of vehicle.
enum {
Bicycle,
@@ -96,9 +106,12 @@ struct Vehicle {
// CAR-NEXT: "Car"
// CAR-NEXT: ]
- // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix INFORMATION
- // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix WHEELS
- // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix NAME
+ // RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix INFORMATION
+ // RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix WHEELS
+ // RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix NAME
+ // RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix INFORMATION
+ // RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix WHEELS
+ // RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix NAME
/// The information about the vehicle.
union {
int wheels;
@@ -145,8 +158,10 @@ struct Vehicle {
// NAME-NEXT: ]
};
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBALCASE
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix GLOBALOTHERCASE
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix GLOBALCASE
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix GLOBALOTHERCASE
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix GLOBALCASE
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix GLOBALOTHERCASE
enum {
GlobalCase,
GlobalOtherCase
@@ -163,7 +178,8 @@ enum {
// GLOBALOTHERCASE-NEXT: "GlobalOtherCase"
// GLOBALOTHERCASE-NEXT: ]
-// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix VEC
+// RUN: FileCheck %s --input-file %t/output-c.symbols.json --check-prefix VEC
+// RUN: FileCheck %s --input-file %t/output-cxx.symbols.json --check-prefix VEC
union Vector {
struct {
float X;
diff --git a/clang/test/ExtractAPI/typedef_anonymous_record.c b/clang/test/ExtractAPI/typedef_anonymous_record.c
index 8e298f8d9ce829..c100e30803e4c8 100644
--- a/clang/test/ExtractAPI/typedef_anonymous_record.c
+++ b/clang/test/ExtractAPI/typedef_anonymous_record.c
@@ -1,8 +1,11 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
-// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c-header %s -o %t/typedefchain.symbols.json -verify
+// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c-header %s -o %t/typedefchain-c.symbols.json -verify
+// RUN: %clang_cc1 -extract-api --pretty-sgf --emit-sgf-symbol-labels-for-testing \
+// RUN: --product-name=TypedefChain -triple arm64-apple-macosx -x c++-header %s -o %t/typedefchain-cxx.symbols.json -verify
-// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYSTRUCT
+// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix MYSTRUCT
+// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix MYSTRUCT
typedef struct { } MyStruct;
// MYSTRUCT-LABEL: "!testLabel": "c:@SA at MyStruct"
// MYSTRUCT: "accessLevel": "public",
@@ -34,7 +37,7 @@ typedef struct { } MyStruct;
// MYSTRUCT-NEXT: ]
// MYSTRUCT: "kind": {
// MYSTRUCT-NEXT: "displayName": "Structure",
-// MYSTRUCT-NEXT: "identifier": "c.struct"
+// MYSTRUCT-NEXT: "identifier": "c{{(\+\+)?}}.struct"
// MYSTRUCT: "names": {
// MYSTRUCT-NEXT: "navigator": [
// MYSTRUCT-NEXT: {
@@ -54,7 +57,8 @@ typedef struct { } MyStruct;
// MYSTRUCT-NEXT: "MyStruct"
// MYSTRUCT-NEXT: ]
-// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYSTRUCTSTRUCT
+// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix MYSTRUCTSTRUCT
+// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix MYSTRUCTSTRUCT
typedef MyStruct MyStructStruct;
// MYSTRUCTSTRUCT-LABEL: "!testLabel": "c:typedef_anonymous_record.c at T@MyStructStruct"
// MYSTRUCTSTRUCT: "accessLevel": "public",
@@ -87,10 +91,12 @@ typedef MyStruct MyStructStruct;
// MYSTRUCTSTRUCT-NEXT:],
// MYSTRUCTSTRUCT: "kind": {
// MYSTRUCTSTRUCT-NEXT: "displayName": "Type Alias",
-// MYSTRUCTSTRUCT-NEXT: "identifier": "c.typealias"
+// MYSTRUCTSTRUCT-NEXT: "identifier": "c{{(\+\+)?}}.typealias"
-// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYENUM
-// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix CASE
+// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix MYENUM
+// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix CASE
+// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix MYENUM
+// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix CASE
typedef enum { Case } MyEnum;
// MYENUM: "source": "c:@EA at MyEnum@Case",
// MYENUM-NEXT: "target": "c:@EA at MyEnum",
@@ -124,7 +130,7 @@ typedef enum { Case } MyEnum;
// MYENUM-NEXT:],
// MYENUM: "kind": {
// MYENUM-NEXT: "displayName": "Enumeration",
-// MYENUM-NEXT: "identifier": "c.enum"
+// MYENUM-NEXT: "identifier": "c{{(\+\+)?}}.enum"
// MYENUM: "names": {
// MYENUM-NEXT: "navigator": [
// MYENUM-NEXT: {
@@ -147,7 +153,8 @@ typedef enum { Case } MyEnum;
// CASE-NEXT: "Case"
// CASE-NEXT: ]
-// RUN: FileCheck %s --input-file %t/typedefchain.symbols.json --check-prefix MYENUMENUM
+// RUN: FileCheck %s --input-file %t/typedefchain-c.symbols.json --check-prefix MYENUMENUM
+// RUN: FileCheck %s --input-file %t/typedefchain-cxx.symbols.json --check-prefix MYENUMENUM
typedef MyEnum MyEnumEnum;
// MYENUMENUM-LABEL: "!testLabel": "c:typedef_anonymous_record.c at T@MyEnumEnum"
// MYENUMENUM: "declarationFragments": [
@@ -179,7 +186,7 @@ typedef MyEnum MyEnumEnum;
// MYENUMENUM-NEXT: ],
// MYENUMENUM: "kind": {
// MYENUMENUM-NEXT: "displayName": "Type Alias",
-// MYENUMENUM-NEXT: "identifier": "c.typealias"
+// MYENUMENUM-NEXT: "identifier": "c{{(\+\+)?}}.typealias"
// MYENUMENUM-NEXT: },
// MYENUMENUM: "title": "MyEnumEnum"
More information about the cfe-commits
mailing list