From 529a0570f7e8c5144bd3ad057e43f00e3af58d1b Mon Sep 17 00:00:00 2001 From: Daniel Grumberg Date: Tue, 29 Mar 2022 17:48:11 +0100 Subject: [clang][extract-api] Add support for macros To achieve this we hook into the preprocessor during the ExtractAPIAction and record definitions for macros that don't get undefined during preprocessing. --- clang/lib/ExtractAPI/API.cpp | 87 +++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 42 deletions(-) (limited to 'clang/lib/ExtractAPI/API.cpp') diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 1c9314c..66ebbb5 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -17,11 +17,30 @@ #include "clang/AST/CommentLexer.h" #include "clang/AST/RawCommentList.h" #include "clang/Index/USRGeneration.h" +#include "llvm/ADT/STLFunctionalExtras.h" +#include "llvm/ADT/StringRef.h" #include using namespace clang::extractapi; using namespace llvm; +namespace { + +template +RecordTy *addTopLevelRecord(APISet::RecordMap &RecordMap, + StringRef Name, CtorArgsTy &&...CtorArgs) { + auto Result = RecordMap.insert({Name, nullptr}); + + // Create the record if it does not already exist + if (Result.second) + Result.first->second = + std::make_unique(Name, std::forward(CtorArgs)...); + + return Result.first->second.get(); +} + +} // namespace + GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, @@ -29,15 +48,8 @@ GlobalRecord *APISet::addGlobal(GVKind Kind, StringRef Name, StringRef USR, DeclarationFragments Fragments, DeclarationFragments SubHeading, FunctionSignature Signature) { - auto Result = Globals.insert({Name, nullptr}); - if (Result.second) { - // Create the record if it does not already exist. - auto Record = std::make_unique( - Kind, Name, USR, Loc, Availability, Linkage, Comment, Fragments, - SubHeading, Signature); - Result.first->second = std::move(Record); - } - return Result.first->second.get(); + return addTopLevelRecord(Globals, Name, USR, Loc, Availability, Linkage, + Comment, Fragments, SubHeading, Kind, Signature); } GlobalRecord * @@ -73,14 +85,8 @@ EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) { - auto Result = Enums.insert({Name, nullptr}); - if (Result.second) { - // Create the record if it does not already exist. - auto Record = std::make_unique( - Name, USR, Loc, Availability, Comment, Declaration, SubHeading); - Result.first->second = std::move(Record); - } - return Result.first->second.get(); + return addTopLevelRecord(Enums, Name, USR, Loc, Availability, Comment, + Declaration, SubHeading); } StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name, @@ -99,14 +105,8 @@ StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) { - auto Result = Structs.insert({Name, nullptr}); - if (Result.second) { - // Create the record if it does not already exist. - auto Record = std::make_unique( - Name, USR, Loc, Availability, Comment, Declaration, SubHeading); - Result.first->second = std::move(Record); - } - return Result.first->second.get(); + return addTopLevelRecord(Structs, Name, USR, Loc, Availability, Comment, + Declaration, SubHeading); } ObjCInterfaceRecord *APISet::addObjCInterface( @@ -114,15 +114,9 @@ ObjCInterfaceRecord *APISet::addObjCInterface( const AvailabilityInfo &Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, SymbolReference SuperClass) { - auto Result = ObjCInterfaces.insert({Name, nullptr}); - if (Result.second) { - // Create the record if it does not already exist. - auto Record = std::make_unique( - Name, USR, Loc, Availability, Linkage, Comment, Declaration, SubHeading, - SuperClass); - Result.first->second = std::move(Record); - } - return Result.first->second.get(); + return addTopLevelRecord(ObjCInterfaces, Name, USR, Loc, Availability, + Linkage, Comment, Declaration, SubHeading, + SuperClass); } ObjCMethodRecord *APISet::addObjCMethod( @@ -165,14 +159,15 @@ ObjCProtocolRecord *APISet::addObjCProtocol( StringRef Name, StringRef USR, PresumedLoc Loc, const AvailabilityInfo &Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading) { - auto Result = ObjCProtocols.insert({Name, nullptr}); - if (Result.second) { - // Create the record if it does not already exist. - auto Record = std::make_unique( - Name, USR, Loc, Availability, Comment, Declaration, SubHeading); - Result.first->second = std::move(Record); - } - return Result.first->second.get(); + return addTopLevelRecord(ObjCProtocols, Name, USR, Loc, Availability, Comment, + Declaration, SubHeading); +} + +MacroDefinitionRecord * +APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc, + DeclarationFragments Declaration, + DeclarationFragments SubHeading) { + return addTopLevelRecord(Macros, Name, USR, Loc, Declaration, SubHeading); } StringRef APISet::recordUSR(const Decl *D) { @@ -181,6 +176,13 @@ StringRef APISet::recordUSR(const Decl *D) { return copyString(USR); } +StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL, + const SourceManager &SM) { + SmallString<128> USR; + index::generateUSRForMacro(Name, SL, SM, USR); + return copyString(USR); +} + StringRef APISet::copyString(StringRef String) { if (String.empty()) return {}; @@ -208,3 +210,4 @@ void ObjCInstanceVariableRecord::anchor() {} void ObjCMethodRecord::anchor() {} void ObjCInterfaceRecord::anchor() {} void ObjCProtocolRecord::anchor() {} +void MacroDefinitionRecord::anchor() {} -- cgit v1.1