-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[InstallAPI] Hookup Input files & basic ASTVisitor (#82552)
This patch takes in json files as input to determine that header files to process, and in which order, to pass along for CC1 invocations. This patch also includes an ASTVisitor to collect simple global variables.
- Loading branch information
1 parent
ad43ea3
commit c6cbf81
Showing
12 changed files
with
472 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
//===- InstallAPI/Frontend.h -----------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// Top level wrappers for InstallAPI frontend operations. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_INSTALLAPI_FRONTEND_H | ||
#define LLVM_CLANG_INSTALLAPI_FRONTEND_H | ||
|
||
#include "clang/AST/ASTConsumer.h" | ||
#include "clang/Frontend/CompilerInstance.h" | ||
#include "clang/Frontend/FrontendActions.h" | ||
#include "clang/InstallAPI/Context.h" | ||
#include "clang/InstallAPI/Visitor.h" | ||
#include "llvm/ADT/Twine.h" | ||
#include "llvm/Support/MemoryBuffer.h" | ||
|
||
namespace clang { | ||
namespace installapi { | ||
|
||
/// Create a buffer that contains all headers to scan | ||
/// for global symbols with. | ||
std::unique_ptr<llvm::MemoryBuffer> | ||
createInputBuffer(const InstallAPIContext &Ctx); | ||
|
||
class InstallAPIAction : public ASTFrontendAction { | ||
public: | ||
explicit InstallAPIAction(llvm::MachO::RecordsSlice &Records) | ||
: Records(Records) {} | ||
|
||
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, | ||
StringRef InFile) override { | ||
return std::make_unique<InstallAPIVisitor>(CI.getASTContext(), Records); | ||
} | ||
|
||
private: | ||
llvm::MachO::RecordsSlice &Records; | ||
}; | ||
} // namespace installapi | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_INSTALLAPI_FRONTEND_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
//===- InstallAPI/Visitor.h -----------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
/// | ||
/// ASTVisitor Interface for InstallAPI frontend operations. | ||
/// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_CLANG_INSTALLAPI_VISITOR_H | ||
#define LLVM_CLANG_INSTALLAPI_VISITOR_H | ||
|
||
#include "clang/AST/Mangle.h" | ||
#include "clang/AST/RecursiveASTVisitor.h" | ||
#include "clang/Basic/TargetInfo.h" | ||
#include "clang/Frontend/FrontendActions.h" | ||
#include "llvm/ADT/Twine.h" | ||
#include "llvm/TextAPI/RecordsSlice.h" | ||
|
||
namespace clang { | ||
namespace installapi { | ||
|
||
/// ASTVisitor for collecting declarations that represent global symbols. | ||
class InstallAPIVisitor final : public ASTConsumer, | ||
public RecursiveASTVisitor<InstallAPIVisitor> { | ||
public: | ||
InstallAPIVisitor(ASTContext &ASTCtx, llvm::MachO::RecordsSlice &Slice) | ||
: Slice(Slice), | ||
MC(ItaniumMangleContext::create(ASTCtx, ASTCtx.getDiagnostics())), | ||
Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {} | ||
void HandleTranslationUnit(ASTContext &ASTCtx) override; | ||
|
||
/// Collect global variables. | ||
bool VisitVarDecl(const VarDecl *D); | ||
|
||
private: | ||
std::string getMangledName(const NamedDecl *D) const; | ||
std::string getBackendMangledName(llvm::Twine Name) const; | ||
|
||
llvm::MachO::RecordsSlice &Slice; | ||
std::unique_ptr<clang::ItaniumMangleContext> MC; | ||
StringRef Layout; | ||
}; | ||
|
||
} // namespace installapi | ||
} // namespace clang | ||
|
||
#endif // LLVM_CLANG_INSTALLAPI_VISITOR_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//===- Frontend.cpp ---------------------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "clang/InstallAPI/Frontend.h" | ||
#include "clang/AST/Availability.h" | ||
#include "llvm/ADT/SmallString.h" | ||
#include "llvm/ADT/StringRef.h" | ||
|
||
using namespace llvm; | ||
using namespace llvm::MachO; | ||
|
||
namespace clang::installapi { | ||
|
||
static StringRef getFileExtension(clang::Language Lang) { | ||
switch (Lang) { | ||
default: | ||
llvm_unreachable("Unexpected language option."); | ||
case clang::Language::C: | ||
return ".c"; | ||
case clang::Language::CXX: | ||
return ".cpp"; | ||
case clang::Language::ObjC: | ||
return ".m"; | ||
case clang::Language::ObjCXX: | ||
return ".mm"; | ||
} | ||
} | ||
|
||
std::unique_ptr<MemoryBuffer> createInputBuffer(const InstallAPIContext &Ctx) { | ||
assert(Ctx.Type != HeaderType::Unknown && | ||
"unexpected access level for parsing"); | ||
SmallString<4096> Contents; | ||
raw_svector_ostream OS(Contents); | ||
for (const HeaderFile &H : Ctx.InputHeaders) { | ||
if (H.getType() != Ctx.Type) | ||
continue; | ||
if (Ctx.LangMode == Language::C || Ctx.LangMode == Language::CXX) | ||
OS << "#include "; | ||
else | ||
OS << "#import "; | ||
if (H.useIncludeName()) | ||
OS << "<" << H.getIncludeName() << ">"; | ||
else | ||
OS << "\"" << H.getPath() << "\""; | ||
} | ||
if (Contents.empty()) | ||
return nullptr; | ||
|
||
return llvm::MemoryBuffer::getMemBufferCopy( | ||
Contents, "installapi-includes" + getFileExtension(Ctx.LangMode)); | ||
} | ||
|
||
} // namespace clang::installapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//===- Visitor.cpp ---------------------------------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#include "clang/InstallAPI/Visitor.h" | ||
#include "clang/AST/Availability.h" | ||
#include "clang/Basic/Linkage.h" | ||
#include "llvm/ADT/SmallString.h" | ||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/IR/DataLayout.h" | ||
#include "llvm/IR/Mangler.h" | ||
|
||
using namespace llvm; | ||
using namespace llvm::MachO; | ||
|
||
namespace clang::installapi { | ||
|
||
// Exported NamedDecl needs to have externally visibiliy linkage and | ||
// default visibility from LinkageComputer. | ||
static bool isExported(const NamedDecl *D) { | ||
auto LV = D->getLinkageAndVisibility(); | ||
return isExternallyVisible(LV.getLinkage()) && | ||
(LV.getVisibility() == DefaultVisibility); | ||
} | ||
|
||
static SymbolFlags getFlags(bool WeakDef, bool ThreadLocal) { | ||
SymbolFlags Result = SymbolFlags::None; | ||
if (WeakDef) | ||
Result |= SymbolFlags::WeakDefined; | ||
if (ThreadLocal) | ||
Result |= SymbolFlags::ThreadLocalValue; | ||
|
||
return Result; | ||
} | ||
|
||
void InstallAPIVisitor::HandleTranslationUnit(ASTContext &ASTCtx) { | ||
if (ASTCtx.getDiagnostics().hasErrorOccurred()) | ||
return; | ||
|
||
auto *D = ASTCtx.getTranslationUnitDecl(); | ||
TraverseDecl(D); | ||
} | ||
|
||
std::string InstallAPIVisitor::getMangledName(const NamedDecl *D) const { | ||
SmallString<256> Name; | ||
if (MC->shouldMangleDeclName(D)) { | ||
raw_svector_ostream NStream(Name); | ||
MC->mangleName(D, NStream); | ||
} else | ||
Name += D->getNameAsString(); | ||
|
||
return getBackendMangledName(Name); | ||
} | ||
|
||
std::string InstallAPIVisitor::getBackendMangledName(Twine Name) const { | ||
SmallString<256> FinalName; | ||
Mangler::getNameWithPrefix(FinalName, Name, DataLayout(Layout)); | ||
return std::string(FinalName); | ||
} | ||
|
||
/// Collect all global variables. | ||
bool InstallAPIVisitor::VisitVarDecl(const VarDecl *D) { | ||
// Skip function parameters. | ||
if (isa<ParmVarDecl>(D)) | ||
return true; | ||
|
||
// Skip variables in records. They are handled seperately for C++. | ||
if (D->getDeclContext()->isRecord()) | ||
return true; | ||
|
||
// Skip anything inside functions or methods. | ||
if (!D->isDefinedOutsideFunctionOrMethod()) | ||
return true; | ||
|
||
// If this is a template but not specialization or instantiation, skip. | ||
if (D->getASTContext().getTemplateOrSpecializationInfo(D) && | ||
D->getTemplateSpecializationKind() == TSK_Undeclared) | ||
return true; | ||
|
||
// TODO: Capture SourceLocation & Availability for Decls. | ||
const RecordLinkage Linkage = | ||
isExported(D) ? RecordLinkage::Exported : RecordLinkage::Internal; | ||
const bool WeakDef = D->hasAttr<WeakAttr>(); | ||
const bool ThreadLocal = D->getTLSKind() != VarDecl::TLS_None; | ||
Slice.addGlobal(getMangledName(D), Linkage, GlobalRecord::Kind::Variable, | ||
getFlags(WeakDef, ThreadLocal)); | ||
return true; | ||
} | ||
|
||
} // namespace clang::installapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.