Vendor import of clang 3.0 final release:

http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_30/final@145349
This commit is contained in:
Dimitry Andric 2011-12-09 18:30:42 +00:00
parent 36981b17ed
commit 9da628931e
37 changed files with 1118 additions and 887 deletions

View File

@ -815,7 +815,7 @@ class Cursor(Structure):
The Cursor class represents a reference to an element within the AST. It
acts as a kind of iterator.
"""
_fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
_fields_ = [("_kind_id", c_int), ("xdata", c_int), ("data", c_void_p * 3)]
def __eq__(self, other):
return Cursor_eq(self, other)
@ -1019,7 +1019,7 @@ def __repr__(self):
TypeKind.OBJCOBJECTPOINTER = TypeKind(109)
TypeKind.FUNCTIONNOPROTO = TypeKind(110)
TypeKind.FUNCTIONPROTO = TypeKind(111)
TypeKind.CONSTANTARRAY = TypeKind(112)
class Type(Structure):
"""

View File

@ -74,3 +74,22 @@ def test_a_struct():
else:
assert False, "Didn't find teststruct??"
constarrayInput="""
struct teststruct {
void *A[2];
};
"""
def testConstantArray():
index = Index.create()
tu = index.parse('t.c', unsaved_files = [('t.c',constarrayInput)])
for n in tu.cursor.get_children():
if n.spelling == 'teststruct':
fields = list(n.get_children())
assert fields[0].spelling == 'A'
assert fields[0].type.kind == TypeKind.CONSTANTARRAY
break
else:
assert False, "Didn't find teststruct??"

View File

@ -672,16 +672,16 @@ LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_LANGUAGES)
LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_LANGUAGES)
// POSIX unistd.h
LIBBUILTIN(_exit, "vi", "fr", "unistd.h", ALL_LANGUAGES)
LIBBUILTIN(vfork, "iJ", "fj", "unistd.h", ALL_LANGUAGES)
LIBBUILTIN(vfork, "i", "fj", "unistd.h", ALL_LANGUAGES)
// POSIX setjmp.h
// In some systems setjmp is a macro that expands to _setjmp. We undefine
// it here to avoid having two identical LIBBUILTIN entries.
#undef setjmp
LIBBUILTIN(_setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(__sigsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(__sigsetjmp, "iJi", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(setjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(sigsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(sigsetjmp, "iJi", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(setjmp_syscall, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(savectx, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)
LIBBUILTIN(qsetjmp, "iJ", "fj", "setjmp.h", ALL_LANGUAGES)

View File

@ -642,6 +642,17 @@ def isystem : JoinedOrSeparate<"-isystem">, MetaVarName<"<directory>">,
def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">,MetaVarName<"<directory>">,
HelpText<"Add directory to SYSTEM include search path, "
"absolute paths are relative to -isysroot">;
def internal_isystem : JoinedOrSeparate<"-internal-isystem">,
MetaVarName<"<directory>">,
HelpText<"Add directory to the internal system include search path; these "
"are assumed to not be user-provided and are used to model system "
"and standard headers' paths.">;
def internal_externc_isystem : JoinedOrSeparate<"-internal-externc-isystem">,
MetaVarName<"<directory>">,
HelpText<"Add directory to the internal system include search path with "
"implicit extern \"C\" semantics; these are assumed to not be "
"user-provided and are used to model system and standard headers' "
"paths.">;
def iprefix : JoinedOrSeparate<"-iprefix">, MetaVarName<"<prefix>">,
HelpText<"Set the -iwithprefix/-iwithprefixbefore prefix">;
def iwithprefix : JoinedOrSeparate<"-iwithprefix">, MetaVarName<"<dir>">,

View File

@ -195,15 +195,21 @@ class ToolChain {
/// FIXME: this really belongs on some sort of DeploymentTarget abstraction
virtual bool hasBlocksRuntime() const { return true; }
/// \brief Add the clang cc1 arguments for system include paths.
///
/// This routine is responsible for adding the necessary cc1 arguments to
/// include headers from standard system header directories.
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
// GetCXXStdlibType - Determine the C++ standard library type to use with the
// given compilation arguments.
virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const;
/// AddClangCXXStdlibIncludeArgs - Add the clang -cc1 level arguments to set
/// the include paths to use for the given C++ standard library type.
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &Args,
ArgStringList &CmdArgs,
bool ObjCXXAutoRefCount) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
/// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
/// for the given C++ standard library type.

View File

@ -49,10 +49,24 @@ class HeaderSearchOptions {
/// path.
unsigned IgnoreSysRoot : 1;
/// \brief True if this entry is an internal search path.
///
/// This typically indicates that users didn't directly provide it, but
/// instead it was provided by a compatibility layer for a particular
/// system. This isn't redundant with IsUserSupplied (even though perhaps
/// it should be) because that is false for user provided '-iwithprefix'
/// header search entries.
unsigned IsInternal : 1;
/// \brief True if this entry's headers should be wrapped in extern "C".
unsigned ImplicitExternC : 1;
Entry(StringRef path, frontend::IncludeDirGroup group,
bool isUserSupplied, bool isFramework, bool ignoreSysRoot)
bool isUserSupplied, bool isFramework, bool ignoreSysRoot,
bool isInternal, bool implicitExternC)
: Path(path), Group(group), IsUserSupplied(isUserSupplied),
IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot) {}
IsFramework(isFramework), IgnoreSysRoot(ignoreSysRoot),
IsInternal(isInternal), ImplicitExternC(implicitExternC) {}
};
/// If non-empty, the directory to use as a "virtual system root" for include
@ -98,9 +112,10 @@ class HeaderSearchOptions {
/// AddPath - Add the \arg Path path to the specified \arg Group list.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot) {
bool IsUserSupplied, bool IsFramework, bool IgnoreSysRoot,
bool IsInternal = false, bool ImplicitExternC = false) {
UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework,
IgnoreSysRoot));
IgnoreSysRoot, IsInternal, ImplicitExternC));
}
};

