[PATCH] D34059: Get the file name for the symbol from the Module, not the SourceManager.
v.g.vassilev closed this revision. v.g.vassilev added a comment. Landed in r311844. https://reviews.llvm.org/D34059 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34059: Get the file name for the symbol from the Module, not the SourceManager.
rsmith accepted this revision. rsmith added a comment. This revision is now accepted and ready to land. Looks good, thanks! https://reviews.llvm.org/D34059 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34059: Get the file name for the symbol from the Module, not the SourceManager.
v.g.vassilev updated this revision to Diff 103572. v.g.vassilev added a comment. Update test file comment. https://reviews.llvm.org/D34059 Files: lib/CodeGen/CGDeclCXX.cpp unittests/CodeGen/CMakeLists.txt unittests/CodeGen/IncrementalProcessingTest.cpp Index: unittests/CodeGen/IncrementalProcessingTest.cpp === --- /dev/null +++ unittests/CodeGen/IncrementalProcessingTest.cpp @@ -0,0 +1,174 @@ +//=== unittests/CodeGen/IncrementalProcessingTest.cpp - IncrementalCodeGen ===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/ModuleBuilder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Parse/Parser.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/Triple.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/MemoryBuffer.h" +#include "gtest/gtest.h" + +#include + +using namespace llvm; +using namespace clang; + +namespace { + +// Incremental processing produces several modules, all using the same "main +// file". Make sure CodeGen can cope with that, e.g. for static initializers. +const char TestProgram1[] = +"extern \"C\" int funcForProg1() { return 17; }\n" +"struct EmitCXXGlobalInitFunc1 {\n" +" EmitCXXGlobalInitFunc1() {}\n" +"} test1;"; + +const char TestProgram2[] = +"extern \"C\" int funcForProg2() { return 42; }\n" +"struct EmitCXXGlobalInitFunc2 {\n" +" EmitCXXGlobalInitFunc2() {}\n" +"} test2;"; + + +/// An incremental version of ParseAST(). +static std::unique_ptr +IncrementalParseAST(CompilerInstance& CI, Parser& P, +CodeGenerator& CG, const char* code) { + static int counter = 0; + struct IncreaseCounterOnRet { +~IncreaseCounterOnRet() { + ++counter; +} + } ICOR; + + Sema& S = CI.getSema(); + clang::SourceManager = S.getSourceManager(); + if (!code) { +// Main file +SM.setMainFileID(SM.createFileID( +llvm::MemoryBuffer::getMemBuffer(""), clang::SrcMgr::C_User)); + +S.getPreprocessor().EnterMainSourceFile(); +P.Initialize(); + } else { +FileID FID = SM.createFileID( +llvm::MemoryBuffer::getMemBuffer(code), clang::SrcMgr::C_User); +SourceLocation MainStartLoc = SM.getLocForStartOfFile(SM.getMainFileID()); +SourceLocation InclLoc = MainStartLoc.getLocWithOffset(counter); +S.getPreprocessor().EnterSourceFile(FID, 0, InclLoc); + } + + ExternalASTSource *External = S.getASTContext().getExternalSource(); + if (External) +External->StartTranslationUnit(); + + Parser::DeclGroupPtrTy ADecl; + for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF; + AtEOF = P.ParseTopLevelDecl(ADecl)) { +// If we got a null return and something *was* parsed, ignore it. This +// is due to a top-level semicolon, an action override, or a parse error +// skipping something. +if (ADecl && !CG.HandleTopLevelDecl(ADecl.get())) + return false; + } + + // Process any TopLevelDecls generated by #pragma weak. + for (Decl *D : S.WeakTopLevelDecls()) +CG.HandleTopLevelDecl(DeclGroupRef(D)); + + CG.HandleTranslationUnit(S.getASTContext()); + + std::unique_ptr M(CG.ReleaseModule()); + // Switch to next module. + CG.StartModule("incremental-module-" + std::to_string(counter), + M->getContext(), CI.getCodeGenOpts()); + return M; +} + +const Function* getGlobalInit(llvm::Module& M) { + for (const auto& Func: M) +if (Func.hasName() && Func.getName().startswith("_GLOBAL__sub_I_")) + return + + return nullptr; +} + +TEST(IncrementalProcessing, EmitCXXGlobalInitFunc) { +LLVMContext Context; +CompilerInstance compiler; + +compiler.createDiagnostics(); +compiler.getLangOpts().CPlusPlus = 1; +compiler.getLangOpts().CPlusPlus11 = 1; + +compiler.getTargetOpts().Triple = llvm::Triple::normalize( +llvm::sys::getProcessTriple()); +compiler.setTarget(clang::TargetInfo::CreateTargetInfo( + compiler.getDiagnostics(), + std::make_shared( +compiler.getTargetOpts(; + +compiler.createFileManager(); +compiler.createSourceManager(compiler.getFileManager()); +compiler.createPreprocessor(clang::TU_Prefix); +compiler.getPreprocessor().enableIncrementalProcessing(); + +compiler.createASTContext(); + +CodeGenerator* CG = +CreateLLVMCodeGen( +compiler.getDiagnostics(), +"main-module", +compiler.getHeaderSearchOpts(), +
[PATCH] D34059: Get the file name for the symbol from the Module, not the SourceManager.
v.g.vassilev updated this revision to Diff 103566. v.g.vassilev added a comment. Herald added a subscriber: mgorny. Add a test case. https://reviews.llvm.org/D34059 Files: lib/CodeGen/CGDeclCXX.cpp unittests/CodeGen/CMakeLists.txt unittests/CodeGen/IncrementalProcessingTest.cpp Index: unittests/CodeGen/IncrementalProcessingTest.cpp === --- /dev/null +++ unittests/CodeGen/IncrementalProcessingTest.cpp @@ -0,0 +1,174 @@ +//===- unittests/CodeGen/BufferSourceTest.cpp - MemoryBuffer source tests -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===--===// + +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/ModuleBuilder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Parse/Parser.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/Triple.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/MemoryBuffer.h" +#include "gtest/gtest.h" + +#include + +using namespace llvm; +using namespace clang; + +namespace { + +// Incremental processing produces several modules, all using the same "main +// file". Make sure CodeGen can cope with that, e.g. for static initializers. +const char TestProgram1[] = +"extern \"C\" int funcForProg1() { return 17; }\n" +"struct EmitCXXGlobalInitFunc1 {\n" +" EmitCXXGlobalInitFunc1() {}\n" +"} test1;"; + +const char TestProgram2[] = +"extern \"C\" int funcForProg2() { return 42; }\n" +"struct EmitCXXGlobalInitFunc2 {\n" +" EmitCXXGlobalInitFunc2() {}\n" +"} test2;"; + + +/// An incremental version of ParseAST(). +static std::unique_ptr +IncrementalParseAST(CompilerInstance& CI, Parser& P, +CodeGenerator& CG, const char* code) { + static int counter = 0; + struct IncreaseCounterOnRet { +~IncreaseCounterOnRet() { + ++counter; +} + } ICOR; + + Sema& S = CI.getSema(); + clang::SourceManager = S.getSourceManager(); + if (!code) { +// Main file +SM.setMainFileID(SM.createFileID( +llvm::MemoryBuffer::getMemBuffer(""), clang::SrcMgr::C_User)); + +S.getPreprocessor().EnterMainSourceFile(); +P.Initialize(); + } else { +FileID FID = SM.createFileID( +llvm::MemoryBuffer::getMemBuffer(code), clang::SrcMgr::C_User); +SourceLocation MainStartLoc = SM.getLocForStartOfFile(SM.getMainFileID()); +SourceLocation InclLoc = MainStartLoc.getLocWithOffset(counter); +S.getPreprocessor().EnterSourceFile(FID, 0, InclLoc); + } + + ExternalASTSource *External = S.getASTContext().getExternalSource(); + if (External) +External->StartTranslationUnit(); + + Parser::DeclGroupPtrTy ADecl; + for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF; + AtEOF = P.ParseTopLevelDecl(ADecl)) { +// If we got a null return and something *was* parsed, ignore it. This +// is due to a top-level semicolon, an action override, or a parse error +// skipping something. +if (ADecl && !CG.HandleTopLevelDecl(ADecl.get())) + return false; + } + + // Process any TopLevelDecls generated by #pragma weak. + for (Decl *D : S.WeakTopLevelDecls()) +CG.HandleTopLevelDecl(DeclGroupRef(D)); + + CG.HandleTranslationUnit(S.getASTContext()); + + std::unique_ptr M(CG.ReleaseModule()); + // Switch to next module. + CG.StartModule("incremental-module-" + std::to_string(counter), + M->getContext(), CI.getCodeGenOpts()); + return M; +} + +const Function* getGlobalInit(llvm::Module& M) { + for (const auto& Func: M) +if (Func.hasName() && Func.getName().startswith("_GLOBAL__sub_I_")) + return + + return nullptr; +} + +TEST(IncrementalProcessing, EmitCXXGlobalInitFunc) { +LLVMContext Context; +CompilerInstance compiler; + +compiler.createDiagnostics(); +compiler.getLangOpts().CPlusPlus = 1; +compiler.getLangOpts().CPlusPlus11 = 1; + +compiler.getTargetOpts().Triple = llvm::Triple::normalize( +llvm::sys::getProcessTriple()); +compiler.setTarget(clang::TargetInfo::CreateTargetInfo( + compiler.getDiagnostics(), + std::make_shared( +compiler.getTargetOpts(; + +compiler.createFileManager(); +compiler.createSourceManager(compiler.getFileManager()); +compiler.createPreprocessor(clang::TU_Prefix); +compiler.getPreprocessor().enableIncrementalProcessing(); + +compiler.createASTContext(); + +CodeGenerator* CG = +CreateLLVMCodeGen( +compiler.getDiagnostics(), +"main-module", +compiler.getHeaderSearchOpts(), +
[PATCH] D34059: Get the file name for the symbol from the Module, not the SourceManager.
rsmith added a comment. Is there any way to add a test for this? Does it affect the behavior of clang or any in-tree clang-based tools? If this isn't visible through existing in-tree tools, it would be useful to add to unittests/ a rough skeleton of what you're doing, so you can add tests for this kind of thing, and so we don't regress functionality you're depending on. Repository: rL LLVM https://reviews.llvm.org/D34059 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D34059: Get the file name for the symbol from the Module, not the SourceManager.
v.g.vassilev created this revision. This allows multi-module / incremental compilation environments to have unique initializer symbols. Patch by Axel Naumann! Repository: rL LLVM https://reviews.llvm.org/D34059 Files: lib/CodeGen/CGDeclCXX.cpp Index: lib/CodeGen/CGDeclCXX.cpp === --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -449,16 +449,12 @@ PrioritizedCXXGlobalInits.clear(); } - SmallString<128> FileName; - SourceManager = Context.getSourceManager(); - if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { -// Include the filename in the symbol name. Including "sub_" matches gcc and -// makes sure these symbols appear lexicographically behind the symbols with -// priority emitted above. -FileName = llvm::sys::path::filename(MainFile->getName()); - } else { + // Include the filename in the symbol name. Including "sub_" matches gcc and + // makes sure these symbols appear lexicographically behind the symbols with + // priority emitted above. + SmallString<128> FileName = llvm::sys::path::filename(getModule().getName()); + if (FileName.empty()) FileName = ""; - } for (size_t i = 0; i < FileName.size(); ++i) { // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens Index: lib/CodeGen/CGDeclCXX.cpp === --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -449,16 +449,12 @@ PrioritizedCXXGlobalInits.clear(); } - SmallString<128> FileName; - SourceManager = Context.getSourceManager(); - if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { -// Include the filename in the symbol name. Including "sub_" matches gcc and -// makes sure these symbols appear lexicographically behind the symbols with -// priority emitted above. -FileName = llvm::sys::path::filename(MainFile->getName()); - } else { + // Include the filename in the symbol name. Including "sub_" matches gcc and + // makes sure these symbols appear lexicographically behind the symbols with + // priority emitted above. + SmallString<128> FileName = llvm::sys::path::filename(getModule().getName()); + if (FileName.empty()) FileName = ""; - } for (size_t i = 0; i < FileName.size(); ++i) { // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits