diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h index b9f9d14540..5812da1b56 100644 --- a/include/clang/CodeGen/ModuleBuilder.h +++ b/include/clang/CodeGen/ModuleBuilder.h @@ -24,6 +24,7 @@ namespace llvm { namespace clang { class Diagnostic; class LangOptions; + class CompileOptions; class CodeGenerator : public ASTConsumer { public: @@ -32,9 +33,8 @@ namespace clang { }; CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags, - const LangOptions &Features, - const std::string& ModuleName, - bool GenerateDebugInfo); + const std::string &ModuleName, + const CompileOptions &CO); } #endif diff --git a/include/clang/Frontend/CompileOptions.h b/include/clang/Frontend/CompileOptions.h index 86092708c7..1af5e48ea1 100644 --- a/include/clang/Frontend/CompileOptions.h +++ b/include/clang/Frontend/CompileOptions.h @@ -35,6 +35,7 @@ public: unsigned VerifyModule : 1; /// Control whether the module /// should be run through the LLVM Verifier. unsigned TimePasses : 1; /// Set when -ftime-report is enabled. + unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled. /// CPU - An optional CPU to target. std::string CPU; @@ -52,6 +53,7 @@ public: InlineFunctions = SimplifyLibCalls = UnrollLoops = 0; VerifyModule = 1; TimePasses = 0; + NoCommon = 0; } }; diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 92af03ea89..8a880516f6 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// -#include "CGDebugInfo.h" #include "CodeGenModule.h" +#include "CGDebugInfo.h" #include "CodeGenFunction.h" #include "CGCall.h" #include "CGObjCRuntime.h" #include "Mangle.h" +#include "clang/Frontend/CompileOptions.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" @@ -31,10 +32,11 @@ using namespace clang; using namespace CodeGen; -CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, +CodeGenModule::CodeGenModule(ASTContext &C, const CompileOptions &compileOpts, llvm::Module &M, const llvm::TargetData &TD, - Diagnostic &diags, bool GenerateDebugInfo) - : BlockModule(C, M, TD, Types, *this), Context(C), Features(LO), TheModule(M), + Diagnostic &diags) + : BlockModule(C, M, TD, Types, *this), Context(C), + Features(C.getLangOptions()), CompileOpts(compileOpts), TheModule(M), TheTargetData(TD), Diags(diags), Types(C, M, TD), Runtime(0), MemCpyFn(0), MemMoveFn(0), MemSetFn(0), CFConstantStringClassRef(0) { @@ -48,7 +50,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, Runtime = CreateMacObjCRuntime(*this); // If debug info generation is enabled, create the CGDebugInfo object. - DebugInfo = GenerateDebugInfo ? new CGDebugInfo(this) : 0; + DebugInfo = CompileOpts.DebugInfo ? new CGDebugInfo(this) : 0; } CodeGenModule::~CodeGenModule() { @@ -767,7 +769,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { case VarDecl::Register: assert(0 && "Can't have auto or register globals"); case VarDecl::None: - if (!D->getInit()) + if (!D->getInit() && !CompileOpts.NoCommon) GV->setLinkage(llvm::GlobalVariable::CommonLinkage); else GV->setLinkage(llvm::GlobalVariable::ExternalLinkage); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index a32774852d..228020ca79 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -14,15 +14,13 @@ #ifndef CLANG_CODEGEN_CODEGENMODULE_H #define CLANG_CODEGEN_CODEGENMODULE_H -#include "CodeGenTypes.h" #include "clang/AST/Attr.h" +#include "CGBlocks.h" +#include "CGCall.h" +#include "CodeGenTypes.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" - -#include "CGBlocks.h" -#include "CGCall.h" - #include namespace llvm { @@ -52,6 +50,7 @@ namespace clang { class ValueDecl; class VarDecl; class LangOptions; + class CompileOptions; class Diagnostic; class AnnotateAttr; @@ -71,6 +70,7 @@ class CodeGenModule : public BlockModule { ASTContext &Context; const LangOptions &Features; + const CompileOptions &CompileOpts; llvm::Module &TheModule; const llvm::TargetData &TheTargetData; Diagnostic &Diags; @@ -138,9 +138,8 @@ class CodeGenModule : public BlockModule { /// strings. This value has type int * but is actually an Obj-C class pointer. llvm::Constant *CFConstantStringClassRef; public: - CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, - const llvm::TargetData &TD, Diagnostic &Diags, - bool GenerateDebugInfo); + CodeGenModule(ASTContext &C, const CompileOptions &CompileOpts, + llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags); ~CodeGenModule(); diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 3e3f5e463f..6c0b68b5dd 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -13,20 +13,17 @@ #include "clang/CodeGen/ModuleBuilder.h" #include "CodeGenModule.h" +#include "clang/Frontend/CompileOptions.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" -using namespace clang; - -//===----------------------------------------------------------------------===// -// LLVM Emitter - #include "clang/Basic/Diagnostic.h" #include "clang/Basic/TargetInfo.h" #include "llvm/Module.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/Compiler.h" #include "llvm/ADT/OwningPtr.h" +using namespace clang; namespace { @@ -34,17 +31,14 @@ namespace { Diagnostic &Diags; llvm::OwningPtr TD; ASTContext *Ctx; - const LangOptions &Features; - bool GenerateDebugInfo; + const CompileOptions CompileOpts; // Intentionally copied in. protected: llvm::OwningPtr M; llvm::OwningPtr Builder; public: - CodeGeneratorImpl(Diagnostic &diags, const LangOptions &LO, - const std::string& ModuleName, - bool DebugInfoFlag) - : Diags(diags), Features(LO), GenerateDebugInfo(DebugInfoFlag), - M(new llvm::Module(ModuleName)) {} + CodeGeneratorImpl(Diagnostic &diags, const std::string& ModuleName, + const CompileOptions &CO) + : Diags(diags), CompileOpts(CO), M(new llvm::Module(ModuleName)) {} virtual ~CodeGeneratorImpl() {} @@ -62,8 +56,8 @@ namespace { M->setTargetTriple(Ctx->Target.getTargetTriple()); M->setDataLayout(Ctx->Target.getTargetDescription()); TD.reset(new llvm::TargetData(Ctx->Target.getTargetDescription())); - Builder.reset(new CodeGen::CodeGenModule(Context, Features, *M, *TD, - Diags, GenerateDebugInfo)); + Builder.reset(new CodeGen::CodeGenModule(Context, CompileOpts, + *M, *TD, Diags)); } virtual void HandleTopLevelDecl(Decl *D) { @@ -93,8 +87,7 @@ namespace { } CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags, - const LangOptions &Features, const std::string& ModuleName, - bool GenerateDebugInfo) { - return new CodeGeneratorImpl(Diags, Features, ModuleName, GenerateDebugInfo); + const CompileOptions &CO) { + return new CodeGeneratorImpl(Diags, ModuleName, CO); } diff --git a/tools/clang-cc/Backend.cpp b/tools/clang-cc/Backend.cpp index 459bd696b0..c5eeb640b6 100644 --- a/tools/clang-cc/Backend.cpp +++ b/tools/clang-cc/Backend.cpp @@ -85,7 +85,7 @@ namespace { OutputFile(outfile), LLVMIRGeneration("LLVM IR Generation Time"), CodeGenerationTime("Code Generation Time"), - Gen(CreateLLVMCodeGen(Diags, langopts, InputFile, compopts.DebugInfo)), + Gen(CreateLLVMCodeGen(Diags, InputFile, compopts)), TheModule(0), TheTargetData(0), AsmOutStream(0), ModuleProvider(0), CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) { diff --git a/tools/clang-cc/clang.cpp b/tools/clang-cc/clang.cpp index e0a90a3600..8beecd0d0a 100644 --- a/tools/clang-cc/clang.cpp +++ b/tools/clang-cc/clang.cpp @@ -1235,6 +1235,10 @@ GenerateDebugInfo("g", static llvm::cl::opt OptSize("Os", llvm::cl::desc("Optimize for size")); +static llvm::cl::opt +NoCommon("fno-common", + llvm::cl::desc("Compile common globals like normal definitions")); + // It might be nice to add bounds to the CommandLine library directly. struct OptLevelParser : public llvm::cl::parser { bool parse(llvm::cl::Option &O, const char *ArgName, @@ -1281,6 +1285,8 @@ static void InitializeCompileOptions(CompileOptions &Opts, Opts.Features.insert(Opts.Features.end(), TargetFeatures.begin(), TargetFeatures.end()); + Opts.NoCommon = NoCommon | LangOpts.CPlusPlus; + // Handle -ftime-report. Opts.TimePasses = TimeReport; }