View File

@ -32,7 +32,7 @@ std::string getClangRepositoryPath() {
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/branches/release_30/lib/Basic/Version.cpp $");
static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_30/final/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));

View File

@ -538,11 +538,12 @@ class CGObjCGCC : public CGObjCGNU {
llvm::Value *cmd,
llvm::MDNode *node) {
CGBuilderTy &Builder = CGF.Builder;
llvm::Value *imp = Builder.CreateCall2(MsgLookupFn,
EnforceType(Builder, Receiver, IdTy),
EnforceType(Builder, cmd, SelectorTy));
cast<llvm::CallInst>(imp)->setMetadata(msgSendMDKind, node);
return imp;
llvm::Value *args[] = {
EnforceType(Builder, Receiver, IdTy),
EnforceType(Builder, cmd, SelectorTy) };
llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args);
imp->setMetadata(msgSendMDKind, node);
return imp.getInstruction();
}
virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF,
llvm::Value *ObjCSuper,
@ -597,16 +598,17 @@ class CGObjCGNUstep : public CGObjCGNU {
// The lookup function is guaranteed not to capture the receiver pointer.
LookupFn->setDoesNotCapture(1);
llvm::CallInst *slot =
Builder.CreateCall3(LookupFn,
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
EnforceType(Builder, cmd, SelectorTy),
EnforceType(Builder, self, IdTy));
slot->setOnlyReadsMemory();
llvm::Value *args[] = {
EnforceType(Builder, ReceiverPtr, PtrToIdTy),
EnforceType(Builder, cmd, SelectorTy),
EnforceType(Builder, self, IdTy) };
llvm::CallSite slot = CGF.EmitCallOrInvoke(LookupFn, args);
slot.setOnlyReadsMemory();
slot->setMetadata(msgSendMDKind, node);
// Load the imp from the slot
llvm::Value *imp = Builder.CreateLoad(Builder.CreateStructGEP(slot, 4));
llvm::Value *imp =
Builder.CreateLoad(Builder.CreateStructGEP(slot.getInstruction(), 4));
// The lookup function may have changed the receiver, so make sure we use
// the new one.
@ -1361,8 +1363,8 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
LongTy, // abi_version
IvarOffsets->getType(), // ivar_offsets
Properties->getType(), // properties
Int64Ty, // strong_pointers
Int64Ty, // weak_pointers
IntPtrTy, // strong_pointers
IntPtrTy, // weak_pointers
NULL);
llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0);
// Fill in the structure
@ -1723,12 +1725,14 @@ void CGObjCGNU::GenerateProtocolHolderCategory(void) {
/// bitfield / with the 63rd bit set will be 1<<64.
llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) {
int bitCount = bits.size();
if (bitCount < 64) {
int ptrBits =
(TheModule.getPointerSize() == llvm::Module::Pointer32) ? 32 : 64;
if (bitCount < ptrBits) {
uint64_t val = 1;
for (int i=0 ; i<bitCount ; ++i) {
if (bits[i]) val |= 1ULL<<(i+1);
}
return llvm::ConstantInt::get(Int64Ty, val);
return llvm::ConstantInt::get(IntPtrTy, val);
}
llvm::SmallVector<llvm::Constant*, 8> values;
int v=0;
@ -1748,8 +1752,6 @@ llvm::Constant *CGObjCGNU::MakeBitField(llvm::SmallVectorImpl<bool> &bits) {
llvm::Constant *GS = MakeGlobal(llvm::StructType::get(Int32Ty, arrayTy,
NULL), fields);
llvm::Constant *ptr = llvm::ConstantExpr::getPtrToInt(GS, IntPtrTy);
if (IntPtrTy != Int64Ty)
ptr = llvm::ConstantExpr::getZExt(ptr, Int64Ty);
return ptr;
}
@ -2073,12 +2075,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
}
++ivarIndex;
}
llvm::Constant *Zero64 = llvm::ConstantInt::get(Int64Ty, 0);
llvm::Constant *ZeroPtr = llvm::ConstantInt::get(IntPtrTy, 0);
//Generate metaclass for class methods
llvm::Constant *MetaClassStruct = GenerateClassStructure(NULLPtr,
NULLPtr, 0x12L, ClassName.c_str(), 0, Zeros[0], GenerateIvarList(
empty, empty, empty), ClassMethodList, NULLPtr,
NULLPtr, NULLPtr, Zero64, Zero64, true);
NULLPtr, NULLPtr, ZeroPtr, ZeroPtr, true);
// Generate the class structure
llvm::Constant *ClassStruct =

View File

