Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
cfe/trunk/lib/Driver/ToolChains/Clang.cpp
Show First 20 Lines • Show All 1,054 Lines • ▼ Show 20 Lines | void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA, | ||||
if (JA.isOffloading(Action::OFK_Cuda)) | if (JA.isOffloading(Action::OFK_Cuda)) | ||||
getToolChain().AddCudaIncludeArgs(Args, CmdArgs); | getToolChain().AddCudaIncludeArgs(Args, CmdArgs); | ||||
// Add -i* options, and automatically translate to | // Add -i* options, and automatically translate to | ||||
// -include-pch/-include-pth for transparent PCH support. It's | // -include-pch/-include-pth for transparent PCH support. It's | ||||
// wonky, but we include looking for .gch so we can support seamless | // wonky, but we include looking for .gch so we can support seamless | ||||
// replacement into a build system already set up to be generating | // replacement into a build system already set up to be generating | ||||
// .gch files. | // .gch files. | ||||
int YcIndex = -1, YuIndex = -1; | |||||
{ | if (getToolChain().getDriver().IsCLMode()) { | ||||
int AI = -1; | |||||
const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc); | const Arg *YcArg = Args.getLastArg(options::OPT__SLASH_Yc); | ||||
const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu); | const Arg *YuArg = Args.getLastArg(options::OPT__SLASH_Yu); | ||||
for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) { | if (YcArg && JA.getKind() >= Action::PrecompileJobClass && | ||||
// Walk the whole i_Group and skip non "-include" flags so that the index | |||||
// here matches the index in the next loop below. | |||||
++AI; | |||||
if (!A->getOption().matches(options::OPT_include)) | |||||
continue; | |||||
if (YcArg && strcmp(A->getValue(), YcArg->getValue()) == 0) | |||||
YcIndex = AI; | |||||
if (YuArg && strcmp(A->getValue(), YuArg->getValue()) == 0) | |||||
YuIndex = AI; | |||||
} | |||||
} | |||||
if (isa<PrecompileJobAction>(JA) && YcIndex != -1) { | |||||
Driver::InputList Inputs; | |||||
D.BuildInputs(getToolChain(), C.getArgs(), Inputs); | |||||
assert(Inputs.size() == 1 && "Need one input when building pch"); | |||||
CmdArgs.push_back(Args.MakeArgString(Twine("-find-pch-source=") + | |||||
Inputs[0].second->getValue())); | |||||
} | |||||
if (YcIndex != -1 && JA.getKind() >= Action::PrecompileJobClass && | |||||
JA.getKind() <= Action::AssembleJobClass) { | JA.getKind() <= Action::AssembleJobClass) { | ||||
CmdArgs.push_back(Args.MakeArgString("-building-pch-with-obj")); | CmdArgs.push_back(Args.MakeArgString("-building-pch-with-obj")); | ||||
} | } | ||||
if (YcArg || YuArg) { | |||||
bool RenderedImplicitInclude = false; | StringRef ThroughHeader = YcArg ? YcArg->getValue() : YuArg->getValue(); | ||||
int AI = -1; | if (!isa<PrecompileJobAction>(JA)) { | ||||
for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) { | |||||
++AI; | |||||
if (getToolChain().getDriver().IsCLMode() && | |||||
A->getOption().matches(options::OPT_include)) { | |||||
// In clang-cl mode, /Ycfoo.h means that all code up to a foo.h | |||||
// include is compiled into foo.h, and everything after goes into | |||||
// the .obj file. /Yufoo.h means that all includes prior to and including | |||||
// foo.h are completely skipped and replaced with a use of the pch file | |||||
// for foo.h. (Each flag can have at most one value, multiple /Yc flags | |||||
// just mean that the last one wins.) If /Yc and /Yu are both present | |||||
// and refer to the same file, /Yc wins. | |||||
// Note that OPT__SLASH_FI gets mapped to OPT_include. | |||||
// FIXME: The code here assumes that /Yc and /Yu refer to the same file. | |||||
// cl.exe seems to support both flags with different values, but that | |||||
// seems strange (which flag does /Fp now refer to?), so don't implement | |||||
// that until someone needs it. | |||||
int PchIndex = YcIndex != -1 ? YcIndex : YuIndex; | |||||
if (PchIndex != -1) { | |||||
if (isa<PrecompileJobAction>(JA)) { | |||||
// When building the pch, skip all includes after the pch. | |||||
assert(YcIndex != -1 && PchIndex == YcIndex); | |||||
if (AI >= YcIndex) | |||||
continue; | |||||
} else { | |||||
// When using the pch, skip all includes prior to the pch. | |||||
if (AI < PchIndex) { | |||||
A->claim(); | |||||
continue; | |||||
} | |||||
if (AI == PchIndex) { | |||||
A->claim(); | |||||
CmdArgs.push_back("-include-pch"); | CmdArgs.push_back("-include-pch"); | ||||
CmdArgs.push_back( | CmdArgs.push_back(Args.MakeArgString(D.GetClPchPath(C, ThroughHeader))); | ||||
Args.MakeArgString(D.GetClPchPath(C, A->getValue()))); | |||||
continue; | |||||
} | } | ||||
CmdArgs.push_back( | |||||
Args.MakeArgString(Twine("-pch-through-header=") + ThroughHeader)); | |||||
} | } | ||||
} | } | ||||
} else if (A->getOption().matches(options::OPT_include)) { | |||||
bool RenderedImplicitInclude = false; | |||||
for (const Arg *A : Args.filtered(options::OPT_clang_i_Group)) { | |||||
if (A->getOption().matches(options::OPT_include)) { | |||||
// Handling of gcc-style gch precompiled headers. | // Handling of gcc-style gch precompiled headers. | ||||
bool IsFirstImplicitInclude = !RenderedImplicitInclude; | bool IsFirstImplicitInclude = !RenderedImplicitInclude; | ||||
RenderedImplicitInclude = true; | RenderedImplicitInclude = true; | ||||
// Use PCH if the user requested it. | // Use PCH if the user requested it. | ||||
bool UsePCH = D.CCCUsePCH; | bool UsePCH = D.CCCUsePCH; | ||||
bool FoundPTH = false; | bool FoundPTH = false; | ||||
▲ Show 20 Lines • Show All 4,530 Lines • Show Last 20 Lines |