aboutsummaryrefslogtreecommitdiff
path: root/tools/clang-cc/clang-cc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/clang-cc/clang-cc.cpp')
-rw-r--r--tools/clang-cc/clang-cc.cpp263
1 files changed, 60 insertions, 203 deletions
diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp
index f77767c150e9..671fc35d182b 100644
--- a/tools/clang-cc/clang-cc.cpp
+++ b/tools/clang-cc/clang-cc.cpp
@@ -26,6 +26,7 @@
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompileOptions.h"
+#include "clang/Frontend/DiagnosticOptions.h"
#include "clang/Frontend/FixItRewriter.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/InitHeaderSearch.h"
@@ -69,7 +70,6 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Host.h"
#include "llvm/System/Path.h"
-#include "llvm/System/Process.h"
#include "llvm/System/Program.h"
#include "llvm/System/Signals.h"
#include "llvm/Target/TargetSelect.h"
@@ -106,8 +106,6 @@ static bool ResolveParsedLocation(ParsedSourceLocation &ParsedLoc,
/// anything.
llvm::Timer *ClangFrontendTimer = 0;
-static bool HadErrors = false;
-
static llvm::cl::opt<bool>
Verbose("v", llvm::cl::desc("Enable verbose output"));
static llvm::cl::opt<bool>
@@ -240,6 +238,8 @@ TokenCache("token-cache", llvm::cl::value_desc("path"),
// Diagnostic Options
//===----------------------------------------------------------------------===//
+static DiagnosticOptions DiagOpts;
+
static llvm::cl::opt<bool>
VerifyDiagnostics("verify",
llvm::cl::desc("Verify emitted diagnostics and warnings"));
@@ -283,10 +283,9 @@ MessageLength("fmessage-length",
llvm::cl::value_desc("N"));
static llvm::cl::opt<bool>
-NoColorDiagnostic("fno-color-diagnostics",
- llvm::cl::desc("Don't use colors when showing diagnostics "
- "(automatically turned off if output is not a "
- "terminal)."));
+PrintColorDiagnostic("fcolor-diagnostics",
+ llvm::cl::desc("Use colors in diagnostics"));
+
//===----------------------------------------------------------------------===//
// C++ Visualization.
//===----------------------------------------------------------------------===//
@@ -655,10 +654,18 @@ static llvm::cl::opt<bool>
NoElideConstructors("fno-elide-constructors",
llvm::cl::desc("Disable C++ copy constructor elision"));
+static llvm::cl::opt<bool>
+NoMergeConstants("fno-merge-all-constants",
+ llvm::cl::desc("Disallow merging of constants."));
+
static llvm::cl::opt<std::string>
TargetABI("target-abi",
llvm::cl::desc("Target a particular ABI type"));
+static llvm::cl::opt<std::string>
+TargetTriple("triple",
+ llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)"));
+
// It might be nice to add bounds to the CommandLine library directly.
struct OptLevelParser : public llvm::cl::parser<unsigned> {
@@ -878,132 +885,6 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
}
//===----------------------------------------------------------------------===//
-// Target Triple Processing.
-//===----------------------------------------------------------------------===//
-
-static llvm::cl::opt<std::string>
-TargetTriple("triple",
- llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)"));
-
-static llvm::cl::opt<std::string>
-MacOSVersionMin("mmacosx-version-min",
- llvm::cl::desc("Specify target Mac OS X version (e.g. 10.5)"));
-
-// If -mmacosx-version-min=10.3.9 is specified, change the triple from being
-// something like powerpc-apple-darwin9 to powerpc-apple-darwin7
-
-// FIXME: We should have the driver do this instead.
-static void HandleMacOSVersionMin(llvm::Triple &Triple) {
- if (Triple.getOS() != llvm::Triple::Darwin) {
- fprintf(stderr,
- "-mmacosx-version-min only valid for darwin (Mac OS X) targets\n");
- exit(1);
- }
-
- // Validate that MacOSVersionMin is a 'version number', starting with 10.[3-9]
- if (MacOSVersionMin.size() < 4 ||
- MacOSVersionMin.substr(0, 3) != "10." ||
- !isdigit(MacOSVersionMin[3])) {
- fprintf(stderr,
- "-mmacosx-version-min=%s is invalid, expected something like '10.4'.\n",
- MacOSVersionMin.c_str());
- exit(1);
- }
-
- unsigned VersionNum = MacOSVersionMin[3]-'0';
-
- if (VersionNum <= 4 && Triple.getArch() == llvm::Triple::x86_64) {
- fprintf(stderr,
- "-mmacosx-version-min=%s is invalid with -arch x86_64.\n",
- MacOSVersionMin.c_str());
- exit(1);
- }
-
-
- llvm::SmallString<16> NewDarwinString;
- NewDarwinString += "darwin";
-
- // Turn MacOSVersionMin into a darwin number: e.g. 10.3.9 is 3 -> darwin7.
- VersionNum += 4;
- if (VersionNum > 9) {
- NewDarwinString += '1';
- VersionNum -= 10;
- }
- NewDarwinString += (VersionNum+'0');
-
- if (MacOSVersionMin.size() == 4) {
- // "10.4" is ok.
- } else if (MacOSVersionMin.size() == 6 &&
- MacOSVersionMin[4] == '.' &&
- isdigit(MacOSVersionMin[5])) { // 10.4.7 is ok.
- // Add the period piece (.7) to the end of the triple. This gives us
- // something like ...-darwin8.7
- NewDarwinString += '.';
- NewDarwinString += MacOSVersionMin[5];
- } else { // "10.4" is ok. 10.4x is not.
- fprintf(stderr,
- "-mmacosx-version-min=%s is invalid, expected something like '10.4'.\n",
- MacOSVersionMin.c_str());
- exit(1);
- }
-
- Triple.setOSName(NewDarwinString.str());
-}
-
-static llvm::cl::opt<std::string>
-IPhoneOSVersionMin("miphoneos-version-min",
- llvm::cl::desc("Specify target iPhone OS version (e.g. 2.0)"));
-
-// If -miphoneos-version-min=2.2 is specified, change the triple from being
-// something like armv6-apple-darwin10 to armv6-apple-darwin9.2.2. We use
-// 9 as the default major Darwin number, and encode the iPhone OS version
-// number in the minor version and revision.
-
-// FIXME: We should have the driver do this instead.
-static void HandleIPhoneOSVersionMin(llvm::Triple &Triple) {
- if (Triple.getOS() != llvm::Triple::Darwin) {
- fprintf(stderr,
- "-miphoneos-version-min only valid for darwin (Mac OS X) targets\n");
- exit(1);
- }
-
- // Validate that IPhoneOSVersionMin is a 'version number', starting with
- // [2-9].[0-9]
- if (IPhoneOSVersionMin.size() != 3 || !isdigit(IPhoneOSVersionMin[0]) ||
- IPhoneOSVersionMin[1] != '.' || !isdigit(IPhoneOSVersionMin[2])) {
- fprintf(stderr,
- "-miphoneos-version-min=%s is invalid, expected something like '2.0'.\n",
- IPhoneOSVersionMin.c_str());
- exit(1);
- }
-
- // Turn IPhoneOSVersionMin into a darwin number: e.g. 2.0 is 2 -> 9.2.0
- llvm::SmallString<16> NewDarwinString;
- NewDarwinString += "darwin9.";
- NewDarwinString += IPhoneOSVersionMin;
- Triple.setOSName(NewDarwinString.str());
-}
-
-/// CreateTargetTriple - Process the various options that affect the target
-/// triple and build a final aggregate triple that we are compiling for.
-static llvm::Triple CreateTargetTriple() {
- // Initialize base triple. If a -triple option has been specified, use
- // that triple. Otherwise, default to the host triple.
- llvm::Triple Triple(TargetTriple);
- if (Triple.getTriple().empty())
- Triple = llvm::Triple(llvm::sys::getHostTriple());
-
- // If -mmacosx-version-min=10.3.9 is specified, change the triple from being
- // something like powerpc-apple-darwin9 to powerpc-apple-darwin7
- if (!MacOSVersionMin.empty())
- HandleMacOSVersionMin(Triple);
- else if (!IPhoneOSVersionMin.empty())
- HandleIPhoneOSVersionMin(Triple);
-
- return Triple;
-}
-
-//===----------------------------------------------------------------------===//
// SourceManager initialization.
//===----------------------------------------------------------------------===//
@@ -1056,6 +937,9 @@ static bool InitializeSourceManager(Preprocessor &PP,
// -A... - Play with #assertions
// -undef - Undefine all predefined macros
+static llvm::cl::opt<bool>
+undef_macros("undef", llvm::cl::value_desc("macro"), llvm::cl::desc("undef all system defines"));
+
static llvm::cl::list<std::string>
D_macros("D", llvm::cl::value_desc("macro"), llvm::cl::Prefix,
llvm::cl::desc("Predefine the specified macro"));
@@ -1099,8 +983,8 @@ static llvm::cl::opt<bool>
nostdinc("nostdinc", llvm::cl::desc("Disable standard #include directories"));
static llvm::cl::opt<bool>
-nostdclanginc("nostdclanginc",
- llvm::cl::desc("Disable standard clang #include directories"));
+nobuiltininc("nobuiltininc",
+ llvm::cl::desc("Disable builtin #include directories"));
// Various command line options. These four add directories to each chain.
static llvm::cl::list<std::string>
@@ -1240,7 +1124,7 @@ void InitializeIncludePaths(const char *Argv0, HeaderSearch &Headers,
Init.AddDefaultEnvVarPaths(Lang);
- if (!nostdclanginc)
+ if (!nobuiltininc)
AddClangIncludePaths(Argv0, &Init);
if (!nostdinc)
@@ -1367,7 +1251,7 @@ public:
PreprocessorInitOptions InitOpts;
InitializePreprocessorInitOptions(InitOpts);
- if (InitializePreprocessor(*PP, InitOpts))
+ if (InitializePreprocessor(*PP, InitOpts, undef_macros))
return 0;
return PP.take();
@@ -1493,6 +1377,8 @@ static void InitializeCompileOptions(CompileOptions &Opts,
Opts.DisableRedZone = DisableRedZone;
Opts.NoImplicitFloat = NoImplicitFloat;
+
+ Opts.MergeAllConstants = !NoMergeConstants;
}
//===----------------------------------------------------------------------===//
@@ -1681,14 +1567,7 @@ public:
// Output diags both where requested...
Chain1.reset(Normal);
// .. and to our log file.
- Chain2.reset(new TextDiagnosticPrinter(*BuildLogFile,
- !NoShowColumn,
- !NoCaretDiagnostics,
- !NoShowLocation,
- PrintSourceRangeInfo,
- PrintDiagnosticOption,
- !NoDiagnosticsFixIt,
- MessageLength));
+ Chain2.reset(new TextDiagnosticPrinter(*BuildLogFile, DiagOpts));
}
virtual void setLangOptions(const LangOptions *LO) {
@@ -1862,8 +1741,8 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
Features, Context));
if (!Consumer.get()) {
- fprintf(stderr, "Unexpected program action!\n");
- HadErrors = true;
+ PP.getDiagnostics().Report(FullSourceLoc(),
+ diag::err_fe_invalid_ast_action);
return;
}
@@ -2082,25 +1961,25 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
if (InitializeSourceManager(PP, InFile))
return;
}
-
+
// If we have an ASTConsumer, run the parser with it.
if (Consumer) {
CodeCompleteConsumer *(*CreateCodeCompleter)(Sema &, void *) = 0;
void *CreateCodeCompleterData = 0;
-
+
if (!CodeCompletionAt.FileName.empty()) {
// Tell the source manager to chop off the given file at a specific
// line and column.
- if (const FileEntry *Entry
+ if (const FileEntry *Entry
= PP.getFileManager().getFile(CodeCompletionAt.FileName)) {
// Truncate the named file at the given line/column.
PP.getSourceManager().truncateFileAt(Entry, CodeCompletionAt.Line,
CodeCompletionAt.Column);
-
+
// Set up the creation routine for code-completion.
CreateCodeCompleter = BuildPrintingCodeCompleter;
} else {
- PP.getDiagnostics().Report(FullSourceLoc(),
+ PP.getDiagnostics().Report(FullSourceLoc(),
diag::err_fe_invalid_code_complete_file)
<< CodeCompletionAt.FileName;
}
@@ -2174,11 +2053,9 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
// handles. Also, we don't want to try to erase an open file.
OS.reset();
- if ((HadErrors || (PP.getDiagnostics().getNumErrors() != 0)) &&
- !OutPath.isEmpty()) {
- // If we had errors, try to erase the output file.
+ // If we had errors, try to erase the output file.
+ if (PP.getDiagnostics().getNumErrors() && !OutPath.isEmpty())
OutPath.eraseFromDisk();
- }
}
/// ProcessInputFile - Process a single AST input file with the specified state.
@@ -2233,11 +2110,9 @@ static void ProcessASTInputFile(const std::string &InFile, ProgActions PA,
// handles. Also, we don't want to try to erase an open file.
OS.reset();
- if ((HadErrors || (PP.getDiagnostics().getNumErrors() != 0)) &&
- !OutPath.isEmpty()) {
- // If we had errors, try to erase the output file.
+ // If we had errors, try to erase the output file.
+ if (PP.getDiagnostics().getNumErrors() && !OutPath.isEmpty())
OutPath.eraseFromDisk();
- }
}
static llvm::cl::list<std::string>
@@ -2276,6 +2151,16 @@ int main(int argc, char **argv) {
if (InputFilenames.empty())
InputFilenames.push_back("-");
+ // Initialize the diagnostic options.
+ DiagOpts.ShowColumn = !NoShowColumn;
+ DiagOpts.ShowLocation = !NoShowLocation;
+ DiagOpts.ShowCarets = !NoCaretDiagnostics;
+ DiagOpts.ShowFixits = !NoDiagnosticsFixIt;
+ DiagOpts.ShowSourceRanges = PrintSourceRangeInfo;
+ DiagOpts.ShowOptionNames = PrintDiagnosticOption;
+ DiagOpts.ShowColors = PrintColorDiagnostic;
+ DiagOpts.MessageLength = MessageLength;
+
// Create the diagnostic client for reporting errors or for
// implementing -verify.
llvm::OwningPtr<DiagnosticClient> DiagClient;
@@ -2292,26 +2177,7 @@ int main(int argc, char **argv) {
}
} else if (HTMLDiag.empty()) {
// Print diagnostics to stderr by default.
-
- // If -fmessage-length=N was not specified, determine whether this
- // is a terminal and, if so, implicitly define -fmessage-length
- // appropriately.
- if (MessageLength.getNumOccurrences() == 0)
- MessageLength.setValue(llvm::sys::Process::StandardErrColumns());
-
- if (!NoColorDiagnostic) {
- NoColorDiagnostic.setValue(!llvm::sys::Process::StandardErrHasColors());
- }
-
- DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(),
- !NoShowColumn,
- !NoCaretDiagnostics,
- !NoShowLocation,
- PrintSourceRangeInfo,
- PrintDiagnosticOption,
- !NoDiagnosticsFixIt,
- MessageLength,
- !NoColorDiagnostic));
+ DiagClient.reset(new TextDiagnosticPrinter(llvm::errs(), DiagOpts));
} else {
DiagClient.reset(CreateHTMLDiagnosticClient(HTMLDiag));
}
@@ -2338,18 +2204,14 @@ int main(int argc, char **argv) {
llvm::llvm_install_error_handler(LLVMErrorHandler,
static_cast<void*>(&Diags));
- // -I- is a deprecated GCC feature, scan for it and reject it.
- for (unsigned i = 0, e = I_dirs.size(); i != e; ++i) {
- if (I_dirs[i] == "-") {
- Diags.Report(FullSourceLoc(), diag::err_pp_I_dash_not_supported);
- I_dirs.erase(I_dirs.begin()+i);
- --i;
- }
- }
+ // Initialize base triple. If a -triple option has been specified, use
+ // that triple. Otherwise, default to the host triple.
+ llvm::Triple Triple(TargetTriple);
+ if (Triple.getTriple().empty())
+ Triple = llvm::Triple(llvm::sys::getHostTriple());
// Get information about the target being compiled for.
- llvm::Triple Triple = CreateTargetTriple();
- llvm::OwningPtr<TargetInfo>
+ llvm::OwningPtr<TargetInfo>
Target(TargetInfo::CreateTargetInfo(Triple.getTriple()));
if (Target == 0) {
@@ -2390,8 +2252,8 @@ int main(int argc, char **argv) {
continue;
}
- /// Create a SourceManager object. This tracks and owns all the file
- /// buffers allocated to a translation unit.
+ // Create a SourceManager object. This tracks and owns all the file
+ // buffers allocated to a translation unit.
if (!SourceMgr)
SourceMgr.reset(new SourceManager());
else
@@ -2415,26 +2277,21 @@ int main(int argc, char **argv) {
*SourceMgr.get(), HeaderInfo);
llvm::OwningPtr<Preprocessor> PP(PPFactory.CreatePreprocessor());
-
if (!PP)
continue;
- // Handle generating dependencies, if requested
+ // Handle generating dependencies, if requested.
if (!DependencyFile.empty()) {
- llvm::raw_ostream *DependencyOS;
if (DependencyTargets.empty()) {
- // FIXME: Use a proper diagnostic
- llvm::errs() << "-dependency-file requires at least one -MT option\n";
- HadErrors = true;
+ Diags.Report(FullSourceLoc(), diag::err_fe_dependency_file_requires_MT);
continue;
}
std::string ErrStr;
- DependencyOS =
+ llvm::raw_ostream *DependencyOS =
new llvm::raw_fd_ostream(DependencyFile.c_str(), ErrStr);
if (!ErrStr.empty()) {
- // FIXME: Use a proper diagnostic
- llvm::errs() << "unable to open dependency file: " + ErrStr;
- HadErrors = true;
+ Diags.Report(FullSourceLoc(), diag::err_fe_error_opening)
+ << DependencyFile << ErrStr;
continue;
}
@@ -2483,5 +2340,5 @@ int main(int argc, char **argv) {
// -time-passes usable.
llvm::llvm_shutdown();
- return HadErrors || (Diags.getNumErrors() != 0);
+ return (Diags.getNumErrors() != 0);
}