@ -29,6 +29,7 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@ -858,6 +859,59 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
}
}
namespace {
struct FunctionIsDirectlyRecursive :
public RecursiveASTVisitor<FunctionIsDirectlyRecursive> {
const StringRef Name;
bool Result;
FunctionIsDirectlyRecursive(const FunctionDecl *F) :
Name(F->getName()), Result(false) {
}
typedef RecursiveASTVisitor<FunctionIsDirectlyRecursive> Base;
bool TraverseCallExpr(CallExpr *E) {
const Decl *D = E->getCalleeDecl();
if (!D)
return true;
AsmLabelAttr *Attr = D->getAttr<AsmLabelAttr>();
if (!Attr)
return true;
if (Name == Attr->getLabel()) {
Result = true;
return false;
}
return true;
}
};
}
// isTriviallyRecursiveViaAsm - Check if this function calls another
// decl that, because of the asm attribute, ends up pointing to itself.
bool
CodeGenModule::isTriviallyRecursiveViaAsm(const FunctionDecl *F) {
if (getCXXABI().getMangleContext().shouldMangleDeclName(F))
return false;
FunctionIsDirectlyRecursive Walker(F);
Walker.TraverseFunctionDecl(const_cast<FunctionDecl*>(F));
return Walker.Result;
}
bool
CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
return true;
if (CodeGenOpts.OptimizationLevel == 0 &&
!F->hasAttr<AlwaysInlineAttr>())
return false;
// PR9614. Avoid cases where the source code is lying to us. An available
// externally function should have an equivalent function somewhere else,
// but a function that calls itself is clearly not equivalent to the real
// implementation.
// This happens in glibc's btowc and in some configure checks.
return !isTriviallyRecursiveViaAsm(F);
}
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
const ValueDecl *D = cast<ValueDecl>(GD.getDecl());
@ -868,10 +922,7 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// At -O0, don't generate IR for functions with available_externally
// linkage.
if (CodeGenOpts.OptimizationLevel == 0 &&
!Function->hasAttr<AlwaysInlineAttr>() &&
getFunctionLinkage(Function)
== llvm::Function::AvailableExternallyLinkage)
if (!shouldEmitFunction(Function))
return;
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {

View File

@ -324,6 +324,8 @@ class CodeGenModule : public CodeGenTypeCache {
void createOpenCLRuntime();
void createCUDARuntime();
bool isTriviallyRecursiveViaAsm(const FunctionDecl *F);
bool shouldEmitFunction(const FunctionDecl *F);
llvm::LLVMContext &VMContext;
/// @name Cache for Blocks Runtime Globals

View File

@ -21,5 +21,13 @@ add_clang_library(clangDriver
Types.cpp
)
IF(MSVC)
get_target_property(NON_ANSI_COMPILE_FLAGS clangDriver COMPILE_FLAGS)
string(REPLACE /Za
"" NON_ANSI_COMPILE_FLAGS
${NON_ANSI_COMPILE_FLAGS})
set_target_properties(clangDriver PROPERTIES COMPILE_FLAGS ${NON_ANSI_COMPILE_FLAGS})
ENDIF(MSVC)
add_dependencies(clangDriver ClangAttrList ClangDiagnosticDriver
ClangDriverOptions ClangCC1Options ClangCC1AsOptions)

View File

@ -211,6 +211,11 @@ std::string ToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
return ComputeLLVMTriple(Args, InputType);
}
void ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
// Each toolchain should provide the appropriate include flags.
}
ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
if (Arg *A = Args.getLastArg(options::OPT_stdlib_EQ)) {
StringRef Value = A->getValue(Args);
@ -225,24 +230,18 @@ ToolChain::CXXStdlibType ToolChain::GetCXXStdlibType(const ArgList &Args) const{
return ToolChain::CST_Libstdcxx;
}
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
ArgStringList &CmdArgs,
bool ObjCXXAutoRefCount) const {
CXXStdlibType Type = GetCXXStdlibType(Args);
// Header search paths are handled by the mass of goop in InitHeaderSearch.
switch (Type) {
case ToolChain::CST_Libcxx:
if (ObjCXXAutoRefCount)
CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
break;
case ToolChain::CST_Libstdcxx:
if (ObjCXXAutoRefCount)
CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
break;
}
void ToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {
// Header search paths should be handled by each of the subclasses.
// Historically, they have not been, and instead have been handled inside of
// the CC1-layer frontend. As the logic is hoisted out, this generic function
// will slowly stop being called.
//
// While it is being called, replicate a bit of a hack to propagate the
// '-stdlib=' flag down to CC1 so that it can in turn customize the C++
// header search paths with it. Once all systems are overriding this
// function, the CC1 flag and this line can be removed.
DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
}
void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,

File diff suppressed because it is too large Load Diff

View File

@ -372,6 +372,86 @@ class LLVM_LIBRARY_VISIBILITY DragonFly : public Generic_ELF {
};
class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
/// \brief Struct to store and manipulate GCC versions.
///
/// We rely on assumptions about the form and structure of GCC version
/// numbers: they consist of at most three '.'-separated components, and each
/// component is a non-negative integer except for the last component. For
/// the last component we are very flexible in order to tolerate release
/// candidates or 'x' wildcards.
///
/// Note that the ordering established among GCCVersions is based on the
/// preferred version string to use. For example we prefer versions without
/// a hard-coded patch number to those with a hard coded patch number.
///
/// Currently this doesn't provide any logic for textual suffixes to patches
/// in the way that (for example) Debian's version format does. If that ever
/// becomes necessary, it can be added.
struct GCCVersion {
/// \brief The unparsed text of the version.
std::string Text;
/// \brief The parsed major, minor, and patch numbers.
int Major, Minor, Patch;
/// \brief Any textual suffix on the patch number.
std::string PatchSuffix;
static GCCVersion Parse(StringRef VersionText);
bool operator<(const GCCVersion &RHS) const;
bool operator>(const GCCVersion &RHS) const { return RHS < *this; }
bool operator<=(const GCCVersion &RHS) const { return !(*this > RHS); }
bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
};
/// \brief This is a class to find a viable GCC installation for Clang to
/// use.
///
/// This class tries to find a GCC installation on the system, and report
/// information about it. It starts from the host information provided to the
/// Driver, and has logic for fuzzing that where appropriate.
class GCCInstallationDetector {
bool IsValid;
std::string GccTriple;
// FIXME: These might be better as path objects.
std::string GccInstallPath;
std::string GccParentLibPath;
GCCVersion Version;
public:
GCCInstallationDetector(const Driver &D);
/// \brief Check whether we detected a valid GCC install.
bool isValid() const { return IsValid; }
/// \brief Get the GCC triple for the detected install.
StringRef getTriple() const { return GccTriple; }
/// \brief Get the detected GCC installation path.
StringRef getInstallPath() const { return GccInstallPath; }
/// \brief Get the detected GCC parent lib path.
StringRef getParentLibPath() const { return GccParentLibPath; }
/// \brief Get the detected GCC version string.
StringRef getVersion() const { return Version.Text; }
private:
static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch,
SmallVectorImpl<StringRef> &LibDirs,
SmallVectorImpl<StringRef> &Triples);
void ScanLibDirForGCCTriple(llvm::Triple::ArchType HostArch,
const std::string &LibDir,
StringRef CandidateTriple);
};
GCCInstallationDetector GCCInstallation;
public:
Linux(const HostInfo &Host, const llvm::Triple& Triple);
@ -380,6 +460,11 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
const ActionList &Inputs) const;
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
std::string Linker;
std::vector<std::string> ExtraOpts;
};
@ -417,6 +502,12 @@ class LLVM_LIBRARY_VISIBILITY Windows : public ToolChain {
virtual bool IsUnwindTablesDefault() const;
virtual const char *GetDefaultRelocationModel() const;
virtual const char *GetForcedPicModel() const;
virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const;
};
} // end namespace toolchains

