forked from OSchip/llvm-project
Serialize TargetOptions into an AST file, and make sure that we keep
target options around so they can be accessed at any point (rather than keeping them transient). llvm-svn: 166072
This commit is contained in:
parent
1ee6352788
commit
cb177f15e7
|
@ -25,9 +25,13 @@ def err_fe_pch_file_modified : Error<
|
||||||
def err_fe_pch_file_overridden : Error<
|
def err_fe_pch_file_overridden : Error<
|
||||||
"file '%0' from the precompiled header has been overridden">;
|
"file '%0' from the precompiled header has been overridden">;
|
||||||
|
|
||||||
def warn_pch_target_triple : Error<
|
def err_pch_targetopt_mismatch : Error<
|
||||||
"PCH file was compiled for the target '%0' but the current translation "
|
"PCH file was compiled for the %0 '%1' but the current translation "
|
||||||
"unit is being compiled for target '%1'">;
|
"unit is being compiled for target '%2'">;
|
||||||
|
def err_pch_targetopt_feature_mismatch : Error<
|
||||||
|
"%select{AST file|current translation unit}0 was compiled with the target "
|
||||||
|
"feature'%1' but the %select{current translation unit is|AST file was}0 "
|
||||||
|
"not">;
|
||||||
def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
|
def err_pch_langopt_mismatch : Error<"%0 was %select{disabled|enabled}1 in "
|
||||||
"PCH file but is currently %select{disabled|enabled}2">;
|
"PCH file but is currently %select{disabled|enabled}2">;
|
||||||
def err_pch_langopt_value_mismatch : Error<
|
def err_pch_langopt_value_mismatch : Error<
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
#include "clang/Basic/AddressSpaces.h"
|
#include "clang/Basic/AddressSpaces.h"
|
||||||
|
#include "clang/Basic/TargetOptions.h"
|
||||||
#include "clang/Basic/VersionTuple.h"
|
#include "clang/Basic/VersionTuple.h"
|
||||||
#include "clang/Basic/Specifiers.h"
|
#include "clang/Basic/Specifiers.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -39,7 +40,6 @@ class LangOptions;
|
||||||
class MacroBuilder;
|
class MacroBuilder;
|
||||||
class SourceLocation;
|
class SourceLocation;
|
||||||
class SourceManager;
|
class SourceManager;
|
||||||
class TargetOptions;
|
|
||||||
|
|
||||||
namespace Builtin { struct Info; }
|
namespace Builtin { struct Info; }
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ enum TargetCXXABI {
|
||||||
/// \brief Exposes information about the current target.
|
/// \brief Exposes information about the current target.
|
||||||
///
|
///
|
||||||
class TargetInfo : public RefCountedBase<TargetInfo> {
|
class TargetInfo : public RefCountedBase<TargetInfo> {
|
||||||
TargetOptions *TargetOpts;
|
llvm::IntrusiveRefCntPtr<TargetOptions> TargetOpts;
|
||||||
llvm::Triple Triple;
|
llvm::Triple Triple;
|
||||||
protected:
|
protected:
|
||||||
// Target values set by the ctor of the actual target implementation. Default
|
// Target values set by the ctor of the actual target implementation. Default
|
||||||
|
|
|
@ -15,13 +15,14 @@
|
||||||
#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
|
#ifndef LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
|
||||||
#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
|
#define LLVM_CLANG_FRONTEND_TARGETOPTIONS_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/IntrusiveRefCntPtr.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
|
|
||||||
/// \brief Options for controlling the target.
|
/// \brief Options for controlling the target.
|
||||||
class TargetOptions {
|
class TargetOptions : public RefCountedBase<TargetOptions> {
|
||||||
public:
|
public:
|
||||||
/// If given, the name of the target triple to compile for. If not given the
|
/// If given, the name of the target triple to compile for. If not given the
|
||||||
/// target will be selected to match the host.
|
/// target will be selected to match the host.
|
||||||
|
@ -40,6 +41,9 @@ public:
|
||||||
/// If given, the version string of the linker in use.
|
/// If given, the version string of the linker in use.
|
||||||
std::string LinkerVersion;
|
std::string LinkerVersion;
|
||||||
|
|
||||||
|
/// \brief The list of target specific features to enable or disable, as written on the command line.
|
||||||
|
std::vector<std::string> FeaturesAsWritten;
|
||||||
|
|
||||||
/// The list of target specific features to enable or disable -- this should
|
/// The list of target specific features to enable or disable -- this should
|
||||||
/// be a list of strings starting with by '+' or '-'.
|
/// be a list of strings starting with by '+' or '-'.
|
||||||
std::vector<std::string> Features;
|
std::vector<std::string> Features;
|
||||||
|
|
|
@ -71,8 +71,8 @@ private:
|
||||||
IntrusiveRefCntPtr<TargetInfo> Target;
|
IntrusiveRefCntPtr<TargetInfo> Target;
|
||||||
IntrusiveRefCntPtr<Preprocessor> PP;
|
IntrusiveRefCntPtr<Preprocessor> PP;
|
||||||
IntrusiveRefCntPtr<ASTContext> Ctx;
|
IntrusiveRefCntPtr<ASTContext> Ctx;
|
||||||
|
IntrusiveRefCntPtr<TargetOptions> TargetOpts;
|
||||||
ASTReader *Reader;
|
ASTReader *Reader;
|
||||||
TargetOptions TargetOpts;
|
|
||||||
|
|
||||||
struct ASTWriterData;
|
struct ASTWriterData;
|
||||||
OwningPtr<ASTWriterData> WriterData;
|
OwningPtr<ASTWriterData> WriterData;
|
||||||
|
@ -91,13 +91,6 @@ private:
|
||||||
/// LoadFromCommandLine available.
|
/// LoadFromCommandLine available.
|
||||||
IntrusiveRefCntPtr<CompilerInvocation> Invocation;
|
IntrusiveRefCntPtr<CompilerInvocation> Invocation;
|
||||||
|
|
||||||
/// \brief The set of target features.
|
|
||||||
///
|
|
||||||
/// FIXME: each time we reparse, we need to restore the set of target
|
|
||||||
/// features from this vector, because TargetInfo::CreateTargetInfo()
|
|
||||||
/// mangles the target options in place. Yuck!
|
|
||||||
std::vector<std::string> TargetFeatures;
|
|
||||||
|
|
||||||
// OnlyLocalDecls - when true, walking this AST should only visit declarations
|
// OnlyLocalDecls - when true, walking this AST should only visit declarations
|
||||||
// that come from the AST itself, not from included precompiled headers.
|
// that come from the AST itself, not from included precompiled headers.
|
||||||
// FIXME: This is temporary; eventually, CIndex will always do this.
|
// FIXME: This is temporary; eventually, CIndex will always do this.
|
||||||
|
|
|
@ -52,6 +52,9 @@ class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> {
|
||||||
protected:
|
protected:
|
||||||
/// Options controlling the language variant.
|
/// Options controlling the language variant.
|
||||||
IntrusiveRefCntPtr<LangOptions> LangOpts;
|
IntrusiveRefCntPtr<LangOptions> LangOpts;
|
||||||
|
|
||||||
|
/// Options controlling the target.
|
||||||
|
IntrusiveRefCntPtr<TargetOptions> TargetOpts;
|
||||||
public:
|
public:
|
||||||
CompilerInvocationBase();
|
CompilerInvocationBase();
|
||||||
|
|
||||||
|
@ -59,6 +62,11 @@ public:
|
||||||
|
|
||||||
LangOptions *getLangOpts() { return LangOpts.getPtr(); }
|
LangOptions *getLangOpts() { return LangOpts.getPtr(); }
|
||||||
const LangOptions *getLangOpts() const { return LangOpts.getPtr(); }
|
const LangOptions *getLangOpts() const { return LangOpts.getPtr(); }
|
||||||
|
|
||||||
|
TargetOptions &getTargetOpts() { return *TargetOpts.getPtr(); }
|
||||||
|
const TargetOptions &getTargetOpts() const {
|
||||||
|
return *TargetOpts.getPtr();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Helper class for holding the data necessary to invoke the compiler.
|
/// \brief Helper class for holding the data necessary to invoke the compiler.
|
||||||
|
@ -96,9 +104,6 @@ class CompilerInvocation : public CompilerInvocationBase {
|
||||||
/// Options controlling preprocessed output.
|
/// Options controlling preprocessed output.
|
||||||
PreprocessorOutputOptions PreprocessorOutputOpts;
|
PreprocessorOutputOptions PreprocessorOutputOpts;
|
||||||
|
|
||||||
/// Options controlling the target.
|
|
||||||
TargetOptions TargetOpts;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {}
|
CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {}
|
||||||
|
|
||||||
|
@ -199,11 +204,6 @@ public:
|
||||||
return PreprocessorOutputOpts;
|
return PreprocessorOutputOpts;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetOptions &getTargetOpts() { return TargetOpts; }
|
|
||||||
const TargetOptions &getTargetOpts() const {
|
|
||||||
return TargetOpts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,7 @@ class ASTStmtReader;
|
||||||
class TypeLocReader;
|
class TypeLocReader;
|
||||||
struct HeaderFileInfo;
|
struct HeaderFileInfo;
|
||||||
class VersionTuple;
|
class VersionTuple;
|
||||||
|
class TargetOptions;
|
||||||
|
|
||||||
struct PCHPredefinesBlock {
|
struct PCHPredefinesBlock {
|
||||||
/// \brief The file ID for this predefines buffer in a PCH file.
|
/// \brief The file ID for this predefines buffer in a PCH file.
|
||||||
|
@ -110,11 +111,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Receives the target triple.
|
/// \brief Receives the target options.
|
||||||
///
|
///
|
||||||
/// \returns true to indicate the target triple is invalid or false otherwise.
|
/// \returns true to indicate the target options are invalid, or false
|
||||||
virtual bool ReadTargetTriple(const serialization::ModuleFile &M,
|
/// otherwise.
|
||||||
StringRef Triple) {
|
virtual bool ReadTargetOptions(const serialization::ModuleFile &M,
|
||||||
|
const TargetOptions &TargetOpts) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +160,8 @@ public:
|
||||||
|
|
||||||
virtual bool ReadLanguageOptions(const serialization::ModuleFile &M,
|
virtual bool ReadLanguageOptions(const serialization::ModuleFile &M,
|
||||||
const LangOptions &LangOpts);
|
const LangOptions &LangOpts);
|
||||||
virtual bool ReadTargetTriple(const serialization::ModuleFile &M,
|
virtual bool ReadTargetOptions(const serialization::ModuleFile &M,
|
||||||
StringRef Triple);
|
const TargetOptions &TargetOpts);
|
||||||
virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
|
virtual bool ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
|
||||||
StringRef OriginalFileName,
|
StringRef OriginalFileName,
|
||||||
std::string &SuggestedPredefines,
|
std::string &SuggestedPredefines,
|
||||||
|
|
|
@ -4635,8 +4635,10 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
|
||||||
|
|
||||||
// Apply the user specified deltas.
|
// Apply the user specified deltas.
|
||||||
// First the enables.
|
// First the enables.
|
||||||
for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
|
for (std::vector<std::string>::const_iterator
|
||||||
ie = Opts.Features.end(); it != ie; ++it) {
|
it = Opts.FeaturesAsWritten.begin(),
|
||||||
|
ie = Opts.FeaturesAsWritten.end();
|
||||||
|
it != ie; ++it) {
|
||||||
const char *Name = it->c_str();
|
const char *Name = it->c_str();
|
||||||
|
|
||||||
if (Name[0] != '+')
|
if (Name[0] != '+')
|
||||||
|
@ -4650,8 +4652,10 @@ TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then the disables.
|
// Then the disables.
|
||||||
for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
|
for (std::vector<std::string>::const_iterator
|
||||||
ie = Opts.Features.end(); it != ie; ++it) {
|
it = Opts.FeaturesAsWritten.begin(),
|
||||||
|
ie = Opts.FeaturesAsWritten.end();
|
||||||
|
it != ie; ++it) {
|
||||||
const char *Name = it->c_str();
|
const char *Name = it->c_str();
|
||||||
|
|
||||||
if (Name[0] == '+')
|
if (Name[0] == '+')
|
||||||
|
|
|
@ -503,7 +503,7 @@ class ASTInfoCollector : public ASTReaderListener {
|
||||||
ASTContext &Context;
|
ASTContext &Context;
|
||||||
LangOptions &LangOpt;
|
LangOptions &LangOpt;
|
||||||
HeaderSearch &HSI;
|
HeaderSearch &HSI;
|
||||||
TargetOptions &TargetOpts;
|
IntrusiveRefCntPtr<TargetOptions> &TargetOpts;
|
||||||
IntrusiveRefCntPtr<TargetInfo> &Target;
|
IntrusiveRefCntPtr<TargetInfo> &Target;
|
||||||
std::string &Predefines;
|
std::string &Predefines;
|
||||||
unsigned &Counter;
|
unsigned &Counter;
|
||||||
|
@ -513,7 +513,8 @@ class ASTInfoCollector : public ASTReaderListener {
|
||||||
bool InitializedLanguage;
|
bool InitializedLanguage;
|
||||||
public:
|
public:
|
||||||
ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt,
|
ASTInfoCollector(Preprocessor &PP, ASTContext &Context, LangOptions &LangOpt,
|
||||||
HeaderSearch &HSI, TargetOptions &TargetOpts,
|
HeaderSearch &HSI,
|
||||||
|
IntrusiveRefCntPtr<TargetOptions> &TargetOpts,
|
||||||
IntrusiveRefCntPtr<TargetInfo> &Target,
|
IntrusiveRefCntPtr<TargetInfo> &Target,
|
||||||
std::string &Predefines,
|
std::string &Predefines,
|
||||||
unsigned &Counter)
|
unsigned &Counter)
|
||||||
|
@ -536,21 +537,18 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool ReadTargetTriple(const serialization::ModuleFile &M,
|
virtual bool ReadTargetOptions(const serialization::ModuleFile &M,
|
||||||
StringRef Triple) {
|
const TargetOptions &TargetOpts) {
|
||||||
// If we've already initialized the target, don't do it again.
|
// If we've already initialized the target, don't do it again.
|
||||||
if (Target)
|
if (Target)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(M.Kind == serialization::MK_MainFile);
|
assert(M.Kind == serialization::MK_MainFile);
|
||||||
|
|
||||||
// FIXME: This is broken, we should store the TargetOptions in the AST file.
|
|
||||||
TargetOpts.ABI = "";
|
this->TargetOpts = new TargetOptions(TargetOpts);
|
||||||
TargetOpts.CXXABI = "";
|
Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(),
|
||||||
TargetOpts.CPU = "";
|
*this->TargetOpts);
|
||||||
TargetOpts.Features.clear();
|
|
||||||
TargetOpts.Triple = Triple;
|
|
||||||
Target = TargetInfo::CreateTargetInfo(PP.getDiagnostics(), TargetOpts);
|
|
||||||
|
|
||||||
updated();
|
updated();
|
||||||
return false;
|
return false;
|
||||||
|
@ -1098,7 +1096,6 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
|
||||||
Clang->setDiagnostics(&getDiagnostics());
|
Clang->setDiagnostics(&getDiagnostics());
|
||||||
|
|
||||||
// Create the target instance.
|
// Create the target instance.
|
||||||
Clang->getTargetOpts().Features = TargetFeatures;
|
|
||||||
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
||||||
Clang->getTargetOpts()));
|
Clang->getTargetOpts()));
|
||||||
if (!Clang->hasTarget()) {
|
if (!Clang->hasTarget()) {
|
||||||
|
@ -1568,9 +1565,8 @@ llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
|
||||||
Clang->setDiagnostics(&getDiagnostics());
|
Clang->setDiagnostics(&getDiagnostics());
|
||||||
|
|
||||||
// Create the target instance.
|
// Create the target instance.
|
||||||
Clang->getTargetOpts().Features = TargetFeatures;
|
|
||||||
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
||||||
Clang->getTargetOpts()));
|
Clang->getTargetOpts()));
|
||||||
if (!Clang->hasTarget()) {
|
if (!Clang->hasTarget()) {
|
||||||
llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
|
llvm::sys::Path(FrontendOpts.OutputFile).eraseFromDisk();
|
||||||
Preamble.clear();
|
Preamble.clear();
|
||||||
|
@ -1777,9 +1773,6 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
|
||||||
CI->getFrontendOpts().DisableFree = false;
|
CI->getFrontendOpts().DisableFree = false;
|
||||||
ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
|
ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
|
||||||
|
|
||||||
// Save the target features.
|
|
||||||
AST->TargetFeatures = CI->getTargetOpts().Features;
|
|
||||||
|
|
||||||
// Create the compiler instance to use for building the AST.
|
// Create the compiler instance to use for building the AST.
|
||||||
OwningPtr<CompilerInstance> Clang(new CompilerInstance());
|
OwningPtr<CompilerInstance> Clang(new CompilerInstance());
|
||||||
|
|
||||||
|
@ -1795,7 +1788,6 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(CompilerInvocation *CI,
|
||||||
Clang->setDiagnostics(&AST->getDiagnostics());
|
Clang->setDiagnostics(&AST->getDiagnostics());
|
||||||
|
|
||||||
// Create the target instance.
|
// Create the target instance.
|
||||||
Clang->getTargetOpts().Features = AST->TargetFeatures;
|
|
||||||
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
||||||
Clang->getTargetOpts()));
|
Clang->getTargetOpts()));
|
||||||
if (!Clang->hasTarget())
|
if (!Clang->hasTarget())
|
||||||
|
@ -1884,9 +1876,6 @@ bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {
|
||||||
Invocation->getFrontendOpts().DisableFree = false;
|
Invocation->getFrontendOpts().DisableFree = false;
|
||||||
ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
|
ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
|
||||||
|
|
||||||
// Save the target features.
|
|
||||||
TargetFeatures = Invocation->getTargetOpts().Features;
|
|
||||||
|
|
||||||
llvm::MemoryBuffer *OverrideMainBuffer = 0;
|
llvm::MemoryBuffer *OverrideMainBuffer = 0;
|
||||||
if (PrecompilePreamble) {
|
if (PrecompilePreamble) {
|
||||||
PreambleRebuildCounter = 2;
|
PreambleRebuildCounter = 2;
|
||||||
|
@ -2396,7 +2385,6 @@ void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
|
||||||
StoredDiagnostics);
|
StoredDiagnostics);
|
||||||
|
|
||||||
// Create the target instance.
|
// Create the target instance.
|
||||||
Clang->getTargetOpts().Features = TargetFeatures;
|
|
||||||
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
Clang->setTarget(TargetInfo::CreateTargetInfo(Clang->getDiagnostics(),
|
||||||
Clang->getTargetOpts()));
|
Clang->getTargetOpts()));
|
||||||
if (!Clang->hasTarget()) {
|
if (!Clang->hasTarget()) {
|
||||||
|
|
|
@ -35,11 +35,12 @@ using namespace clang;
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
CompilerInvocationBase::CompilerInvocationBase()
|
CompilerInvocationBase::CompilerInvocationBase()
|
||||||
: LangOpts(new LangOptions()) {}
|
: LangOpts(new LangOptions()), TargetOpts(new TargetOptions()) {}
|
||||||
|
|
||||||
CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
|
CompilerInvocationBase::CompilerInvocationBase(const CompilerInvocationBase &X)
|
||||||
: RefCountedBase<CompilerInvocation>(),
|
: RefCountedBase<CompilerInvocation>(),
|
||||||
LangOpts(new LangOptions(*X.getLangOpts())) {}
|
LangOpts(new LangOptions(*X.getLangOpts())),
|
||||||
|
TargetOpts(new TargetOptions(X.getTargetOpts())) {}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Utility functions.
|
// Utility functions.
|
||||||
|
@ -927,8 +928,8 @@ static void TargetOptsToArgs(const TargetOptions &Opts,
|
||||||
Res.push_back("-target-linker-version", Opts.LinkerVersion);
|
Res.push_back("-target-linker-version", Opts.LinkerVersion);
|
||||||
if (!Opts.CXXABI.empty())
|
if (!Opts.CXXABI.empty())
|
||||||
Res.push_back("-cxx-abi", Opts.CXXABI);
|
Res.push_back("-cxx-abi", Opts.CXXABI);
|
||||||
for (unsigned i = 0, e = Opts.Features.size(); i != e; ++i)
|
for (unsigned i = 0, e = Opts.FeaturesAsWritten.size(); i != e; ++i)
|
||||||
Res.push_back("-target-feature", Opts.Features[i]);
|
Res.push_back("-target-feature", Opts.FeaturesAsWritten[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompilerInvocation::toArgs(std::vector<std::string> &Res) const {
|
void CompilerInvocation::toArgs(std::vector<std::string> &Res) const {
|
||||||
|
@ -2285,7 +2286,7 @@ static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
|
||||||
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
|
Opts.ABI = Args.getLastArgValue(OPT_target_abi);
|
||||||
Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
|
Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
|
||||||
Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
|
Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
|
||||||
Opts.Features = Args.getAllArgValues(OPT_target_feature);
|
Opts.FeaturesAsWritten = Args.getAllArgValues(OPT_target_feature);
|
||||||
Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
|
Opts.LinkerVersion = Args.getLastArgValue(OPT_target_linker_version);
|
||||||
Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
|
Opts.Triple = llvm::Triple::normalize(Args.getLastArgValue(OPT_triple));
|
||||||
|
|
||||||
|
@ -2431,7 +2432,8 @@ std::string CompilerInvocation::getModuleHash() const {
|
||||||
#include "clang/Basic/LangOptions.def"
|
#include "clang/Basic/LangOptions.def"
|
||||||
|
|
||||||
// Extend the signature with the target triple
|
// Extend the signature with the target triple
|
||||||
llvm::Triple T(TargetOpts.Triple);
|
// FIXME: Add target options.
|
||||||
|
llvm::Triple T(TargetOpts->Triple);
|
||||||
Signature.add((unsigned)T.getArch(), 5);
|
Signature.add((unsigned)T.getArch(), 5);
|
||||||
Signature.add((unsigned)T.getVendor(), 4);
|
Signature.add((unsigned)T.getVendor(), 4);
|
||||||
Signature.add((unsigned)T.getOS(), 5);
|
Signature.add((unsigned)T.getOS(), 5);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "clang/Basic/FileManager.h"
|
#include "clang/Basic/FileManager.h"
|
||||||
#include "clang/Basic/FileSystemStatCache.h"
|
#include "clang/Basic/FileSystemStatCache.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
|
#include "clang/Basic/TargetOptions.h"
|
||||||
#include "clang/Basic/Version.h"
|
#include "clang/Basic/Version.h"
|
||||||
#include "clang/Basic/VersionTuple.h"
|
#include "clang/Basic/VersionTuple.h"
|
||||||
#include "llvm/ADT/StringExtras.h"
|
#include "llvm/ADT/StringExtras.h"
|
||||||
|
@ -101,13 +102,66 @@ PCHValidator::ReadLanguageOptions(const ModuleFile &M,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PCHValidator::ReadTargetTriple(const ModuleFile &M, StringRef Triple) {
|
bool PCHValidator::ReadTargetOptions(const ModuleFile &M,
|
||||||
if (Triple == PP.getTargetInfo().getTriple().str())
|
const TargetOptions &TargetOpts) {
|
||||||
return false;
|
const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts();
|
||||||
|
|
||||||
Reader.Diag(diag::warn_pch_target_triple)
|
#define CHECK_TARGET_OPT(Field, Name) \
|
||||||
<< Triple << PP.getTargetInfo().getTriple().str();
|
if (TargetOpts.Field != ExistingTargetOpts.Field) { \
|
||||||
return true;
|
Reader.Diag(diag::err_pch_targetopt_mismatch) \
|
||||||
|
<< Name << TargetOpts.Field << ExistingTargetOpts.Field; \
|
||||||
|
return true; \
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_TARGET_OPT(Triple, "target");
|
||||||
|
CHECK_TARGET_OPT(CPU, "target CPU");
|
||||||
|
CHECK_TARGET_OPT(ABI, "target ABI");
|
||||||
|
CHECK_TARGET_OPT(CXXABI, "target C++ ABI");
|
||||||
|
CHECK_TARGET_OPT(LinkerVersion, "target linker version");
|
||||||
|
#undef CHECK_TARGET_OPT
|
||||||
|
|
||||||
|
// Compare feature sets.
|
||||||
|
SmallVector<StringRef, 4> ExistingFeatures(
|
||||||
|
ExistingTargetOpts.FeaturesAsWritten.begin(),
|
||||||
|
ExistingTargetOpts.FeaturesAsWritten.end());
|
||||||
|
SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(),
|
||||||
|
TargetOpts.FeaturesAsWritten.end());
|
||||||
|
std::sort(ExistingFeatures.begin(), ExistingFeatures.end());
|
||||||
|
std::sort(ReadFeatures.begin(), ReadFeatures.end());
|
||||||
|
|
||||||
|
unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size();
|
||||||
|
unsigned ReadIdx = 0, ReadN = ReadFeatures.size();
|
||||||
|
while (ExistingIdx < ExistingN && ReadIdx < ReadN) {
|
||||||
|
if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) {
|
||||||
|
++ExistingIdx;
|
||||||
|
++ReadIdx;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) {
|
||||||
|
Reader.Diag(diag::err_pch_targetopt_feature_mismatch)
|
||||||
|
<< false << ReadFeatures[ReadIdx];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Reader.Diag(diag::err_pch_targetopt_feature_mismatch)
|
||||||
|
<< true << ExistingFeatures[ExistingIdx];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ExistingIdx < ExistingN) {
|
||||||
|
Reader.Diag(diag::err_pch_targetopt_feature_mismatch)
|
||||||
|
<< true << ExistingFeatures[ExistingIdx];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReadIdx < ReadN) {
|
||||||
|
Reader.Diag(diag::err_pch_targetopt_feature_mismatch)
|
||||||
|
<< false << ReadFeatures[ReadIdx];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -1834,7 +1888,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
|
||||||
case METADATA: {
|
case METADATA: {
|
||||||
if (Record[0] != VERSION_MAJOR && !DisableValidation) {
|
if (Record[0] != VERSION_MAJOR && !DisableValidation) {
|
||||||
Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
|
Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old
|
||||||
: diag::warn_pch_version_too_new);
|
: diag::warn_pch_version_too_new);
|
||||||
return IgnorePCH;
|
return IgnorePCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1846,8 +1900,21 @@ ASTReader::ReadASTBlock(ModuleFile &F) {
|
||||||
|
|
||||||
RelocatablePCH = Record[4];
|
RelocatablePCH = Record[4];
|
||||||
if (Listener) {
|
if (Listener) {
|
||||||
std::string TargetTriple(BlobStart, BlobLen);
|
unsigned Idx = 6;
|
||||||
if (Listener->ReadTargetTriple(F, TargetTriple))
|
TargetOptions TargetOpts;
|
||||||
|
TargetOpts.Triple = ReadString(Record, Idx);
|
||||||
|
TargetOpts.CPU = ReadString(Record, Idx);
|
||||||
|
TargetOpts.ABI = ReadString(Record, Idx);
|
||||||
|
TargetOpts.CXXABI = ReadString(Record, Idx);
|
||||||
|
TargetOpts.LinkerVersion = ReadString(Record, Idx);
|
||||||
|
for (unsigned N = Record[Idx++]; N; --N) {
|
||||||
|
TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx));
|
||||||
|
}
|
||||||
|
for (unsigned N = Record[Idx++]; N; --N) {
|
||||||
|
TargetOpts.Features.push_back(ReadString(Record, Idx));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Listener->ReadTargetOptions(F, TargetOpts))
|
||||||
return IgnorePCH;
|
return IgnorePCH;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
#include "clang/Basic/SourceManagerInternals.h"
|
#include "clang/Basic/SourceManagerInternals.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
|
#include "clang/Basic/TargetOptions.h"
|
||||||
#include "clang/Basic/Version.h"
|
#include "clang/Basic/Version.h"
|
||||||
#include "clang/Basic/VersionTuple.h"
|
#include "clang/Basic/VersionTuple.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
|
@ -984,27 +985,28 @@ void ASTWriter::WriteMetadata(ASTContext &Context, StringRef isysroot,
|
||||||
|
|
||||||
// Metadata
|
// Metadata
|
||||||
const TargetInfo &Target = Context.getTargetInfo();
|
const TargetInfo &Target = Context.getTargetInfo();
|
||||||
BitCodeAbbrev *MetaAbbrev = new BitCodeAbbrev();
|
const TargetOptions &TargetOpts = Target.getTargetOpts();
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(METADATA));
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST major
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // AST minor
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang major
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 16)); // Clang minor
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Relocatable
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Has errors
|
|
||||||
MetaAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Target triple
|
|
||||||
unsigned MetaAbbrevCode = Stream.EmitAbbrev(MetaAbbrev);
|
|
||||||
|
|
||||||
RecordData Record;
|
RecordData Record;
|
||||||
Record.push_back(METADATA);
|
|
||||||
Record.push_back(VERSION_MAJOR);
|
Record.push_back(VERSION_MAJOR);
|
||||||
Record.push_back(VERSION_MINOR);
|
Record.push_back(VERSION_MINOR);
|
||||||
Record.push_back(CLANG_VERSION_MAJOR);
|
Record.push_back(CLANG_VERSION_MAJOR);
|
||||||
Record.push_back(CLANG_VERSION_MINOR);
|
Record.push_back(CLANG_VERSION_MINOR);
|
||||||
Record.push_back(!isysroot.empty());
|
Record.push_back(!isysroot.empty());
|
||||||
Record.push_back(ASTHasCompilerErrors);
|
Record.push_back(ASTHasCompilerErrors);
|
||||||
const std::string &Triple = Target.getTriple().getTriple();
|
AddString(TargetOpts.Triple, Record);
|
||||||
Stream.EmitRecordWithBlob(MetaAbbrevCode, Record, Triple);
|
AddString(TargetOpts.CPU, Record);
|
||||||
|
AddString(TargetOpts.ABI, Record);
|
||||||
|
AddString(TargetOpts.CXXABI, Record);
|
||||||
|
AddString(TargetOpts.LinkerVersion, Record);
|
||||||
|
Record.push_back(TargetOpts.FeaturesAsWritten.size());
|
||||||
|
for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size(); I != N; ++I) {
|
||||||
|
AddString(TargetOpts.FeaturesAsWritten[I], Record);
|
||||||
|
}
|
||||||
|
Record.push_back(TargetOpts.Features.size());
|
||||||
|
for (unsigned I = 0, N = TargetOpts.Features.size(); I != N; ++I) {
|
||||||
|
AddString(TargetOpts.Features[I], Record);
|
||||||
|
}
|
||||||
|
Stream.EmitRecord(METADATA, Record);
|
||||||
|
|
||||||
if (Chain) {
|
if (Chain) {
|
||||||
serialization::ModuleManager &Mgr = Chain->getModuleManager();
|
serialization::ModuleManager &Mgr = Chain->getModuleManager();
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// RUN: %clang_cc1 -triple=x86_64-apple-darwin9 -emit-pch -o %t.pch %S/target-options.h
|
||||||
|
// RUN: not %clang_cc1 -triple=x86_64-unknown-freebsd7.0 -include-pch %t.pch %s -emit-llvm -o - > %t.err 2>&1
|
||||||
|
// RUN: FileCheck %s < %t.err
|
||||||
|
|
||||||
|
// CHECK: for the target
|
|
@ -0,0 +1,2 @@
|
||||||
|
enum { apple_cc = __APPLE_CC__ };
|
||||||
|
|
Loading…
Reference in New Issue