[clang] 7443a50 - [clang][extract-api] Add support for true anonymous enums

Daniel Grumberg via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 12 12:45:14 PDT 2022


Author: Daniel Grumberg
Date: 2022-04-12T20:42:17+01:00
New Revision: 7443a504bf6c22b83727c1e43c82c4165b2d5db5

URL: https://github.com/llvm/llvm-project/commit/7443a504bf6c22b83727c1e43c82c4165b2d5db5
DIFF: https://github.com/llvm/llvm-project/commit/7443a504bf6c22b83727c1e43c82c4165b2d5db5.diff

LOG: [clang][extract-api] Add support for true anonymous enums

Anonymous enums without a typedef should have a "(anonymous)" identifier.

Differential Revision: https://reviews.llvm.org/D123533

Added: 
    

Modified: 
    clang/include/clang/ExtractAPI/API.h
    clang/lib/ExtractAPI/API.cpp
    clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
    clang/test/ExtractAPI/enum.c

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h
index 6a9429704d45e..53db46ca44c13 100644
--- a/clang/include/clang/ExtractAPI/API.h
+++ b/clang/include/clang/ExtractAPI/API.h
@@ -50,13 +50,13 @@ namespace extractapi {
 /// \endcode
 using DocComment = std::vector<RawComment::CommentLine>;
 
-// Classes deriving from APIRecord need to have Name be the first constructor
+// Classes deriving from APIRecord need to have USR be the first constructor
 // argument. This is so that they are compatible with `addTopLevelRecord`
 // defined in API.cpp
 /// The base representation of an API record. Holds common symbol information.
 struct APIRecord {
-  StringRef Name;
   StringRef USR;
+  StringRef Name;
   PresumedLoc Location;
   AvailabilityInfo Availability;
   LinkageInfo Linkage;
@@ -101,11 +101,11 @@ struct APIRecord {
 
   APIRecord() = delete;
 
-  APIRecord(RecordKind Kind, StringRef Name, StringRef USR,
+  APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
             PresumedLoc Location, const AvailabilityInfo &Availability,
             LinkageInfo Linkage, const DocComment &Comment,
             DeclarationFragments Declaration, DeclarationFragments SubHeading)
-      : Name(Name), USR(USR), Location(Location), Availability(Availability),
+      : USR(USR), Name(Name), Location(Location), Availability(Availability),
         Linkage(Linkage), Comment(Comment), Declaration(Declaration),
         SubHeading(SubHeading), Kind(Kind) {}
 
@@ -117,13 +117,13 @@ struct APIRecord {
 struct GlobalFunctionRecord : APIRecord {
   FunctionSignature Signature;
 
-  GlobalFunctionRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                        const AvailabilityInfo &Availability,
                        LinkageInfo Linkage, const DocComment &Comment,
                        DeclarationFragments Declaration,
                        DeclarationFragments SubHeading,
                        FunctionSignature Signature)
-      : APIRecord(RK_GlobalFunction, Name, USR, Loc, Availability, Linkage,
+      : APIRecord(RK_GlobalFunction, USR, Name, Loc, Availability, Linkage,
                   Comment, Declaration, SubHeading),
         Signature(Signature) {}
 
@@ -137,12 +137,12 @@ struct GlobalFunctionRecord : APIRecord {
 
 /// This holds information associated with global functions.
 struct GlobalVariableRecord : APIRecord {
-  GlobalVariableRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                        const AvailabilityInfo &Availability,
                        LinkageInfo Linkage, const DocComment &Comment,
                        DeclarationFragments Declaration,
                        DeclarationFragments SubHeading)
-      : APIRecord(RK_GlobalVariable, Name, USR, Loc, Availability, Linkage,
+      : APIRecord(RK_GlobalVariable, USR, Name, Loc, Availability, Linkage,
                   Comment, Declaration, SubHeading) {}
 
   static bool classof(const APIRecord *Record) {
@@ -155,12 +155,12 @@ struct GlobalVariableRecord : APIRecord {
 
 /// This holds information associated with enum constants.
 struct EnumConstantRecord : APIRecord {
-  EnumConstantRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                      const AvailabilityInfo &Availability,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading)
-      : APIRecord(RK_EnumConstant, Name, USR, Loc, Availability,
+      : APIRecord(RK_EnumConstant, USR, Name, Loc, Availability,
                   LinkageInfo::none(), Comment, Declaration, SubHeading) {}
 
   static bool classof(const APIRecord *Record) {
@@ -175,10 +175,10 @@ struct EnumConstantRecord : APIRecord {
 struct EnumRecord : APIRecord {
   SmallVector<std::unique_ptr<EnumConstantRecord>> Constants;
 
-  EnumRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
              const AvailabilityInfo &Availability, const DocComment &Comment,
              DeclarationFragments Declaration, DeclarationFragments SubHeading)
-      : APIRecord(RK_Enum, Name, USR, Loc, Availability, LinkageInfo::none(),
+      : APIRecord(RK_Enum, USR, Name, Loc, Availability, LinkageInfo::none(),
                   Comment, Declaration, SubHeading) {}
 
   static bool classof(const APIRecord *Record) {
@@ -191,11 +191,11 @@ struct EnumRecord : APIRecord {
 
 /// This holds information associated with struct fields.
 struct StructFieldRecord : APIRecord {
-  StructFieldRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                     const AvailabilityInfo &Availability,
                     const DocComment &Comment, DeclarationFragments Declaration,
                     DeclarationFragments SubHeading)
-      : APIRecord(RK_StructField, Name, USR, Loc, Availability,
+      : APIRecord(RK_StructField, USR, Name, Loc, Availability,
                   LinkageInfo::none(), Comment, Declaration, SubHeading) {}
 
   static bool classof(const APIRecord *Record) {
@@ -210,11 +210,11 @@ struct StructFieldRecord : APIRecord {
 struct StructRecord : APIRecord {
   SmallVector<std::unique_ptr<StructFieldRecord>> Fields;
 
-  StructRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                const AvailabilityInfo &Availability, const DocComment &Comment,
                DeclarationFragments Declaration,
                DeclarationFragments SubHeading)
-      : APIRecord(RK_Struct, Name, USR, Loc, Availability, LinkageInfo::none(),
+      : APIRecord(RK_Struct, USR, Name, Loc, Availability, LinkageInfo::none(),
                   Comment, Declaration, SubHeading) {}
 
   static bool classof(const APIRecord *Record) {
@@ -240,14 +240,14 @@ struct ObjCPropertyRecord : APIRecord {
   StringRef SetterName;
   bool IsOptional;
 
-  ObjCPropertyRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  ObjCPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                      const AvailabilityInfo &Availability,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading, AttributeKind Attributes,
                      StringRef GetterName, StringRef SetterName,
                      bool IsOptional)
-      : APIRecord(RK_ObjCProperty, Name, USR, Loc, Availability,
+      : APIRecord(RK_ObjCProperty, USR, Name, Loc, Availability,
                   LinkageInfo::none(), Comment, Declaration, SubHeading),
         Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
         IsOptional(IsOptional) {}
@@ -269,13 +269,13 @@ struct ObjCInstanceVariableRecord : APIRecord {
   using AccessControl = ObjCIvarDecl::AccessControl;
   AccessControl Access;
 
-  ObjCInstanceVariableRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                              const AvailabilityInfo &Availability,
                              const DocComment &Comment,
                              DeclarationFragments Declaration,
                              DeclarationFragments SubHeading,
                              AccessControl Access)
-      : APIRecord(RK_ObjCIvar, Name, USR, Loc, Availability,
+      : APIRecord(RK_ObjCIvar, USR, Name, Loc, Availability,
                   LinkageInfo::none(), Comment, Declaration, SubHeading),
         Access(Access) {}
 
@@ -292,12 +292,12 @@ struct ObjCMethodRecord : APIRecord {
   FunctionSignature Signature;
   bool IsInstanceMethod;
 
-  ObjCMethodRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  ObjCMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                    const AvailabilityInfo &Availability,
                    const DocComment &Comment, DeclarationFragments Declaration,
                    DeclarationFragments SubHeading, FunctionSignature Signature,
                    bool IsInstanceMethod)
-      : APIRecord(RK_ObjCMethod, Name, USR, Loc, Availability,
+      : APIRecord(RK_ObjCMethod, USR, Name, Loc, Availability,
                   LinkageInfo::none(), Comment, Declaration, SubHeading),
         Signature(Signature), IsInstanceMethod(IsInstanceMethod) {}
 
@@ -340,12 +340,12 @@ struct ObjCContainerRecord : APIRecord {
 
   ObjCContainerRecord() = delete;
 
-  ObjCContainerRecord(RecordKind Kind, StringRef Name, StringRef USR,
+  ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
                       PresumedLoc Loc, const AvailabilityInfo &Availability,
                       LinkageInfo Linkage, const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading)
-      : APIRecord(Kind, Name, USR, Loc, Availability, Linkage, Comment,
+      : APIRecord(Kind, USR, Name, Loc, Availability, Linkage, Comment,
                   Declaration, SubHeading) {}
 
   virtual ~ObjCContainerRecord() = 0;
@@ -355,12 +355,12 @@ struct ObjCContainerRecord : APIRecord {
 struct ObjCCategoryRecord : ObjCContainerRecord {
   SymbolReference Interface;
 
-  ObjCCategoryRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                      const AvailabilityInfo &Availability,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading, SymbolReference Interface)
-      : ObjCContainerRecord(RK_ObjCCategory, Name, USR, Loc, Availability,
+      : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc, Availability,
                             LinkageInfo::none(), Comment, Declaration,
                             SubHeading),
         Interface(Interface) {}
@@ -379,13 +379,13 @@ struct ObjCInterfaceRecord : ObjCContainerRecord {
   // ObjCCategoryRecord%s are stored in and owned by APISet.
   SmallVector<ObjCCategoryRecord *> Categories;
 
-  ObjCInterfaceRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                       const AvailabilityInfo &Availability, LinkageInfo Linkage,
                       const DocComment &Comment,
                       DeclarationFragments Declaration,
                       DeclarationFragments SubHeading,
                       SymbolReference SuperClass)
-      : ObjCContainerRecord(RK_ObjCInterface, Name, USR, Loc, Availability,
+      : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc, Availability,
                             Linkage, Comment, Declaration, SubHeading),
         SuperClass(SuperClass) {}
 
@@ -399,12 +399,12 @@ struct ObjCInterfaceRecord : ObjCContainerRecord {
 
 /// This holds information associated with Objective-C protocols.
 struct ObjCProtocolRecord : ObjCContainerRecord {
-  ObjCProtocolRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                      const AvailabilityInfo &Availability,
                      const DocComment &Comment,
                      DeclarationFragments Declaration,
                      DeclarationFragments SubHeading)
-      : ObjCContainerRecord(RK_ObjCProtocol, Name, USR, Loc, Availability,
+      : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc, Availability,
                             LinkageInfo::none(), Comment, Declaration,
                             SubHeading) {}
 
@@ -418,10 +418,10 @@ struct ObjCProtocolRecord : ObjCContainerRecord {
 
 /// This holds information associated with macro definitions.
 struct MacroDefinitionRecord : APIRecord {
-  MacroDefinitionRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  MacroDefinitionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                         DeclarationFragments Declaration,
                         DeclarationFragments SubHeading)
-      : APIRecord(RK_MacroDefinition, Name, USR, Loc, AvailabilityInfo(),
+      : APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilityInfo(),
                   LinkageInfo(), {}, Declaration, SubHeading) {}
 
   static bool classof(const APIRecord *Record) {
@@ -440,11 +440,11 @@ struct MacroDefinitionRecord : APIRecord {
 struct TypedefRecord : APIRecord {
   SymbolReference UnderlyingType;
 
-  TypedefRecord(StringRef Name, StringRef USR, PresumedLoc Loc,
+  TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
                 const AvailabilityInfo &Availability, const DocComment &Comment,
                 DeclarationFragments Declaration,
                 DeclarationFragments SubHeading, SymbolReference UnderlyingType)
-      : APIRecord(RK_Typedef, Name, USR, Loc, Availability, LinkageInfo(),
+      : APIRecord(RK_Typedef, USR, Name, Loc, Availability, LinkageInfo(),
                   Comment, Declaration, SubHeading),
         UnderlyingType(UnderlyingType) {}
 
@@ -647,8 +647,7 @@ class APISet {
                             DeclarationFragments SubHeading,
                             SymbolReference UnderlyingType);
 
-  /// A mapping type to store a set of APIRecord%s with the declaration name as
-  /// the key.
+  /// A mapping type to store a set of APIRecord%s with the USR as the key.
   template <typename RecordTy,
             typename =
                 std::enable_if_t<std::is_base_of<APIRecord, RecordTy>::value>>

diff  --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index 10d723d452cac..073e36f320d37 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -28,13 +28,13 @@ namespace {
 
 template <typename RecordTy, typename... CtorArgsTy>
 RecordTy *addTopLevelRecord(APISet::RecordMap<RecordTy> &RecordMap,
-                            StringRef Name, CtorArgsTy &&...CtorArgs) {
-  auto Result = RecordMap.insert({Name, nullptr});
+                            StringRef USR, CtorArgsTy &&...CtorArgs) {
+  auto Result = RecordMap.insert({USR, nullptr});
 
   // Create the record if it does not already exist
   if (Result.second)
     Result.first->second =
-        std::make_unique<RecordTy>(Name, std::forward<CtorArgsTy>(CtorArgs)...);
+        std::make_unique<RecordTy>(USR, std::forward<CtorArgsTy>(CtorArgs)...);
 
   return Result.first->second.get();
 }
@@ -46,7 +46,7 @@ APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
                      const AvailabilityInfo &Availability, LinkageInfo Linkage,
                      const DocComment &Comment, DeclarationFragments Fragments,
                      DeclarationFragments SubHeading) {
-  return addTopLevelRecord(GlobalVariables, Name, USR, Loc, Availability,
+  return addTopLevelRecord(GlobalVariables, USR, Name, Loc, Availability,
                            Linkage, Comment, Fragments, SubHeading);
 }
 
@@ -55,7 +55,7 @@ GlobalFunctionRecord *APISet::addGlobalFunction(
     const AvailabilityInfo &Availability, LinkageInfo Linkage,
     const DocComment &Comment, DeclarationFragments Fragments,
     DeclarationFragments SubHeading, FunctionSignature Signature) {
-  return addTopLevelRecord(GlobalFunctions, Name, USR, Loc, Availability,
+  return addTopLevelRecord(GlobalFunctions, USR, Name, Loc, Availability,
                            Linkage, Comment, Fragments, SubHeading, Signature);
 }
 
@@ -64,7 +64,7 @@ EnumConstantRecord *APISet::addEnumConstant(
     const AvailabilityInfo &Availability, const DocComment &Comment,
     DeclarationFragments Declaration, DeclarationFragments SubHeading) {
   auto Record = std::make_unique<EnumConstantRecord>(
-      Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
+      USR, Name, Loc, Availability, Comment, Declaration, SubHeading);
   return Enum->Constants.emplace_back(std::move(Record)).get();
 }
 
@@ -73,7 +73,7 @@ EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
                             const DocComment &Comment,
                             DeclarationFragments Declaration,
                             DeclarationFragments SubHeading) {
-  return addTopLevelRecord(Enums, Name, USR, Loc, Availability, Comment,
+  return addTopLevelRecord(Enums, USR, Name, Loc, Availability, Comment,
                            Declaration, SubHeading);
 }
 
@@ -84,7 +84,7 @@ StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name,
                                           DeclarationFragments Declaration,
                                           DeclarationFragments SubHeading) {
   auto Record = std::make_unique<StructFieldRecord>(
-      Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
+      USR, Name, Loc, Availability, Comment, Declaration, SubHeading);
   return Struct->Fields.emplace_back(std::move(Record)).get();
 }
 
@@ -93,7 +93,7 @@ StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
                                 const DocComment &Comment,
                                 DeclarationFragments Declaration,
                                 DeclarationFragments SubHeading) {
-  return addTopLevelRecord(Structs, Name, USR, Loc, Availability, Comment,
+  return addTopLevelRecord(Structs, USR, Name, Loc, Availability, Comment,
                            Declaration, SubHeading);
 }
 
@@ -103,12 +103,12 @@ ObjCCategoryRecord *APISet::addObjCCategory(
     DeclarationFragments Declaration, DeclarationFragments SubHeading,
     SymbolReference Interface) {
   // Create the category record.
-  auto *Record = addTopLevelRecord(ObjCCategories, Name, USR, Loc, Availability,
+  auto *Record = addTopLevelRecord(ObjCCategories, USR, Name, Loc, Availability,
                                    Comment, Declaration, SubHeading, Interface);
 
   // If this category is extending a known interface, associate it with the
   // ObjCInterfaceRecord.
-  auto It = ObjCInterfaces.find(Interface.Name);
+  auto It = ObjCInterfaces.find(Interface.USR);
   if (It != ObjCInterfaces.end())
     It->second->Categories.push_back(Record);
 
@@ -120,7 +120,7 @@ ObjCInterfaceRecord *APISet::addObjCInterface(
     const AvailabilityInfo &Availability, LinkageInfo Linkage,
     const DocComment &Comment, DeclarationFragments Declaration,
     DeclarationFragments SubHeading, SymbolReference SuperClass) {
-  return addTopLevelRecord(ObjCInterfaces, Name, USR, Loc, Availability,
+  return addTopLevelRecord(ObjCInterfaces, USR, Name, Loc, Availability,
                            Linkage, Comment, Declaration, SubHeading,
                            SuperClass);
 }
@@ -132,7 +132,7 @@ ObjCMethodRecord *APISet::addObjCMethod(
     DeclarationFragments SubHeading, FunctionSignature Signature,
     bool IsInstanceMethod) {
   auto Record = std::make_unique<ObjCMethodRecord>(
-      Name, USR, Loc, Availability, Comment, Declaration, SubHeading, Signature,
+      USR, Name, Loc, Availability, Comment, Declaration, SubHeading, Signature,
       IsInstanceMethod);
   return Container->Methods.emplace_back(std::move(Record)).get();
 }
@@ -145,7 +145,7 @@ ObjCPropertyRecord *APISet::addObjCProperty(
     ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName,
     StringRef SetterName, bool IsOptional) {
   auto Record = std::make_unique<ObjCPropertyRecord>(
-      Name, USR, Loc, Availability, Comment, Declaration, SubHeading,
+      USR, Name, Loc, Availability, Comment, Declaration, SubHeading,
       Attributes, GetterName, SetterName, IsOptional);
   return Container->Properties.emplace_back(std::move(Record)).get();
 }
@@ -157,7 +157,7 @@ ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable(
     DeclarationFragments SubHeading,
     ObjCInstanceVariableRecord::AccessControl Access) {
   auto Record = std::make_unique<ObjCInstanceVariableRecord>(
-      Name, USR, Loc, Availability, Comment, Declaration, SubHeading, Access);
+      USR, Name, Loc, Availability, Comment, Declaration, SubHeading, Access);
   return Container->Ivars.emplace_back(std::move(Record)).get();
 }
 
@@ -165,7 +165,7 @@ ObjCProtocolRecord *APISet::addObjCProtocol(
     StringRef Name, StringRef USR, PresumedLoc Loc,
     const AvailabilityInfo &Availability, const DocComment &Comment,
     DeclarationFragments Declaration, DeclarationFragments SubHeading) {
-  return addTopLevelRecord(ObjCProtocols, Name, USR, Loc, Availability, Comment,
+  return addTopLevelRecord(ObjCProtocols, USR, Name, Loc, Availability, Comment,
                            Declaration, SubHeading);
 }
 
@@ -173,7 +173,7 @@ MacroDefinitionRecord *
 APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
                            DeclarationFragments Declaration,
                            DeclarationFragments SubHeading) {
-  return addTopLevelRecord(Macros, Name, USR, Loc, Declaration, SubHeading);
+  return addTopLevelRecord(Macros, USR, Name, Loc, Declaration, SubHeading);
 }
 
 TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR,
@@ -183,7 +183,7 @@ TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR,
                                   DeclarationFragments Declaration,
                                   DeclarationFragments SubHeading,
                                   SymbolReference UnderlyingType) {
-  return addTopLevelRecord(Typedefs, Name, USR, Loc, Availability, Comment,
+  return addTopLevelRecord(Typedefs, USR, Name, Loc, Availability, Comment,
                            Declaration, SubHeading, UnderlyingType);
 }
 

diff  --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index e3700a0d390a2..0217c656cbb04 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -215,9 +215,11 @@ class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> {
       return true;
 
     // Collect symbol information.
-    StringRef Name = Decl->getName();
+    std::string NameString = Decl->getQualifiedNameAsString();
+    StringRef Name(NameString);
     if (Name.empty())
       Name = getTypedefName(Decl);
+
     StringRef USR = API.recordUSR(Decl);
     PresumedLoc Loc =
         Context.getSourceManager().getPresumedLoc(Decl->getLocation());
@@ -233,8 +235,9 @@ class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> {
     DeclarationFragments SubHeading =
         DeclarationFragmentsBuilder::getSubHeading(Decl);
 
-    EnumRecord *EnumRecord = API.addEnum(Name, USR, Loc, Availability, Comment,
-                                         Declaration, SubHeading);
+    EnumRecord *EnumRecord =
+        API.addEnum(API.copyString(Name), USR, Loc, Availability, Comment,
+                    Declaration, SubHeading);
 
     // Now collect information about the enumerators in this enum.
     recordEnumConstants(EnumRecord, Decl->enumerators());

diff  --git a/clang/test/ExtractAPI/enum.c b/clang/test/ExtractAPI/enum.c
index 49e39f7ba410a..a14666a037471 100644
--- a/clang/test/ExtractAPI/enum.c
+++ b/clang/test/ExtractAPI/enum.c
@@ -30,6 +30,14 @@ enum Direction : unsigned char {
   West
 };
 
+enum {
+  Constant = 1
+};
+
+enum {
+  OtherConstant = 2
+};
+
 //--- reference.output.json.in
 {
   "metadata": {
@@ -100,6 +108,16 @@ enum Direction : unsigned char {
       "kind": "memberOf",
       "source": "c:@E at Direction@West",
       "target": "c:@E at Direction"
+    },
+    {
+      "kind": "memberOf",
+      "source": "c:@Ea at Constant@Constant",
+      "target": "c:@Ea at Constant"
+    },
+    {
+      "kind": "memberOf",
+      "source": "c:@Ea at OtherConstant@OtherConstant",
+      "target": "c:@Ea at OtherConstant"
     }
   ],
   "symbols": [
@@ -641,6 +659,182 @@ enum Direction : unsigned char {
         "Direction",
         "West"
       ]
+    },
+    {
+      "accessLevel": "public",
+      "declarationFragments": [
+        {
+          "kind": "keyword",
+          "spelling": "enum"
+        },
+        {
+          "kind": "text",
+          "spelling": ": "
+        },
+        {
+          "kind": "typeIdentifier",
+          "preciseIdentifier": "c:i",
+          "spelling": "unsigned int"
+        }
+      ],
+      "identifier": {
+        "interfaceLanguage": "c",
+        "precise": "c:@Ea at Constant"
+      },
+      "kind": {
+        "displayName": "Enumeration",
+        "identifier": "c.enum"
+      },
+      "location": {
+        "position": {
+          "character": 1,
+          "line": 17
+        },
+        "uri": "file://INPUT_DIR/input.h"
+      },
+      "names": {
+        "navigator": [
+          {
+            "kind": "identifier",
+            "spelling": "(anonymous)"
+          }
+        ],
+        "title": "(anonymous)"
+      },
+      "pathComponents": [
+        "(anonymous)"
+      ]
+    },
+    {
+      "accessLevel": "public",
+      "declarationFragments": [
+        {
+          "kind": "identifier",
+          "spelling": "Constant"
+        }
+      ],
+      "identifier": {
+        "interfaceLanguage": "c",
+        "precise": "c:@Ea at Constant@Constant"
+      },
+      "kind": {
+        "displayName": "Enumeration Case",
+        "identifier": "c.enum.case"
+      },
+      "location": {
+        "position": {
+          "character": 3,
+          "line": 18
+        },
+        "uri": "file://INPUT_DIR/input.h"
+      },
+      "names": {
+        "navigator": [
+          {
+            "kind": "identifier",
+            "spelling": "Constant"
+          }
+        ],
+        "subHeading": [
+          {
+            "kind": "identifier",
+            "spelling": "Constant"
+          }
+        ],
+        "title": "Constant"
+      },
+      "pathComponents": [
+        "(anonymous)",
+        "Constant"
+      ]
+    },
+    {
+      "accessLevel": "public",
+      "declarationFragments": [
+        {
+          "kind": "keyword",
+          "spelling": "enum"
+        },
+        {
+          "kind": "text",
+          "spelling": ": "
+        },
+        {
+          "kind": "typeIdentifier",
+          "preciseIdentifier": "c:i",
+          "spelling": "unsigned int"
+        }
+      ],
+      "identifier": {
+        "interfaceLanguage": "c",
+        "precise": "c:@Ea at OtherConstant"
+      },
+      "kind": {
+        "displayName": "Enumeration",
+        "identifier": "c.enum"
+      },
+      "location": {
+        "position": {
+          "character": 1,
+          "line": 21
+        },
+        "uri": "file://INPUT_DIR/input.h"
+      },
+      "names": {
+        "navigator": [
+          {
+            "kind": "identifier",
+            "spelling": "(anonymous)"
+          }
+        ],
+        "title": "(anonymous)"
+      },
+      "pathComponents": [
+        "(anonymous)"
+      ]
+    },
+    {
+      "accessLevel": "public",
+      "declarationFragments": [
+        {
+          "kind": "identifier",
+          "spelling": "OtherConstant"
+        }
+      ],
+      "identifier": {
+        "interfaceLanguage": "c",
+        "precise": "c:@Ea at OtherConstant@OtherConstant"
+      },
+      "kind": {
+        "displayName": "Enumeration Case",
+        "identifier": "c.enum.case"
+      },
+      "location": {
+        "position": {
+          "character": 3,
+          "line": 22
+        },
+        "uri": "file://INPUT_DIR/input.h"
+      },
+      "names": {
+        "navigator": [
+          {
+            "kind": "identifier",
+            "spelling": "OtherConstant"
+          }
+        ],
+        "subHeading": [
+          {
+            "kind": "identifier",
+            "spelling": "OtherConstant"
+          }
+        ],
+        "title": "OtherConstant"
+      },
+      "pathComponents": [
+        "(anonymous)",
+        "OtherConstant"
+      ]
     }
   ]
 }


        


More information about the cfe-commits mailing list