View File

@ -364,16 +364,6 @@ void Clang::AddPreprocessingOptions(const Driver &D,
Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
options::OPT_index_header_map);
// Add C++ include arguments, if needed.
types::ID InputType = Inputs[0].getType();
if (types::isCXX(InputType)) {
bool ObjCXXAutoRefCount
= types::isObjC(InputType) && isObjCAutoRefCount(Args);
getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs,
ObjCXXAutoRefCount);
Args.AddAllArgs(CmdArgs, options::OPT_stdlib_EQ);
}
// Add -Wp, and -Xassembler if using the preprocessor.
// FIXME: There is a very unfortunate problem here, some troubled
@ -428,6 +418,13 @@ void Clang::AddPreprocessingOptions(const Driver &D,
// OBJCPLUS_INCLUDE_PATH - system includes enabled when compiling ObjC++.
AddIncludeDirectoryList(Args, CmdArgs, "-objcxx-isystem",
::getenv("OBJCPLUS_INCLUDE_PATH"));
// Add C++ include arguments, if needed.
if (types::isCXX(Inputs[0].getType()))
getToolChain().AddClangCXXStdlibIncludeArgs(Args, CmdArgs);
// Add system include arguments.
getToolChain().AddClangSystemIncludeArgs(Args, CmdArgs);
}
/// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
@ -1965,6 +1962,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (ARC) {
CmdArgs.push_back("-fobjc-arc");
// FIXME: It seems like this entire block, and several around it should be
// wrapped in isObjC, but for now we just use it here as this is where it
// was being used previously.
if (types::isCXX(InputType) && types::isObjC(InputType)) {
if (getToolChain().GetCXXStdlibType(Args) == ToolChain::CST_Libcxx)
CmdArgs.push_back("-fobjc-arc-cxxlib=libc++");
else
CmdArgs.push_back("-fobjc-arc-cxxlib=libstdc++");
}
// Allow the user to enable full exceptions code emission.
// We define off for Objective-CC, on for Objective-C++.
if (Args.hasFlag(options::OPT_fobjc_arc_exceptions,

View File

@ -569,10 +569,18 @@ static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
break;
}
} else {
if (E.Group != frontend::Angled && E.Group != frontend::System)
llvm::report_fatal_error("Invalid option set!");
Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
"-iwithprefix");
if (E.IsInternal) {
assert(E.Group == frontend::System && "Unexpected header search group");
if (E.ImplicitExternC)
Res.push_back("-internal-externc-isystem");
else
Res.push_back("-internal-isystem");
} else {
if (E.Group != frontend::Angled && E.Group != frontend::System)
llvm::report_fatal_error("Invalid option set!");
Res.push_back(E.Group == frontend::Angled ? "-iwithprefixbefore" :
"-iwithprefix");
}
}
Res.push_back(E.Path);
}
@ -1462,6 +1470,15 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
ie = Args.filtered_end(); it != ie; ++it)
Opts.AddPath((*it)->getValue(Args), frontend::ObjCXXSystem, true, false,
true);
// Add the internal paths from a driver that detects standard include paths.
for (arg_iterator I = Args.filtered_begin(OPT_internal_isystem,
OPT_internal_externc_isystem),
E = Args.filtered_end();
I != E; ++I)
Opts.AddPath((*I)->getValue(Args), frontend::System,
false, false, /*IgnoreSysRoot=*/true, /*IsInternal=*/true,
(*I)->getOption().matches(OPT_internal_externc_isystem));
}
void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,

View File

@ -27,12 +27,9 @@
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Path.h"
#include "llvm/Config/config.h"
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#endif
using namespace clang;
using namespace clang::frontend;
@ -207,219 +204,6 @@ void InitHeaderSearch::AddMinGW64CXXPaths(StringRef Base,
CXXSystem, true, false, false);
}
// FIXME: This probably should goto to some platform utils place.
#ifdef _MSC_VER
// Read registry string.
// This also supports a means to look for high-versioned keys by use
// of a $VERSION placeholder in the key path.
// $VERSION in the key path is a placeholder for the version number,
// causing the highest value path to be searched for and used.
// I.e. "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION".
// There can be additional characters in the component. Only the numberic
// characters are compared.
static bool getSystemRegistryString(const char *keyPath, const char *valueName,
char *value, size_t maxLength) {
HKEY hRootKey = NULL;
HKEY hKey = NULL;
const char* subKey = NULL;
DWORD valueType;
DWORD valueSize = maxLength - 1;
long lResult;
bool returnValue = false;
if (strncmp(keyPath, "HKEY_CLASSES_ROOT\\", 18) == 0) {
hRootKey = HKEY_CLASSES_ROOT;
subKey = keyPath + 18;
} else if (strncmp(keyPath, "HKEY_USERS\\", 11) == 0) {
hRootKey = HKEY_USERS;
subKey = keyPath + 11;
} else if (strncmp(keyPath, "HKEY_LOCAL_MACHINE\\", 19) == 0) {
hRootKey = HKEY_LOCAL_MACHINE;
subKey = keyPath + 19;
} else if (strncmp(keyPath, "HKEY_CURRENT_USER\\", 18) == 0) {
hRootKey = HKEY_CURRENT_USER;
subKey = keyPath + 18;
}
else
return false;
const char *placeHolder = strstr(subKey, "$VERSION");
char bestName[256];
bestName[0] = '\0';
// If we have a $VERSION placeholder, do the highest-version search.
if (placeHolder) {
const char *keyEnd = placeHolder - 1;
const char *nextKey = placeHolder;
// Find end of previous key.
while ((keyEnd > subKey) && (*keyEnd != '\\'))
keyEnd--;
// Find end of key containing $VERSION.
while (*nextKey && (*nextKey != '\\'))
nextKey++;
size_t partialKeyLength = keyEnd - subKey;
char partialKey[256];
if (partialKeyLength > sizeof(partialKey))
partialKeyLength = sizeof(partialKey);
strncpy(partialKey, subKey, partialKeyLength);
partialKey[partialKeyLength] = '\0';
HKEY hTopKey = NULL;
lResult = RegOpenKeyEx(hRootKey, partialKey, 0, KEY_READ, &hTopKey);
if (lResult == ERROR_SUCCESS) {
char keyName[256];
int bestIndex = -1;
double bestValue = 0.0;
DWORD index, size = sizeof(keyName) - 1;
for (index = 0; RegEnumKeyEx(hTopKey, index, keyName, &size, NULL,
NULL, NULL, NULL) == ERROR_SUCCESS; index++) {
const char *sp = keyName;
while (*sp && !isdigit(*sp))
sp++;
if (!*sp)
continue;
const char *ep = sp + 1;
while (*ep && (isdigit(*ep) || (*ep == '.')))
ep++;
char numBuf[32];
strncpy(numBuf, sp, sizeof(numBuf) - 1);
numBuf[sizeof(numBuf) - 1] = '\0';
double value = strtod(numBuf, NULL);
if (value > bestValue) {
bestIndex = (int)index;
bestValue = value;
strcpy(bestName, keyName);
}
size = sizeof(keyName) - 1;
}
// If we found the highest versioned key, open the key and get the value.
if (bestIndex != -1) {
// Append rest of key.
strncat(bestName, nextKey, sizeof(bestName) - 1);
bestName[sizeof(bestName) - 1] = '\0';
// Open the chosen key path remainder.
lResult = RegOpenKeyEx(hTopKey, bestName, 0, KEY_READ, &hKey);
if (lResult == ERROR_SUCCESS) {
lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
(LPBYTE)value, &valueSize);
if (lResult == ERROR_SUCCESS)
returnValue = true;
RegCloseKey(hKey);
}
}
RegCloseKey(hTopKey);
}
}
else {
lResult = RegOpenKeyEx(hRootKey, subKey, 0, KEY_READ, &hKey);
if (lResult == ERROR_SUCCESS) {
lResult = RegQueryValueEx(hKey, valueName, NULL, &valueType,
(LPBYTE)value, &valueSize);
if (lResult == ERROR_SUCCESS)
returnValue = true;
RegCloseKey(hKey);
}
}
return returnValue;
}
#else // _MSC_VER
// Read registry string.
static bool getSystemRegistryString(const char*, const char*, char*, size_t) {
return(false);
}
#endif // _MSC_VER
// Get Visual Studio installation directory.
static bool getVisualStudioDir(std::string &path) {
// First check the environment variables that vsvars32.bat sets.
const char* vcinstalldir = getenv("VCINSTALLDIR");
if (vcinstalldir) {
char *p = const_cast<char *>(strstr(vcinstalldir, "\\VC"));
if (p)
*p = '\0';
path = vcinstalldir;
return true;
}
char vsIDEInstallDir[256];
char vsExpressIDEInstallDir[256];
// Then try the windows registry.
bool hasVCDir = getSystemRegistryString(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\$VERSION",
"InstallDir", vsIDEInstallDir, sizeof(vsIDEInstallDir) - 1);
bool hasVCExpressDir = getSystemRegistryString(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VCExpress\\$VERSION",
"InstallDir", vsExpressIDEInstallDir, sizeof(vsExpressIDEInstallDir) - 1);
// If we have both vc80 and vc90, pick version we were compiled with.
if (hasVCDir && vsIDEInstallDir[0]) {
char *p = (char*)strstr(vsIDEInstallDir, "\\Common7\\IDE");
if (p)
*p = '\0';
path = vsIDEInstallDir;
return true;
}
if (hasVCExpressDir && vsExpressIDEInstallDir[0]) {
char *p = (char*)strstr(vsExpressIDEInstallDir, "\\Common7\\IDE");
if (p)
*p = '\0';
path = vsExpressIDEInstallDir;
return true;
}
// Try the environment.
const char *vs100comntools = getenv("VS100COMNTOOLS");
const char *vs90comntools = getenv("VS90COMNTOOLS");
const char *vs80comntools = getenv("VS80COMNTOOLS");
const char *vscomntools = NULL;
// Try to find the version that we were compiled with
if(false) {}
#if (_MSC_VER >= 1600) // VC100
else if(vs100comntools) {
vscomntools = vs100comntools;
}
#elif (_MSC_VER == 1500) // VC80
else if(vs90comntools) {
vscomntools = vs90comntools;
}
#elif (_MSC_VER == 1400) // VC80
else if(vs80comntools) {
vscomntools = vs80comntools;
}
#endif
// Otherwise find any version we can
else if (vs100comntools)
vscomntools = vs100comntools;
else if (vs90comntools)
vscomntools = vs90comntools;
else if (vs80comntools)
vscomntools = vs80comntools;
if (vscomntools && *vscomntools) {
const char *p = strstr(vscomntools, "\\Common7\\Tools");
path = p ? std::string(vscomntools, p) : vscomntools;
return true;
}
return false;
}
// Get Windows SDK installation directory.
static bool getWindowsSDKDir(std::string &path) {
char windowsSDKInstallDir[256];
// Try the Windows registry.
bool hasSDKDir = getSystemRegistryString(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\$VERSION",
"InstallationFolder",
windowsSDKInstallDir,
sizeof(windowsSDKInstallDir) - 1);
// If we have both vc80 and vc90, pick version we were compiled with.
if (hasSDKDir && windowsSDKInstallDir[0]) {
path = windowsSDKInstallDir;
return(true);
}
return(false);
}
void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts) {
llvm::Triple::OSType os = triple.getOS();
@ -464,33 +248,10 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
}
switch (os) {
case llvm::Triple::Win32: {
std::string VSDir;
std::string WindowsSDKDir;
if (getVisualStudioDir(VSDir)) {
AddPath(VSDir + "\\VC\\include", System, false, false, false);
if (getWindowsSDKDir(WindowsSDKDir))
AddPath(WindowsSDKDir + "\\include", System, false, false, false);
else
AddPath(VSDir + "\\VC\\PlatformSDK\\Include",
System, false, false, false);
} else {
// Default install paths.
AddPath("C:/Program Files/Microsoft Visual Studio 10.0/VC/include",
System, false, false, false);
AddPath("C:/Program Files/Microsoft Visual Studio 9.0/VC/include",
System, false, false, false);
AddPath(
"C:/Program Files/Microsoft Visual Studio 9.0/VC/PlatformSDK/Include",
System, false, false, false);
AddPath("C:/Program Files/Microsoft Visual Studio 8/VC/include",
System, false, false, false);
AddPath(
"C:/Program Files/Microsoft Visual Studio 8/VC/PlatformSDK/Include",
System, false, false, false);
}
break;
}
case llvm::Triple::Linux:
case llvm::Triple::Win32:
llvm_unreachable("Include management is handled in the driver.");
case llvm::Triple::Haiku:
AddPath("/boot/common/include", System, true, false, false);
AddPath("/boot/develop/headers/os", System, true, false, false);
@ -556,19 +317,6 @@ void InitHeaderSearch::AddDefaultCIncludePaths(const llvm::Triple &triple,
}
break;
case llvm::Triple::Linux:
// Generic Debian multiarch support:
if (triple.getArch() == llvm::Triple::x86_64) {
AddPath("/usr/include/x86_64-linux-gnu", System, false, false, false);
AddPath("/usr/include/i686-linux-gnu/64", System, false, false, false);
AddPath("/usr/include/i486-linux-gnu/64", System, false, false, false);
} else if (triple.getArch() == llvm::Triple::x86) {
AddPath("/usr/include/x86_64-linux-gnu/32", System, false, false, false);
AddPath("/usr/include/i686-linux-gnu", System, false, false, false);
AddPath("/usr/include/i486-linux-gnu", System, false, false, false);
} else if (triple.getArch() == llvm::Triple::arm) {
AddPath("/usr/include/arm-linux-gnueabi", System, false, false, false);
}
default:
break;
}
@ -629,6 +377,10 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
}
switch (os) {
case llvm::Triple::Linux:
case llvm::Triple::Win32:
llvm_unreachable("Include management is handled in the driver.");
case llvm::Triple::Cygwin:
// Cygwin-1.7
AddMinGWCPlusPlusIncludePaths("/usr/lib/gcc", "i686-pc-cygwin", "4.3.4");
@ -655,257 +407,6 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
break;
case llvm::Triple::DragonFly:
AddPath("/usr/include/c++/4.1", CXXSystem, true, false, false);
break;
case llvm::Triple::Linux:
//===------------------------------------------------------------------===//
// Debian based distros.
// Note: these distros symlink /usr/include/c++/X.Y.Z -> X.Y
//===------------------------------------------------------------------===//
// Ubuntu 11.11 "Oneiric Ocelot" -- gcc-4.6.0
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
"x86_64-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
"i686-linux-gnu", "", "64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
"i486-linux-gnu", "", "64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
"arm-linux-gnueabi", "", "", triple);
// Ubuntu 11.04 "Natty Narwhal" -- gcc-4.5.2
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
"x86_64-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
"i686-linux-gnu", "", "64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
"i486-linux-gnu", "", "64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
"arm-linux-gnueabi", "", "", triple);
// Ubuntu 10.10 "Maverick Meerkat" -- gcc-4.4.5
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"i686-linux-gnu", "", "64", triple);
// The rest of 10.10 is the same as previous versions.
// Ubuntu 10.04 LTS "Lucid Lynx" -- gcc-4.4.3
// Ubuntu 9.10 "Karmic Koala" -- gcc-4.4.1
// Debian 6.0 "squeeze" -- gcc-4.4.2
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"x86_64-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"i486-linux-gnu", "", "64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"arm-linux-gnueabi", "", "", triple);
// Ubuntu 9.04 "Jaunty Jackalope" -- gcc-4.3.3
// Ubuntu 8.10 "Intrepid Ibex" -- gcc-4.3.2
// Debian 5.0 "lenny" -- gcc-4.3.2
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
"x86_64-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
"i486-linux-gnu", "", "64", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
"arm-linux-gnueabi", "", "", triple);
// Ubuntu 8.04.4 LTS "Hardy Heron" -- gcc-4.2.4
// Ubuntu 8.04.[0-3] LTS "Hardy Heron" -- gcc-4.2.3
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
"x86_64-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2",
"i486-linux-gnu", "", "64", triple);
// Ubuntu 7.10 "Gutsy Gibbon" -- gcc-4.1.3
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
"x86_64-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1",
"i486-linux-gnu", "", "64", triple);
//===------------------------------------------------------------------===//
// Redhat based distros.
//===------------------------------------------------------------------===//
// Fedora 15 (GCC 4.6.1)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
"i686-redhat-linux", "", "", triple);
// Fedora 15 (GCC 4.6.0)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
"i686-redhat-linux", "", "", triple);
// Fedora 14
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.1",
"i686-redhat-linux", "", "", triple);
// RHEL5(gcc44)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
"x86_64-redhat-linux6E", "32", "", triple);
// Fedora 13
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.4",
"i686-redhat-linux","", "", triple);
// Fedora 12
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"i686-redhat-linux","", "", triple);
// Fedora 12 (pre-FEB-2010)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.2",
"i686-redhat-linux","", "", triple);
// Fedora 11
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.1",
"i586-redhat-linux","", "", triple);
// Fedora 10
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.2",
"i386-redhat-linux","", "", triple);
// Fedora 9
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.0",
"i386-redhat-linux", "", "", triple);
// Fedora 8
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
"x86_64-redhat-linux", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.2",
"i386-redhat-linux", "", "", triple);
// RHEL 5
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1",
"x86_64-redhat-linux", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.1.1",
"i386-redhat-linux", "", "", triple);
//===------------------------------------------------------------------===//
// Exherbo (2010-01-25)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"x86_64-pc-linux-gnu", "32", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4.3",
"i686-pc-linux-gnu", "", "", triple);
// openSUSE 11.1 32 bit
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
"i586-suse-linux", "", "", triple);
// openSUSE 11.1 64 bit
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3",
"x86_64-suse-linux", "32", "", triple);
// openSUSE 11.2
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"i586-suse-linux", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.4",
"x86_64-suse-linux", "", "", triple);
// openSUSE 11.4
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
"i586-suse-linux", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5",
"x86_64-suse-linux", "", "", triple);
// openSUSE 12.1
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
"i586-suse-linux", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6",
"x86_64-suse-linux", "", "", triple);
// Arch Linux 2008-06-24
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
"i686-pc-linux-gnu", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3.1",
"x86_64-unknown-linux-gnu", "", "", triple);
// Arch Linux gcc 4.6
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
"i686-pc-linux-gnu", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.1",
"x86_64-unknown-linux-gnu", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
"i686-pc-linux-gnu", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.6.0",
"x86_64-unknown-linux-gnu", "", "", triple);
// Slackware gcc 4.5.2 (13.37)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.2",
"i486-slackware-linux", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.2",
"x86_64-slackware-linux", "", "", triple);
// Slackware gcc 4.5.3 (-current)
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.3",
"i486-slackware-linux", "", "", triple);
AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.5.3",
"x86_64-slackware-linux", "", "", triple);
// Gentoo x86 gcc 4.5.2
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.5.2/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 gcc 4.4.5
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.4.5/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 gcc 4.4.4
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.4.4/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 2010.0 stable
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.4.3/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 2009.1 stable
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 2009.0 stable
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 2008.0 stable
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/i686-pc-linux-gnu/4.1.2/include/g++-v4",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo x86 llvm-gcc trunk
AddGnuCPlusPlusIncludePaths(
"/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
"i686-pc-linux-gnu", "", "", triple);
// Gentoo amd64 gcc 4.5.2
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.2/include/g++-v4",
"x86_64-pc-linux-gnu", "32", "", triple);
// Gentoo amd64 gcc 4.4.5
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.5/include/g++-v4",
"x86_64-pc-linux-gnu", "32", "", triple);
// Gentoo amd64 gcc 4.4.4
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.4/include/g++-v4",
"x86_64-pc-linux-gnu", "32", "", triple);
// Gentoo amd64 gcc 4.4.3
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3/include/g++-v4",
"x86_64-pc-linux-gnu", "32", "", triple);
// Gentoo amd64 gcc 4.3.4
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/include/g++-v4",
"x86_64-pc-linux-gnu", "", "", triple);
// Gentoo amd64 gcc 4.3.2
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.2/include/g++-v4",
"x86_64-pc-linux-gnu", "", "", triple);
// Gentoo amd64 stable
AddGnuCPlusPlusIncludePaths(
"/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4",
"x86_64-pc-linux-gnu", "", "", triple);
// Gentoo amd64 llvm-gcc trunk
AddGnuCPlusPlusIncludePaths(
"/usr/lib/llvm-gcc-4.2-9999/include/c++/4.2.1",
"x86_64-pc-linux-gnu", "", "", triple);
break;
case llvm::Triple::FreeBSD:
// FreeBSD 8.0
@ -942,6 +443,19 @@ AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple, const HeaderSearchOp
void InitHeaderSearch::AddDefaultIncludePaths(const LangOptions &Lang,
const llvm::Triple &triple,
const HeaderSearchOptions &HSOpts) {
// NB: This code path is going away. All of the logic is moving into the
// driver which has the information necessary to do target-specific
// selections of default include paths. Each target which moves there will be
// exempted from this logic here until we can delete the entire pile of code.
switch (triple.getOS()) {
default:
break; // Everything else continues to use this routine's logic.
case llvm::Triple::Linux:
case llvm::Triple::Win32:
return;
}
if (Lang.CPlusPlus && HSOpts.UseStandardCXXIncludes &&
HSOpts.UseStandardSystemIncludes) {
if (HSOpts.UseLibcxx) {
@ -1144,8 +658,8 @@ void clang::ApplyHeaderSearchOptions(HeaderSearch &HS,
// Add the user defined entries.
for (unsigned i = 0, e = HSOpts.UserEntries.size(); i != e; ++i) {
const HeaderSearchOptions::Entry &E = HSOpts.UserEntries[i];
Init.AddPath(E.Path, E.Group, false, E.IsUserSupplied, E.IsFramework,
E.IgnoreSysRoot);
Init.AddPath(E.Path, E.Group, !E.ImplicitExternC, E.IsUserSupplied,
E.IsFramework, E.IgnoreSysRoot);
}
Init.AddDefaultIncludePaths(Lang, Triple, HSOpts);

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,experimental.cplusplus.Iterators -verify %s
// RUN: %clang --analyze -Xclang -analyzer-checker=core,experimental.cplusplus.Iterators -Xclang -verify %s
// XFAIL: win32
#include <vector>

View File

@ -170,7 +170,7 @@ void test_strcat() {
//===----------------------------------------------------------------------===
typedef int __int32_t;
typedef __int32_t pid_t;
pid_t vfork(void); //expected-warning{{declaration of built-in function 'vfork' requires inclusion of the header <setjmp.h>}}
pid_t vfork(void);
void test_vfork() {
vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process.}}

22
test/CodeGen/pr9614.c Normal file
View File

@ -0,0 +1,22 @@
// RUN: %clang_cc1 -emit-llvm %s -O1 -o - | FileCheck %s
extern void foo_alias (void) __asm ("foo");
inline void foo (void) {
return foo_alias ();
}
extern void bar_alias (void) __asm ("bar");
inline __attribute__ ((__always_inline__)) void bar (void) {
return bar_alias ();
}
void f(void) {
foo();
bar();
}
// CHECK: define void @f()
// CHECK: call void @foo()
// CHECK-NEXT: call void @bar()
// CHECK-NEXT: ret void
// CHECK: declare void @foo()
// CHECK: declare void @bar()

View File

@ -137,3 +137,11 @@
// CHECK-GCC-VERSION3: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-GCC-VERSION3: "{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5/crtbegin.o"
// CHECK-GCC-VERSION3: "-L{{.*}}/Inputs/gcc_version_parsing3/bin/../lib/gcc/i386-unknown-linux/4.7.99-rc5"
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
// RUN: -ccc-host-triple i386-unknown-linux -m32 \
// RUN: -ccc-install-dir %S/Inputs/gcc_version_parsing4/bin \
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
// RUN: | FileCheck --check-prefix=CHECK-GCC-VERSION4 %s
// CHECK-GCC-VERSION4: "{{.*}}ld{{(.exe)?}}" "--sysroot=[[SYSROOT:[^"]+]]"
// CHECK-GCC-VERSION4: "{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99/crtbegin.o"
// CHECK-GCC-VERSION4: "-L{{.*}}/Inputs/gcc_version_parsing4/bin/../lib/gcc/i386-unknown-linux/4.7.99"

View File

@ -1,6 +1,8 @@
// RUN: %clang_cc1 -emit-pch -o %t -relocatable-pch -isysroot %S/libroot %S/libroot/usr/include/reloc.h
// RUN: %clang_cc1 -include-pch %t -isysroot %S/libroot %s -verify
// RUN: not %clang_cc1 -include-pch %t %s
// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 --relocatable-pch -o %t \
// RUN: -isysroot %S/libroot %S/libroot/usr/include/reloc.h
// RUN: %clang -ccc-host-triple x86_64-apple-darwin10 -fsyntax-only \
// RUN: -include-pch %t -isysroot %S/libroot %s -Xclang -verify
// RUN: not %clang -ccc-host-triple x86_64-apple-darwin10 -include-pch %t %s
#include <reloc.h>
@ -8,7 +10,5 @@ int x = 2; // expected-error{{redefinition}}
int y = 5; // expected-error{{redefinition}}
// expected-note{{previous definition}}
// expected-note{{previous definition}}

View File

@ -1,2 +1,2 @@
// RUN: %clang -fno-ms-extensions %s -E | grep 'stddef.h.*3.*4'
// RUN: %clang -fno-ms-extensions %s -E | grep 'stddef.h.*3'
#include <stddef.h>

View File

@ -2,6 +2,9 @@
import os
import platform
import re
import subprocess
# Configuration file for the 'lit' test runner.
@ -141,7 +144,23 @@ if lit.useValgrind:
config.clang = inferClang(config.environment['PATH']).replace('\\', '/')
if not lit.quiet:
lit.note('using clang: %r' % config.clang)
config.substitutions.append( ('%clang_cc1', config.clang + ' -cc1') )
# Note that when substituting %clang_cc1 also fill in the include directory of
# the builtin headers. Those are part of even a freestanding environment, but
# Clang relies on the driver to locate them.
def getClangBuiltinIncludeDir(clang):
# FIXME: Rather than just getting the version, we should have clang print
# out its resource dir here in an easy to scrape form.
cmd = subprocess.Popen([clang, '-print-file-name=include'],
stdout=subprocess.PIPE)
if not cmd.stdout:
lit.fatal("Couldn't find the include dir for Clang ('%s')" % clang)
return cmd.stdout.read().strip()
config.substitutions.append( ('%clang_cc1', '%s -cc1 -internal-isystem %s'
% (config.clang,
getClangBuiltinIncludeDir(config.clang))) )
config.substitutions.append( ('%clangxx', ' ' + config.clang +
' -ccc-clang-cxx -ccc-cxx '))
config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
@ -175,10 +194,6 @@ if platform.system() not in ['Windows'] or lit.getBashPath() != '':
config.available_features.add('shell')
# Registered Targets
import subprocess
import re
import os
def getRegisteredTargets(tool):
set_of_targets = set()