diff --git a/clang/include/clang/Frontend/PreprocessorOptions.h b/clang/include/clang/Frontend/PreprocessorOptions.h index fc400faa108b..b918a744a2ab 100644 --- a/clang/include/clang/Frontend/PreprocessorOptions.h +++ b/clang/include/clang/Frontend/PreprocessorOptions.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_ #include "llvm/ADT/StringRef.h" +#include #include #include @@ -71,7 +72,7 @@ public: void addInclude(llvm::StringRef Name) { Includes.push_back(Name); } - void addMacroInclude(const std::string &Name) { + void addMacroInclude(llvm::StringRef Name) { MacroIncludes.push_back(Name); } diff --git a/clang/tools/clang-cc/Options.cpp b/clang/tools/clang-cc/Options.cpp index 4f06ff5a6fbd..8105875d22bf 100644 --- a/clang/tools/clang-cc/Options.cpp +++ b/clang/tools/clang-cc/Options.cpp @@ -13,8 +13,11 @@ #include "Options.h" #include "clang/Frontend/CompileOptions.h" +#include "clang/Frontend/PCHReader.h" +#include "clang/Frontend/PreprocessorOptions.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/CommandLine.h" #include @@ -82,6 +85,41 @@ TargetFeatures("target-feature", llvm::cl::desc("Target specific attributes")); } +//===----------------------------------------------------------------------===// +// General Preprocessor Options +//===----------------------------------------------------------------------===// + +namespace preprocessoroptions { + +static llvm::cl::list +D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix, + llvm::cl::desc("Predefine the specified macro")); + +static llvm::cl::list +ImplicitIncludes("include", llvm::cl::value_desc("file"), + llvm::cl::desc("Include file before parsing")); +static llvm::cl::list +ImplicitMacroIncludes("imacros", llvm::cl::value_desc("file"), + llvm::cl::desc("Include macros from file before parsing")); + +static llvm::cl::opt +ImplicitIncludePCH("include-pch", llvm::cl::value_desc("file"), + llvm::cl::desc("Include precompiled header file")); + +static llvm::cl::opt +ImplicitIncludePTH("include-pth", llvm::cl::value_desc("file"), + llvm::cl::desc("Include file before parsing")); + +static llvm::cl::list +U_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix, + llvm::cl::desc("Undefine the specified macro")); + +static llvm::cl::opt +UndefMacros("undef", llvm::cl::value_desc("macro"), + llvm::cl::desc("undef all system defines")); + +} + //===----------------------------------------------------------------------===// // Option Object Construction //===----------------------------------------------------------------------===// @@ -155,3 +193,52 @@ void clang::InitializeCompileOptions(CompileOptions &Opts, Opts.MergeAllConstants = !NoMergeConstants; } + +void clang::InitializePreprocessorOptions(PreprocessorOptions &Opts) { + using namespace preprocessoroptions; + + Opts.setImplicitPCHInclude(ImplicitIncludePCH); + Opts.setImplicitPTHInclude(ImplicitIncludePTH); + + // Use predefines? + Opts.setUsePredefines(!UndefMacros); + + // Add macros from the command line. + unsigned d = 0, D = D_macros.size(); + unsigned u = 0, U = U_macros.size(); + while (d < D || u < U) { + if (u == U || (d < D && D_macros.getPosition(d) < U_macros.getPosition(u))) + Opts.addMacroDef(D_macros[d++]); + else + Opts.addMacroUndef(U_macros[u++]); + } + + // If -imacros are specified, include them now. These are processed before + // any -include directives. + for (unsigned i = 0, e = ImplicitMacroIncludes.size(); i != e; ++i) + Opts.addMacroInclude(ImplicitMacroIncludes[i]); + + // Add the ordered list of -includes, sorting in the implicit include options + // at the appropriate location. + llvm::SmallVector, 8> OrderedPaths; + std::string OriginalFile; + + if (!ImplicitIncludePTH.empty()) + OrderedPaths.push_back(std::make_pair(ImplicitIncludePTH.getPosition(), + &ImplicitIncludePTH)); + if (!ImplicitIncludePCH.empty()) { + OriginalFile = PCHReader::getOriginalSourceFile(ImplicitIncludePCH); + // FIXME: Don't fail like this. + if (OriginalFile.empty()) + exit(1); + OrderedPaths.push_back(std::make_pair(ImplicitIncludePCH.getPosition(), + &OriginalFile)); + } + for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i) + OrderedPaths.push_back(std::make_pair(ImplicitIncludes.getPosition(i), + &ImplicitIncludes[i])); + llvm::array_pod_sort(OrderedPaths.begin(), OrderedPaths.end()); + + for (unsigned i = 0, e = OrderedPaths.size(); i != e; ++i) + Opts.addInclude(*OrderedPaths[i].second); +} diff --git a/clang/tools/clang-cc/Options.h b/clang/tools/clang-cc/Options.h index 088029f4adb2..ac9e4a58f93b 100644 --- a/clang/tools/clang-cc/Options.h +++ b/clang/tools/clang-cc/Options.h @@ -16,13 +16,18 @@ namespace clang { class CompileOptions; class LangOptions; +class PreprocessorOptions; class TargetInfo; +// FIXME: This can be sunk into InitializeCompileOptions now that that happens +// before language initialization? void ComputeFeatureMap(TargetInfo &Target, llvm::StringMap &Features); void InitializeCompileOptions(CompileOptions &Opts, const llvm::StringMap &Features); +void InitializePreprocessorOptions(PreprocessorOptions &Opts); + } // end namespace clang #endif diff --git a/clang/tools/clang-cc/clang-cc.cpp b/clang/tools/clang-cc/clang-cc.cpp index 8bf02f748f71..cf1fde97c2cc 100644 --- a/clang/tools/clang-cc/clang-cc.cpp +++ b/clang/tools/clang-cc/clang-cc.cpp @@ -53,7 +53,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" @@ -882,32 +881,6 @@ static bool InitializeSourceManager(Preprocessor &PP, // Preprocessor Initialization //===----------------------------------------------------------------------===// -static llvm::cl::opt -UndefMacros("undef", llvm::cl::value_desc("macro"), - llvm::cl::desc("undef all system defines")); - -static llvm::cl::list -D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix, - llvm::cl::desc("Predefine the specified macro")); -static llvm::cl::list -U_macros("U", llvm::cl::value_desc("macro"), llvm::cl::Prefix, - llvm::cl::desc("Undefine the specified macro")); - -static llvm::cl::list -ImplicitIncludes("include", llvm::cl::value_desc("file"), - llvm::cl::desc("Include file before parsing")); -static llvm::cl::list -ImplicitMacroIncludes("imacros", llvm::cl::value_desc("file"), - llvm::cl::desc("Include macros from file before parsing")); - -static llvm::cl::opt -ImplicitIncludePCH("include-pch", llvm::cl::value_desc("file"), - llvm::cl::desc("Include precompiled header file")); - -static llvm::cl::opt -ImplicitIncludePTH("include-pth", llvm::cl::value_desc("file"), - llvm::cl::desc("Include file before parsing")); - static llvm::cl::opt RelocatablePCH("relocatable-pch", llvm::cl::desc("Whether to build a relocatable precompiled " @@ -1087,57 +1060,6 @@ static void InitializeIncludePaths(HeaderSearchOptions &Opts, Opts.UseStandardIncludes = !nostdinc; } -static void InitializePreprocessorOptions(PreprocessorOptions &InitOpts) { - InitOpts.setImplicitPCHInclude(ImplicitIncludePCH); - InitOpts.setImplicitPTHInclude(ImplicitIncludePTH); - - // Use predefines? - InitOpts.setUsePredefines(!UndefMacros); - - // Add macros from the command line. - unsigned d = 0, D = D_macros.size(); - unsigned u = 0, U = U_macros.size(); - while (d < D || u < U) { - if (u == U || (d < D && D_macros.getPosition(d) < U_macros.getPosition(u))) - InitOpts.addMacroDef(D_macros[d++]); - else - InitOpts.addMacroUndef(U_macros[u++]); - } - - // If -imacros are specified, include them now. These are processed before - // any -include directives. - for (unsigned i = 0, e = ImplicitMacroIncludes.size(); i != e; ++i) - InitOpts.addMacroInclude(ImplicitMacroIncludes[i]); - - if (!ImplicitIncludePTH.empty() || !ImplicitIncludes.empty() || - !ImplicitIncludePCH.empty()) { - // We want to add these paths to the predefines buffer in order, make a - // temporary vector to sort by their occurrence. - llvm::SmallVector, 8> OrderedPaths; - std::string OriginalFile; // For use by -implicit-include-pch. - - if (!ImplicitIncludePTH.empty()) - OrderedPaths.push_back(std::make_pair(ImplicitIncludePTH.getPosition(), - &ImplicitIncludePTH)); - if (!ImplicitIncludePCH.empty()) { - OriginalFile = PCHReader::getOriginalSourceFile(ImplicitIncludePCH); - // FIXME: Don't fail like this. - if (OriginalFile.empty()) - exit(1); - OrderedPaths.push_back(std::make_pair(ImplicitIncludePCH.getPosition(), - &OriginalFile)); - } - for (unsigned i = 0, e = ImplicitIncludes.size(); i != e; ++i) - OrderedPaths.push_back(std::make_pair(ImplicitIncludes.getPosition(i), - &ImplicitIncludes[i])); - llvm::array_pod_sort(OrderedPaths.begin(), OrderedPaths.end()); - - // Now that they are ordered by position, add to the predefines buffer. - for (unsigned i = 0, e = OrderedPaths.size(); i != e; ++i) - InitOpts.addInclude(*OrderedPaths[i].second); - } -} - //===----------------------------------------------------------------------===// // Preprocessor construction //===----------------------------------------------------------------------===//