forked from OSchip/llvm-project
[clang][extract-api] Use correct language info from inputs
The current way of getting the `clang::Language` from `LangOptions` does not handle Objective-C correctly because `clang::Language::ObjC` does not correspond to any `LangStandard`. This patch passes the correct `Language` from the frontend input information. Differential Revision: https://reviews.llvm.org/D122495
This commit is contained in:
parent
ef6f7c4a60
commit
15bf0e5673
|
@ -309,8 +309,8 @@ public:
|
|||
/// Get the target triple for the ExtractAPI invocation.
|
||||
const llvm::Triple &getTarget() const { return Target; }
|
||||
|
||||
/// Get the language options used to parse the APIs.
|
||||
const LangOptions &getLangOpts() const { return LangOpts; }
|
||||
/// Get the language used by the APIs.
|
||||
Language getLanguage() const { return Lang; }
|
||||
|
||||
const GlobalRecordMap &getGlobals() const { return Globals; }
|
||||
const EnumRecordMap &getEnums() const { return Enums; }
|
||||
|
@ -328,8 +328,8 @@ public:
|
|||
/// \returns a StringRef of the copied string in APISet::Allocator.
|
||||
StringRef copyString(StringRef String);
|
||||
|
||||
APISet(const llvm::Triple &Target, const LangOptions &LangOpts)
|
||||
: Target(Target), LangOpts(LangOpts) {}
|
||||
APISet(const llvm::Triple &Target, Language Lang)
|
||||
: Target(Target), Lang(Lang) {}
|
||||
|
||||
private:
|
||||
/// BumpPtrAllocator to store generated/copied strings.
|
||||
|
@ -338,7 +338,7 @@ private:
|
|||
llvm::BumpPtrAllocator StringAllocator;
|
||||
|
||||
const llvm::Triple Target;
|
||||
const LangOptions LangOpts;
|
||||
const Language Lang;
|
||||
|
||||
GlobalRecordMap Globals;
|
||||
EnumRecordMap Enums;
|
||||
|
|
|
@ -41,9 +41,8 @@ namespace {
|
|||
/// information.
|
||||
class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> {
|
||||
public:
|
||||
explicit ExtractAPIVisitor(ASTContext &Context)
|
||||
: Context(Context),
|
||||
API(Context.getTargetInfo().getTriple(), Context.getLangOpts()) {}
|
||||
ExtractAPIVisitor(ASTContext &Context, Language Lang)
|
||||
: Context(Context), API(Context.getTargetInfo().getTriple(), Lang) {}
|
||||
|
||||
const APISet &getAPI() const { return API; }
|
||||
|
||||
|
@ -309,9 +308,9 @@ private:
|
|||
|
||||
class ExtractAPIConsumer : public ASTConsumer {
|
||||
public:
|
||||
ExtractAPIConsumer(ASTContext &Context, StringRef ProductName,
|
||||
ExtractAPIConsumer(ASTContext &Context, StringRef ProductName, Language Lang,
|
||||
std::unique_ptr<raw_pwrite_stream> OS)
|
||||
: Visitor(Context), ProductName(ProductName), OS(std::move(OS)) {}
|
||||
: Visitor(Context, Lang), ProductName(ProductName), OS(std::move(OS)) {}
|
||||
|
||||
void HandleTranslationUnit(ASTContext &Context) override {
|
||||
// Use ExtractAPIVisitor to traverse symbol declarations in the context.
|
||||
|
@ -339,6 +338,7 @@ ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
|
|||
return nullptr;
|
||||
return std::make_unique<ExtractAPIConsumer>(
|
||||
CI.getASTContext(), CI.getInvocation().getFrontendOpts().ProductName,
|
||||
CI.getFrontendOpts().Inputs.back().getKind().getLanguage(),
|
||||
std::move(OS));
|
||||
}
|
||||
|
||||
|
|
|
@ -151,11 +151,9 @@ Optional<Object> serializeAvailability(const AvailabilityInfo &Avail) {
|
|||
return Availbility;
|
||||
}
|
||||
|
||||
/// Get the short language name string for interface language references.
|
||||
StringRef getLanguageName(const LangOptions &LangOpts) {
|
||||
auto LanguageKind =
|
||||
LangStandard::getLangStandardForKind(LangOpts.LangStd).getLanguage();
|
||||
switch (LanguageKind) {
|
||||
/// Get the language name string for interface language references.
|
||||
StringRef getLanguageName(Language Lang) {
|
||||
switch (Lang) {
|
||||
case Language::C:
|
||||
return "c";
|
||||
case Language::ObjC:
|
||||
|
@ -185,11 +183,10 @@ StringRef getLanguageName(const LangOptions &LangOpts) {
|
|||
///
|
||||
/// The identifier property of a symbol contains the USR for precise and unique
|
||||
/// references, and the interface language name.
|
||||
Object serializeIdentifier(const APIRecord &Record,
|
||||
const LangOptions &LangOpts) {
|
||||
Object serializeIdentifier(const APIRecord &Record, Language Lang) {
|
||||
Object Identifier;
|
||||
Identifier["precise"] = Record.USR;
|
||||
Identifier["interfaceLanguage"] = getLanguageName(LangOpts);
|
||||
Identifier["interfaceLanguage"] = getLanguageName(Lang);
|
||||
|
||||
return Identifier;
|
||||
}
|
||||
|
@ -335,10 +332,9 @@ Object serializeNames(const APIRecord &Record) {
|
|||
/// The Symbol Graph symbol kind property contains a shorthand \c identifier
|
||||
/// which is prefixed by the source language name, useful for tooling to parse
|
||||
/// the kind, and a \c displayName for rendering human-readable names.
|
||||
Object serializeSymbolKind(const APIRecord &Record,
|
||||
const LangOptions &LangOpts) {
|
||||
auto AddLangPrefix = [&LangOpts](StringRef S) -> std::string {
|
||||
return (getLanguageName(LangOpts) + "." + S).str();
|
||||
Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
|
||||
auto AddLangPrefix = [&Lang](StringRef S) -> std::string {
|
||||
return (getLanguageName(Lang) + "." + S).str();
|
||||
};
|
||||
|
||||
Object Kind;
|
||||
|
@ -420,8 +416,8 @@ SymbolGraphSerializer::serializeAPIRecord(const APIRecord &Record) const {
|
|||
|
||||
Object Obj;
|
||||
serializeObject(Obj, "identifier",
|
||||
serializeIdentifier(Record, API.getLangOpts()));
|
||||
serializeObject(Obj, "kind", serializeSymbolKind(Record, API.getLangOpts()));
|
||||
serializeIdentifier(Record, API.getLanguage()));
|
||||
serializeObject(Obj, "kind", serializeSymbolKind(Record, API.getLanguage()));
|
||||
serializeObject(Obj, "names", serializeNames(Record));
|
||||
serializeObject(
|
||||
Obj, "location",
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: split-file %s %t
|
||||
// RUN: sed -e "s@INPUT_DIR@%/t@g" %t/c.reference.output.json.in >> \
|
||||
// RUN: %t/c.reference.output.json
|
||||
// RUN: sed -e "s@INPUT_DIR@%/t@g" %t/objc.reference.output.json.in >> \
|
||||
// RUN: %t/objc.reference.output.json
|
||||
|
||||
// RUN: %clang -extract-api -x c-header -target arm64-apple-macosx \
|
||||
// RUN: %t/c.h -o %t/c.output.json | FileCheck -allow-empty %s
|
||||
// RUN: %clang -extract-api -x objective-c-header -target arm64-apple-macosx \
|
||||
// RUN: %t/objc.h -o %t/objc.output.json | FileCheck -allow-empty %s
|
||||
|
||||
// Generator version is not consistent across test runs, normalize it.
|
||||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
|
||||
// RUN: %t/c.output.json >> %t/c.output-normalized.json
|
||||
// RUN: sed -e "s@\"generator\": \".*\"@\"generator\": \"?\"@g" \
|
||||
// RUN: %t/objc.output.json >> %t/objc.output-normalized.json
|
||||
|
||||
// RUN: diff %t/c.reference.output.json %t/c.output-normalized.json
|
||||
// RUN: diff %t/objc.reference.output.json %t/objc.output-normalized.json
|
||||
|
||||
// CHECK-NOT: error:
|
||||
// CHECK-NOT: warning:
|
||||
|
||||
//--- c.h
|
||||
char c;
|
||||
|
||||
//--- objc.h
|
||||
char objc;
|
||||
|
||||
//--- c.reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationhips": [],
|
||||
"symbols": [
|
||||
{
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:C",
|
||||
"spelling": "char"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "c"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "c",
|
||||
"precise": "c:@c"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Global Variable",
|
||||
"identifier": "c.var"
|
||||
},
|
||||
"location": {
|
||||
"character": 6,
|
||||
"line": 1,
|
||||
"uri": "file://INPUT_DIR/c.h"
|
||||
},
|
||||
"names": {
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "c"
|
||||
}
|
||||
],
|
||||
"title": "c"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
//--- objc.reference.output.json.in
|
||||
{
|
||||
"metadata": {
|
||||
"formatVersion": {
|
||||
"major": 0,
|
||||
"minor": 5,
|
||||
"patch": 3
|
||||
},
|
||||
"generator": "?"
|
||||
},
|
||||
"module": {
|
||||
"name": "",
|
||||
"platform": {
|
||||
"architecture": "arm64",
|
||||
"operatingSystem": {
|
||||
"minimumVersion": {
|
||||
"major": 11,
|
||||
"minor": 0,
|
||||
"patch": 0
|
||||
},
|
||||
"name": "macosx"
|
||||
},
|
||||
"vendor": "apple"
|
||||
}
|
||||
},
|
||||
"relationhips": [],
|
||||
"symbols": [
|
||||
{
|
||||
"declarationFragments": [
|
||||
{
|
||||
"kind": "typeIdentifier",
|
||||
"preciseIdentifier": "c:C",
|
||||
"spelling": "char"
|
||||
},
|
||||
{
|
||||
"kind": "text",
|
||||
"spelling": " "
|
||||
},
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "objc"
|
||||
}
|
||||
],
|
||||
"identifier": {
|
||||
"interfaceLanguage": "objective-c",
|
||||
"precise": "c:@objc"
|
||||
},
|
||||
"kind": {
|
||||
"displayName": "Global Variable",
|
||||
"identifier": "objective-c.var"
|
||||
},
|
||||
"location": {
|
||||
"character": 6,
|
||||
"line": 1,
|
||||
"uri": "file://INPUT_DIR/objc.h"
|
||||
},
|
||||
"names": {
|
||||
"subHeading": [
|
||||
{
|
||||
"kind": "identifier",
|
||||
"spelling": "objc"
|
||||
}
|
||||
],
|
||||
"title": "objc"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue