From clattner at apple.com Mon Mar 30 00:55:19 2009 From: clattner at apple.com (Chris Lattner) Date: Sun, 29 Mar 2009 22:55:19 -0700 Subject: [cfe-commits] r68021 - /cfe/trunk/lib/Sema/SemaOverload.cpp In-Reply-To: <200903292246.n2TMkO6o018591@zion.cs.uiuc.edu> References: <200903292246.n2TMkO6o018591@zion.cs.uiuc.edu> Message-ID: <9C39A9E8-A673-4FEE-9C38-20DF16B7D5EA@apple.com> On Mar 29, 2009, at 3:46 PM, Sebastian Redl wrote: > URL: http://llvm.org/viewvc/llvm-project?rev=68021&view=rev > Log: > Hopefully fix the rval regressions. Thanks to Chris for pointing out > that valgrind complains. Works great for me, thanks Sebastian! -Chris From xuzhongxing at gmail.com Mon Mar 30 00:55:47 2009 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Mon, 30 Mar 2009 05:55:47 -0000 Subject: [cfe-commits] r68024 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRState.h include/clang/Analysis/PathSensitive/Store.h lib/Analysis/BasicStore.cpp lib/Analysis/GRExprEngine.cpp lib/Analysis/RegionStore.cpp Message-ID: <200903300555.n2U5tl3l005284@zion.cs.uiuc.edu> Author: zhongxingxu Date: Mon Mar 30 00:55:46 2009 New Revision: 68024 URL: http://llvm.org/viewvc/llvm-project?rev=68024&view=rev Log: Implement a FIXME. Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h cfe/trunk/include/clang/Analysis/PathSensitive/Store.h cfe/trunk/lib/Analysis/BasicStore.cpp cfe/trunk/lib/Analysis/GRExprEngine.cpp cfe/trunk/lib/Analysis/RegionStore.cpp Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h?rev=68024&r1=68023&r2=68024&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h (original) +++ cfe/trunk/include/clang/Analysis/PathSensitive/GRState.h Mon Mar 30 00:55:46 2009 @@ -461,7 +461,7 @@ return BindExpr(St, Ex, V, isBlkExpr, Invalidate); } - SVal ArrayToPointer(SVal Array) { + SVal ArrayToPointer(Loc Array) { return StoreMgr->ArrayToPointer(Array); } Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Store.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Store.h?rev=68024&r1=68023&r2=68024&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/PathSensitive/Store.h (original) +++ cfe/trunk/include/clang/Analysis/PathSensitive/Store.h Mon Mar 30 00:55:46 2009 @@ -106,7 +106,7 @@ /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit /// conversions between arrays and pointers. - virtual SVal ArrayToPointer(SVal Array) = 0; + virtual SVal ArrayToPointer(Loc Array) = 0; class CastResult { Modified: cfe/trunk/lib/Analysis/BasicStore.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=68024&r1=68023&r2=68024&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/BasicStore.cpp (original) +++ cfe/trunk/lib/Analysis/BasicStore.cpp Mon Mar 30 00:55:46 2009 @@ -85,7 +85,7 @@ /// ArrayToPointer - Used by GRExprEngine::VistCast to handle implicit /// conversions between arrays and pointers. - SVal ArrayToPointer(SVal Array) { return Array; } + SVal ArrayToPointer(Loc Array) { return Array; } /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from /// a MemRegion* to a specific location type. 'R' is the region being Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=68024&r1=68023&r2=68024&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original) +++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Mon Mar 30 00:55:46 2009 @@ -1877,7 +1877,7 @@ // Check for casts from array type to another type. if (ExTy->isArrayType()) { // We will always decay to a pointer. - V = StateMgr.ArrayToPointer(V); + V = StateMgr.ArrayToPointer(cast(V)); // Are we casting from an array to a pointer? If so just pass on // the decayed value. Modified: cfe/trunk/lib/Analysis/RegionStore.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=68024&r1=68023&r2=68024&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/RegionStore.cpp (original) +++ cfe/trunk/lib/Analysis/RegionStore.cpp Mon Mar 30 00:55:46 2009 @@ -199,7 +199,7 @@ /// version of that lvalue (i.e., a pointer to the first element of /// the array). This is called by GRExprEngine when evaluating /// casts from arrays to pointers. - SVal ArrayToPointer(SVal Array); + SVal ArrayToPointer(Loc Array); /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from /// a MemRegion* to a specific location type. 'R' is the region being @@ -562,12 +562,7 @@ /// version of that lvalue (i.e., a pointer to the first element of /// the array). This is called by GRExprEngine when evaluating casts /// from arrays to pointers. -SVal RegionStoreManager::ArrayToPointer(SVal Array) { - // FIXME: This should be factored into GRExprEngine. This allows - // us to pass a "loc" instead of an "SVal" for "Array". - if (Array.isUnknownOrUndef()) - return Array; - +SVal RegionStoreManager::ArrayToPointer(Loc Array) { if (!isa(Array)) return UnknownVal(); From daniel at zuster.org Mon Mar 30 01:36:42 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 30 Mar 2009 06:36:42 -0000 Subject: [cfe-commits] r68027 - in /cfe/trunk: include/clang/Driver/ToolChain.h include/clang/Driver/Types.def lib/Driver/Driver.cpp lib/Driver/Tools.cpp test/Frontend/dependency-gen.c tools/clang-cc/DependencyFile.cpp Message-ID: <200903300636.n2U6agJg006816@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Mar 30 01:36:42 2009 New Revision: 68027 URL: http://llvm.org/viewvc/llvm-project?rev=68027&view=rev Log: Driver: Support -M and -MM. - Not particularly elegant, but my hand is forced by gcc. Also, tweak -ccc-print-bindings output. Modified: cfe/trunk/include/clang/Driver/ToolChain.h cfe/trunk/include/clang/Driver/Types.def cfe/trunk/lib/Driver/Driver.cpp cfe/trunk/lib/Driver/Tools.cpp cfe/trunk/test/Frontend/dependency-gen.c cfe/trunk/tools/clang-cc/DependencyFile.cpp Modified: cfe/trunk/include/clang/Driver/ToolChain.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=68027&r1=68026&r2=68027&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/ToolChain.h (original) +++ cfe/trunk/include/clang/Driver/ToolChain.h Mon Mar 30 01:36:42 2009 @@ -54,6 +54,10 @@ const std::string &getPlatform() const { return Platform; } const std::string &getOS() const { return OS; } + const std::string getTripleString() const { + return getArchName() + "-" + getPlatform() + "-" + getOS(); + } + path_list &getFilePaths() { return FilePaths; } const path_list &getFilePaths() const { return FilePaths; } Modified: cfe/trunk/include/clang/Driver/Types.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Types.def?rev=68027&r1=68026&r2=68027&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Types.def (original) +++ cfe/trunk/include/clang/Driver/Types.def Mon Mar 30 01:36:42 2009 @@ -74,4 +74,5 @@ TYPE("object", Object, INVALID, "o", "") TYPE("treelang", Treelang, INVALID, 0, "u") TYPE("image", Image, INVALID, "out", "") +TYPE("dependencies", Dependencies, INVALID, "d", "") TYPE("none", Nothing, INVALID, 0, "u") Modified: cfe/trunk/lib/Driver/Driver.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=68027&r1=68026&r2=68027&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Driver.cpp (original) +++ cfe/trunk/lib/Driver/Driver.cpp Mon Mar 30 01:36:42 2009 @@ -245,8 +245,7 @@ llvm::errs() << "clang version 1.0 (" << vers << " " << revision << ")" << "\n"; const ToolChain &TC = C.getDefaultToolChain(); - llvm::errs() << "Target: " << TC.getArchName() << '-' - << TC.getPlatform() << '-' << TC.getOS() << '\n'; + llvm::errs() << "Target: " << TC.getTripleString() << '\n'; } bool Driver::HandleImmediateArgs(const Compilation &C) { @@ -379,9 +378,6 @@ if (Archs.size() > 1) { // No recovery needed, the point of this is just to prevent // overwriting the same files. - if (const Arg *A = Args.getLastArg(options::OPT_M_Group)) - Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs) - << A->getAsString(Args); if (const Arg *A = Args.getLastArg(options::OPT_save_temps)) Diag(clang::diag::err_drv_invalid_opt_with_multiple_archs) << A->getAsString(Args); @@ -618,9 +614,15 @@ switch (Phase) { case phases::Link: assert(0 && "link action invalid here."); case phases::Preprocess: { - types::ID OutputTy = types::getPreprocessedType(Input->getType()); - assert(OutputTy != types::TY_INVALID && - "Cannot preprocess this input type!"); + types::ID OutputTy; + // -{M, MM} alter the output type. + if (Args.hasArg(options::OPT_M) || Args.hasArg(options::OPT_MM)) { + OutputTy = types::TY_Dependencies; + } else { + OutputTy = types::getPreprocessedType(Input->getType()); + assert(OutputTy != types::TY_INVALID && + "Cannot preprocess this input type!"); + } return new PreprocessJobAction(Input, OutputTy); } case phases::Precompile: @@ -848,7 +850,8 @@ } if (CCCPrintBindings) { - llvm::errs() << "bind - \"" << T.getName() << "\", inputs: ["; + llvm::errs() << "# \"" << T.getToolChain().getTripleString() << '"' + << " - \"" << T.getName() << "\", inputs: ["; for (unsigned i = 0, e = InputInfos.size(); i != e; ++i) { llvm::errs() << InputInfos[i].getAsString(); if (i + 1 != e) Modified: cfe/trunk/lib/Driver/Tools.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=68027&r1=68026&r2=68027&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Tools.cpp (original) +++ cfe/trunk/lib/Driver/Tools.cpp Mon Mar 30 01:36:42 2009 @@ -43,7 +43,10 @@ assert(JA.getType() == types::TY_Plist && "Invalid output type."); CmdArgs.push_back("-analyze"); } else if (isa(JA)) { - CmdArgs.push_back("-E"); + if (Output.getType() == types::TY_Dependencies) + CmdArgs.push_back("-Eonly"); + else + CmdArgs.push_back("-E"); } else if (isa(JA)) { // No special option needed, driven by -x. // @@ -218,7 +221,12 @@ (A = Args.getLastArg(options::OPT_MMD))) { // Determine the output location. const char *DepFile; - if (Arg *MF = Args.getLastArg(options::OPT_MF)) { + if (Output.getType() == types::TY_Dependencies) { + if (Output.isPipe()) + DepFile = "-"; + else + DepFile = Output.getFilename(); + } else if (Arg *MF = Args.getLastArg(options::OPT_MF)) { DepFile = MF->getValue(Args); } else if (A->getOption().getId() == options::OPT_M || A->getOption().getId() == options::OPT_MM) { @@ -234,8 +242,10 @@ if (!Args.hasArg(options::OPT_MT) && !Args.hasArg(options::OPT_MQ)) { const char *DepTarget; - // If user provided -o, that is the dependency target. - if (Arg *A = Args.getLastArg(options::OPT_o)) { + // If user provided -o, that is the dependency target, except + // when we are only generating a dependency file. + Arg *OutputOpt = Args.getLastArg(options::OPT_o); + if (OutputOpt && Output.getType() != types::TY_Dependencies) { DepTarget = A->getValue(Args); } else { // Otherwise derive from the base input. @@ -260,14 +270,9 @@ Args.AddLastArg(CmdArgs, options::OPT_MP); Args.AddAllArgs(CmdArgs, options::OPT_MT); - Arg *Unsupported = Args.getLastArg(options::OPT_M); - if (!Unsupported) - Unsupported = Args.getLastArg(options::OPT_MM); - if (!Unsupported) - Unsupported = Args.getLastArg(options::OPT_MG); - if (!Unsupported) - Unsupported = Args.getLastArg(options::OPT_MQ); - if (Unsupported) { + Arg *Unsupported; + if ((Unsupported = Args.getLastArg(options::OPT_MG)) || + (Unsupported = Args.getLastArg(options::OPT_MQ))) { const Driver &D = getToolChain().getHost().getDriver(); D.Diag(clang::diag::err_drv_unsupported_opt) << Unsupported->getOption().getName(); @@ -371,9 +376,8 @@ CmdArgs.push_back("-arch"); CmdArgs.push_back(getToolChain().getArchName().c_str()); - // FIXME: We should have a separate type for this. - if (Args.hasArg(options::OPT_M) || Args.hasArg(options::OPT_MM)) { - CmdArgs.push_back("-M"); + if (Output.getType() == types::TY_Dependencies) { + // Handled with other dependency code. } else if (Output.isPipe()) { CmdArgs.push_back("-o"); CmdArgs.push_back("-"); Modified: cfe/trunk/test/Frontend/dependency-gen.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/dependency-gen.c?rev=68027&r1=68026&r2=68027&view=diff ============================================================================== --- cfe/trunk/test/Frontend/dependency-gen.c (original) +++ cfe/trunk/test/Frontend/dependency-gen.c Mon Mar 30 01:36:42 2009 @@ -1,5 +1,7 @@ // rdar://6533411 // RUN: clang -MD -MF %t.d -c -x c -o %t.o /dev/null && - // RUN: grep '.*dependency-gen.c.out.tmp.o:' %t.d -// RUN: grep '/dev/null' %t.d +// RUN: grep '/dev/null' %t.d && + +// RUN: clang -M -x c /dev/null -o %t.deps && +// RUN: grep 'null.o: /dev/null' %t.deps Modified: cfe/trunk/tools/clang-cc/DependencyFile.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/DependencyFile.cpp?rev=68027&r1=68026&r2=68027&view=diff ============================================================================== --- cfe/trunk/tools/clang-cc/DependencyFile.cpp (original) +++ cfe/trunk/tools/clang-cc/DependencyFile.cpp Mon Mar 30 01:36:42 2009 @@ -91,11 +91,15 @@ } std::string ErrMsg; - llvm::raw_ostream *OS = - new llvm::raw_fd_ostream(DependencyFile.c_str(), false, ErrStr); - if (!ErrMsg.empty()) { - ErrStr = "unable to open dependency file: " + ErrMsg; - return false; + llvm::raw_ostream *OS; + if (DependencyFile == "-") { + OS = new llvm::raw_stdout_ostream(); + } else { + OS = new llvm::raw_fd_ostream(DependencyFile.c_str(), false, ErrStr); + if (!ErrMsg.empty()) { + ErrStr = "unable to open dependency file: " + ErrMsg; + return false; + } } DependencyFileCallback *PPDep = From xuzhongxing at gmail.com Mon Mar 30 01:48:57 2009 From: xuzhongxing at gmail.com (Zhongxing Xu) Date: Mon, 30 Mar 2009 06:48:57 -0000 Subject: [cfe-commits] r68028 - in /cfe/trunk: include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/MemRegion.cpp lib/Analysis/RegionStore.cpp Message-ID: <200903300648.n2U6mvLZ007301@zion.cs.uiuc.edu> Author: zhongxingxu Date: Mon Mar 30 01:48:56 2009 New Revision: 68028 URL: http://llvm.org/viewvc/llvm-project?rev=68028&view=rev Log: Make SymbolicRegion untyped. Layer the type information with a TypedViewRegion on top of the SymbolicRegion. Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h cfe/trunk/lib/Analysis/MemRegion.cpp cfe/trunk/lib/Analysis/RegionStore.cpp Modified: cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h?rev=68028&r1=68027&r2=68028&view=diff ============================================================================== --- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original) +++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Mon Mar 30 01:48:56 2009 @@ -39,10 +39,10 @@ class MemRegion : public llvm::FoldingSetNode { public: enum Kind { MemSpaceRegionKind, + SymbolicRegionKind, AllocaRegionKind, // Typed regions. BEG_TYPED_REGIONS, - SymbolicRegionKind, CompoundLiteralRegionKind, StringRegionKind, ElementRegionKind, TypedViewRegionKind, @@ -179,21 +179,18 @@ /// either a real region, a NULL pointer, etc. It essentially is used to /// map the concept of symbolic values into the domain of regions. Symbolic /// regions do not need to be typed. -class SymbolicRegion : public TypedRegion { +class SymbolicRegion : public SubRegion { protected: const SymbolRef sym; public: SymbolicRegion(const SymbolRef s, const MemRegion* sreg) - : TypedRegion(sreg, SymbolicRegionKind), sym(s) {} + : SubRegion(sreg, SymbolicRegionKind), sym(s) {} SymbolRef getSymbol() const { return sym; } - QualType getRValueType(ASTContext& C) const; - QualType getLValueType(ASTContext& C) const; - void Profile(llvm::FoldingSetNodeID& ID) const; static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym); Modified: cfe/trunk/lib/Analysis/MemRegion.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/MemRegion.cpp?rev=68028&r1=68027&r2=68028&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/MemRegion.cpp (original) +++ cfe/trunk/lib/Analysis/MemRegion.cpp Mon Mar 30 01:48:56 2009 @@ -111,28 +111,6 @@ // getLValueType() and getRValueType() //===----------------------------------------------------------------------===// -QualType SymbolicRegion::getRValueType(ASTContext& C) const { - // Get the type of the symbol. - QualType T = sym->getType(C); - - if (const PointerType* PTy = T->getAsPointerType()) - return PTy->getPointeeType(); - - if (const BlockPointerType* PTy = T->getAsBlockPointerType()) - return PTy->getPointeeType(); - - // There is no rvalue type of id<...>. - if (T->getAsObjCQualifiedIdType()) - return QualType(); - - assert(Loc::IsLocType(T) && "Non-location type."); - return QualType(); -} - -QualType SymbolicRegion::getLValueType(ASTContext& C) const { - return sym->getType(C); -} - QualType ElementRegion::getRValueType(ASTContext& C) const { // Strip off typedefs from the ArrayRegion's RvalueType. QualType T = getArrayRegion()->getRValueType(C)->getDesugaredType(); Modified: cfe/trunk/lib/Analysis/RegionStore.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=68028&r1=68027&r2=68028&view=diff ============================================================================== --- cfe/trunk/lib/Analysis/RegionStore.cpp (original) +++ cfe/trunk/lib/Analysis/RegionStore.cpp Mon Mar 30 01:48:56 2009 @@ -362,9 +362,13 @@ BaseR = cast(BaseL).getRegion(); break; - case loc::SymbolValKind: - BaseR = MRMgr.getSymbolicRegion(cast(&BaseL)->getSymbol()); + case loc::SymbolValKind: { + SymbolRef Sym = cast(&BaseL)->getSymbol(); + const SymbolicRegion* SR = MRMgr.getSymbolicRegion(Sym); + // Layer the type information. + BaseR = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); break; + } case loc::GotoLabelKind: case loc::FuncValKind: @@ -407,9 +411,14 @@ const TypedRegion* BaseRegion = 0; - BaseRegion = isa(Base) - ? MRMgr.getSymbolicRegion(cast(Base).getSymbol()) - : cast(cast(Base).getRegion()); + if (isa(Base)) { + SymbolRef Sym = cast(Base).getSymbol(); + SymbolicRegion* SR = MRMgr.getSymbolicRegion(Sym); + // Layer the type information. + BaseRegion = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); + } + else + BaseRegion = cast(cast(Base).getRegion()); // Pointer of any type can be cast and used as array base. const ElementRegion *ElemR = dyn_cast(BaseRegion); From daniel at zuster.org Mon Mar 30 01:49:41 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 30 Mar 2009 06:49:41 -0000 Subject: [cfe-commits] r68029 - /cfe/trunk/test/Driver/bindings.c Message-ID: <200903300649.n2U6nfuV007340@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Mar 30 01:49:40 2009 New Revision: 68029 URL: http://llvm.org/viewvc/llvm-project?rev=68029&view=rev Log: Missed test case update (part of previous commit) Modified: cfe/trunk/test/Driver/bindings.c Modified: cfe/trunk/test/Driver/bindings.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/bindings.c?rev=68029&r1=68028&r2=68029&view=diff ============================================================================== --- cfe/trunk/test/Driver/bindings.c (original) +++ cfe/trunk/test/Driver/bindings.c Mon Mar 30 01:49:40 2009 @@ -1,56 +1,56 @@ // Basic binding. // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings %s 2> %t && -// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t && -// RUN: grep 'bind - "gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && -// RUN: grep 'bind - "gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && +// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t && +// RUN: grep '"gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && +// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang %s 2> %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[".*bindings.c"\], output: ".*\.s"' %t && -// RUN: grep 'bind - "gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && -// RUN: grep 'bind - "gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && +// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: ".*\.s"' %t && +// RUN: grep '"gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && +// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -no-integrated-cpp %s 2> %t && -// RUN: grep 'bind - "gcc::Preprocess", inputs: \[".*bindings.c"\], output: ".*\.i"' %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[".*\.i"\], output: ".*\.s"' %t && -// RUN: grep 'bind - "gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && -// RUN: grep 'bind - "gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && +// RUN: grep '"gcc::Preprocess", inputs: \[".*bindings.c"\], output: ".*\.i"' %t && +// RUN: grep '"gcc::Compile", inputs: \[".*\.i"\], output: ".*\.s"' %t && +// RUN: grep '"gcc::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && +// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -no-integrated-cpp -pipe %s 2> %t && -// RUN: grep 'bind - "gcc::Preprocess", inputs: \[".*bindings.c"\], output: (pipe)' %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[(pipe)\], output: (pipe)' %t && -// RUN: grep 'bind - "gcc::Assemble", inputs: \[(pipe)\], output: ".*\.o"' %t && -// RUN: grep 'bind - "gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && +// RUN: grep '"gcc::Preprocess", inputs: \[".*bindings.c"\], output: (pipe)' %t && +// RUN: grep '"gcc::Compile", inputs: \[(pipe)\], output: (pipe)' %t && +// RUN: grep '"gcc::Assemble", inputs: \[(pipe)\], output: ".*\.o"' %t && +// RUN: grep '"gcc::Link", inputs: \[".*\.o"\], output: "a.out"' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -x c-header %s 2> %t && -// RUN: grep 'bind - "gcc::Precompile", inputs: \[".*bindings.c"\], output: ".*bindings.c.gch' %t && +// RUN: grep '"gcc::Precompile", inputs: \[".*bindings.c"\], output: ".*bindings.c.gch' %t && // Clang control options // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -fsyntax-only %s 2> %t && -// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: (nothing)' %t && +// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang -fsyntax-only %s 2> %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t && +// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -fsyntax-only -x c++ %s 2> %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t && +// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-clang-cxx -fsyntax-only -x c++ %s 2> %t && -// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: (nothing)' %t && +// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-unknown-unknown -ccc-print-bindings -ccc-no-clang-cpp -fsyntax-only -no-integrated-cpp %s 2> %t && -// RUN: grep 'bind - "gcc::Preprocess", inputs: \[".*bindings.c"\], output: ".*\.i"' %t && -// RUN: grep 'bind - "clang", inputs: \[".*\.i"\], output: (nothing)' %t && +// RUN: grep '"gcc::Preprocess", inputs: \[".*bindings.c"\], output: ".*\.i"' %t && +// RUN: grep '"clang", inputs: \[".*\.i"\], output: (nothing)' %t && // RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs i386 %s -S -arch ppc 2> %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && +// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && // RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings -ccc-clang-archs ppc %s -S -arch ppc 2> %t && -// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && +// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && // RUN: clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings -ccc-clang-archs "" %s -S 2> %t && -// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && +// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && // RUN: clang -ccc-host-triple powerpc-unknown-unknown -ccc-print-bindings %s -S 2> %t && -// RUN: grep 'bind - "gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && +// RUN: grep '"gcc::Compile", inputs: \[".*bindings.c"\], output: "bindings.s"' %t && // Darwin bindings // RUN: clang -ccc-host-triple i386-apple-darwin9 -ccc-print-bindings %s 2> %t && -// RUN: grep 'bind - "clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t && -// RUN: grep 'bind - "darwin::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && -// RUN: grep 'bind - "darwin::Link", inputs: \[".*\.o"\], output: "a.out"' %t && +// RUN: grep '"clang", inputs: \[".*bindings.c"\], output: ".*\.s"' %t && +// RUN: grep '"darwin::Assemble", inputs: \[".*\.s"\], output: ".*\.o"' %t && +// RUN: grep '"darwin::Link", inputs: \[".*\.o"\], output: "a.out"' %t && // RUN: true From daniel at zuster.org Mon Mar 30 01:50:02 2009 From: daniel at zuster.org (Daniel Dunbar) Date: Mon, 30 Mar 2009 06:50:02 -0000 Subject: [cfe-commits] r68030 - in /cfe/trunk/docs: DriverArchitecture.png DriverInternals.html InternalsManual.html Message-ID: <200903300650.n2U6o2O5007367@zion.cs.uiuc.edu> Author: ddunbar Date: Mon Mar 30 01:50:01 2009 New Revision: 68030 URL: http://llvm.org/viewvc/llvm-project?rev=68030&view=rev Log: Some very rough Driver documentation. Added: cfe/trunk/docs/DriverArchitecture.png (with props) cfe/trunk/docs/DriverInternals.html Modified: cfe/trunk/docs/InternalsManual.html Added: cfe/trunk/docs/DriverArchitecture.png URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/DriverArchitecture.png?rev=68030&view=auto ============================================================================== Binary file - no diff available. Propchange: cfe/trunk/docs/DriverArchitecture.png ------------------------------------------------------------------------------ svn:mime-type = application/octet-stream Added: cfe/trunk/docs/DriverInternals.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/DriverInternals.html?rev=68030&view=auto ============================================================================== --- cfe/trunk/docs/DriverInternals.html (added) +++ cfe/trunk/docs/DriverInternals.html Mon Mar 30 01:50:01 2009 @@ -0,0 +1,510 @@ + + + Clang Driver Manual + + + + + + + + +
+ +

Driver Design & Internals

+ + + + + +

Introduction

+ + +

This document describes the Clang driver. The purpose of this + document is to describe both the motivation and design goals + for the driver, as well as details of the internal + implementation.

+ + +

Features and Goals

+ + +

The Clang driver is intended to be a production quality + compiler driver providing access to the Clang compiler and + tools, with a command line interface which is compatible with + the gcc driver.

+ +

Although the driver is part of and driven by the Clang + project, it is logically a separate tool which shares many of + the same goals as Clang:

+ +

Features:

+ + + +

GCC Compatibility

+ + +

The number one goal of the driver is to ease the adoption of + Clang by allowing users to drop Clang into a build system + which was designed to call GCC. Although this makes the driver + much more complicated than might otherwise be necessary, we + decided that being very compatible with the gcc command line + interface was worth it in order to allow users to quickly test + clang on their projects.

+ + +

Flexible

+ + +

The driver was designed to be flexible and easily accomodate + new uses as we grow the clang and LLVM infrastructure. As one + example, the driver can easily support the introduction of + tools which have an integrated assembler; something we hope to + add to LLVM in the future.

+ +

Similarly, most of the driver functionality is kept in a + library which can be used to build other tools which want to + implement or accept a gcc like interface.

+ + +

Low Overhead

+ + +

The driver should have as little overhead as possible. In + practice, we found that the gcc driver by itself incurred a + small but meaningful overhead when compiling many small + files. The driver doesn't do much work compared to a + compilation, but we have tried to keep it as efficient as + possible by following a few simple principles:

+
    +
  • Avoid memory allocation and string copying when + possible.
  • + +
  • Don't parse arguments more than once.
  • + +
  • Provide a few simple interfaces for effienctly searching + arguments.
  • +
+ + +

Simple

+ + +

Finally, the driver was designed to be "as simple as + possible", given the other goals. Notably, trying to be + completely compatible with the gcc driver adds a significant + amount of complexity. However, the design of the driver + attempts to mitigate this complexity by dividing the process + into a number of independent stages instead of a single + monolithic task.

+ + +

Internal Design and Implementation

+ + + + + +

Internals Introduction

+ + +

In order to satisfy the stated goals, the driver was designed + to completely subsume the functionality of the gcc executable; + that is, the driver should not need to delegate to gcc to + perform subtasks. On Darwin, this implies that the Clang + driver also subsumes the gcc driver-driver, which is used to + implement support for building universal images (binaries and + object files). This also implies that the driver should be + able to call the language specific compilers (e.g. cc1) + directly, which means that it must have enough information to + forward command line arguments to child processes + correctly.

+ + +

Design Overview

+ + +

The diagram below shows the significant components of the + driver architecture and how they relate to one another. The + orange components represent concrete data structures built by + the driver, the green components indicate conceptually + distinct stages which manipulate these data structures, and + the blue components are important helper classes.

+ +
+ + + +
+ + +

Driver Stages

+ + +

The driver functionality is conceptually divided into five stages:

+ +
    +
  1. + Parse: Option Parsing + +

    The command line argument strings are decomposed into + arguments (Arg instances). The driver expects to + understand all available options, although there is some + facility for just passing certain classes of options + through (like -Wl,).

    + +

    Each argument corresponds to exactly one + abstract Option definition, which describes how + the option is parsed along with some additional + metadata. The Arg instances themselves are lightweight and + merely contain enough information for clients to determine + which option they correspond to and their values (if they + have additional parameters).

    + +

    For example, a command line like "-Ifoo -I foo" would + parse to two Arg instances (a JoinedArg and a SeparateArg + instance), but each would refer to the same Option.

    + +

    Options are lazily created in order to avoid populating + all Option classes when the driver is loaded. Most of the + driver code only needs to deal with options by their + unique ID (e.g., options::OPT_I),

    + +

    Arg instances themselves do not generally store the + values of parameters. In almost all cases, this would + simply result in creating unnecessary string + copies. Instead, Arg instances are always embedded inside + an ArgList structure, which contains the original vector + of argument strings. Each Arg itself can then only contain + an index into this vector instead of storing its values + directly.

    + +

    The current clang driver can dump the results of this + stage using the -ccc-print-options flag (which + must preceed any actual command line arguments). For + example:

    +
    +            $ clang -ccc-print-options -Xarch_i386 -fomit-frame-pointer -Wa,-fast -Ifoo -I foo t.c
    +            Option 0 - Name: "-Xarch_", Values: {"i386", "-fomit-frame-pointer"}
    +            Option 1 - Name: "-Wa,", Values: {"-fast"}
    +            Option 2 - Name: "-I", Values: {"foo"}
    +            Option 3 - Name: "-I", Values: {"foo"}
    +            Option 4 - Name: "<input>", Values: {"t.c"}
    +          
    + +

    After this stage is complete the command line should be + broken down into well defined option objects with their + appropriate parameters. Subsequent stages should rarely, + if ever, need to do any string processing.

    +
  2. + +
  3. + Pipeline: Compilation Job Construction + +

    Once the arguments are parsed, the tree of subprocess + jobs needed for the desired compilation sequence are + constructed. This involves determing the input files and + their types, what work is to be done on them (preprocess, + compile, assemble, link, etc.), and constructing a list of + Action instances for each task. The result is a list of + one or more top-level actions, each of which generally + corresponds to a single output (for example, an object or + linked executable).

    + +

    The majority of Actions correspond to actual tasks, + however there are two special Actions. The first is + InputAction, which simply serves to adapt an input + argument for use as an input to other Actions. The second + is BindArchAction, which conceptually alters the + architecture to be used for all of its input Actions.

    + +

    The current clang driver can dump the results of this + stage using the -ccc-print-phases flag. For + example:

    +
    +            $ clang -ccc-print-phases -x c t.c -x assembler t.s
    +            0: input, "t.c", c
    +            1: preprocessor, {0}, cpp-output
    +            2: compiler, {1}, assembler
    +            3: assembler, {2}, object
    +            4: input, "t.s", assembler
    +            5: assembler, {4}, object
    +            6: linker, {3, 5}, image
    +          
    +

    Here the driver is constructing sevent distinct actions, + four to compile the "t.c" input into an object file, two to + assemble the "t.s" input, and one to link them together.

    + +

    A rather different compilation pipeline is shown here; in + this example there are two top level actions to compile + the input files into two separate object files, where each + object file is built using lipo to merge results + built for two separate architectures.

    +
    +            $ clang -ccc-print-phases -c -arch i386 -arch x86_64 t0.c t1.c
    +            0: input, "t0.c", c
    +            1: preprocessor, {0}, cpp-output
    +            2: compiler, {1}, assembler
    +            3: assembler, {2}, object
    +            4: bind-arch, "i386", {3}, object
    +            5: bind-arch, "x86_64", {3}, object
    +            6: lipo, {4, 5}, object
    +            7: input, "t1.c", c
    +            8: preprocessor, {7}, cpp-output
    +            9: compiler, {8}, assembler
    +            10: assembler, {9}, object
    +            11: bind-arch, "i386", {10}, object
    +            12: bind-arch, "x86_64", {10}, object
    +            13: lipo, {11, 12}, object
    +          
    + +

    After this stage is complete the compilation process is + divided into a simple set of actions which need to be + performed to produce intermediate or final outputs (in + some cases, like -fsyntax-only, there is no + "real" final output). Phases are well known compilation + steps, such as "preprocess", "compile", "assemble", + "link", etc.

    +
  4. + +
  5. + Bind: Tool & Filename Selection + +

    The stage (in conjunction with the Translate stage) turns + the tree of Actions into a list of actual subprocess to + run. Conceptually, the driver performs a simple tree match + to assign Action(s) to Tools. Once an Action has been + bound to a Tool, the driver interacts with the tool to + determine how the Tools should be connected (via pipes, + temporary files, or user provided filenames) and whether + the tool supports things like an integrated + preprocessor.

    + +

    The driver interacts with a ToolChain to perform the Tool + bindings. Each ToolChain contains information about all + the tools needed for compilation for a particular + architecture, platform, and operating system. A single + driver may query multiple ToolChains during a single + compilation in order to interact with tools for separate + architectures.

    + +

    The results of this stage are not computed directly, but + the driver can print the results via + the -ccc-print-bindings option. For example:

    +
    +            $ clang -ccc-print-bindings -arch i386 -arch ppc t0.c
    +            # "i386-apple-darwin10.0.0d6" - "clang", inputs: ["t0.c"], output: "/tmp/cc-Sn4RKF.s"
    +            # "i386-apple-darwin10.0.0d6" - "darwin::Assemble", inputs: ["/tmp/cc-Sn4RKF.s"], output: "/tmp/cc-gvSnbS.o"
    +            # "i386-apple-darwin10.0.0d6" - "darwin::Link", inputs: ["/tmp/cc-gvSnbS.o"], output: "/tmp/cc-jgHQxi.out"
    +            # "ppc-apple-darwin10.0.0d6" - "gcc::Compile", inputs: ["t0.c"], output: "/tmp/cc-Q0bTox.s"
    +            # "ppc-apple-darwin10.0.0d6" - "gcc::Assemble", inputs: ["/tmp/cc-Q0bTox.s"], output: "/tmp/cc-WCdicw.o"
    +            # "ppc-apple-darwin10.0.0d6" - "gcc::Link", inputs: ["/tmp/cc-WCdicw.o"], output: "/tmp/cc-HHBEBh.out"
    +            # "i386-apple-darwin10.0.0d6" - "darwin::Lipo", inputs: ["/tmp/cc-jgHQxi.out", "/tmp/cc-HHBEBh.out"], output: "a.out"
    +          
    + +

    This shows the tool chain, tool, inputs and outputs which + have been bound for this compilation sequence. Here clang + is being used to compile t0.c on the i386 architecture and + darwin specific versions of the tools are being used to + assemble and link the result, but generic gcc versions of + the tools are being used on PowerPC.

    +
  6. + +
  7. + Translate: Tool Specific Argument Translation + +

    Once a Tool has been selected to perform a particular + Action, the Tool must construct concrete Jobs which will be + executed during compilation. The main work is in translating + from the gcc style command line options to whatever options + the subprocess expects.

    + +

    Some tools, such as the assembler, only interact with a + handful of arguments and just determine the path of the + executable to call and pass on their input and output + arguments. Others, like the compiler or the linker, may + translate a large number of arguments in addition.

    + +

    The ArgList class provides a number of simple helper + methods to assist with translating arguments; for example, + to pass on only the last of arguments corresponding to some + option, or all arguments for an option.

    + +

    The result of this stage is a list of Jobs (executable + paths and argument strings) to execute.

    +
  8. + +
  9. + Execute +

    Finally, the compilation pipeline is executed. This is + mostly straightforward, although there is some interaction + with options + like -pipe, -pass-exit-codes + and -time.

    +
  10. + +
+ + +

Additional Notes

+ + +

The Compilation Object

+ +

The driver constructs a Compilation object for each set of + command line arguments. The Driver itself is intended to be + invariant during construct of a Compilation; an IDE should be + able to construct a single long lived driver instance to use + for an entire build, for example.

+ +

The Compilation object holds information that is particular + to each compilation sequence. For example, the list of used + temporary files (which must be removed once compilation is + finished) and result files (which should be removed if + compilation files).

+ +

Unified Parsing & Pipelining

+ +

Parsing and pipeling both occur without reference to a + Compilation instance. This is by design; the driver expects that + both of these phases are platform neutral, with a few very well + defined exceptions such as whether the platform uses a driver + driver.

+ +

ToolChain Argument Translation

+ +

In order to match gcc very closely, the clang driver + currently allows tool chains to perform their own translation of + the argument list (into a new ArgList data structure). Although + this allows the clang driver to match gcc easily, it also makes + the driver operation much harder to understand (since the Tools + stop seeing some arguments the user provided, and see new ones + instead).

+ +

For example, on Darwin -gfull gets translated into + two separate arguments, -g + and -fno-eliminate-unused-debug-symbols. Trying to + write Tool logic to do something with -gfull will not + work, because at Tools run after the arguments have been + translated.

+ +

A long term goal is to remove this tool chain specific + translation, and instead force each tool to change its own logic + to do the right thing on the untranslated original arguments.

+ +

Unused Argument Warnings

+

The driver operates by parsing all arguments but giving Tools + the opportunity to choose which arguments to pass on. One + downside of this infrastructure is that if the user misspells + some option, or is confused about which options to use, some + command line arguments the user really cared about may go + unused. This problem is particularly important when using + clang as a compiler, since the clang compiler does not support + anywhere all the options that gcc does, and we want to make + sure users know which ones are being used.

+ +

To support this, the driver maintains a bit associated with + each argument of whether it has been used (at all) during the + compilation. This bit usually doesn't need to be set by hand, + as the key ArgList accessors will set it automatically.

+ +

When a compilation is successfull (there are no errors), the + driver checks the bit and emits an "unused argument" warning for + any arguments which were never accessed. This is conservative + (the argument may not have been used to do what the user wanted) + but still catches the most obvious cases.

+ + +

Relation to GCC Driver Concepts

+ + +

For those familiar with the gcc driver, this section provides + a brief overview of how things from the gcc driver map to the + clang driver.

+ +
    +
  • + Driver Driver +

    The driver driver is fully integrated into the clang + driver. The driver simply constructs additional Actions to + bind the architecture during the Pipeline + phase. The tool chain specific argument translation is + responsible for handling -Xarch_.

    + +

    The one caveat is that this approach + requires -Xarch_ not be used to alter the + compilation itself (for example, one cannot + provide -S as an -Xarch_ argument). The + driver attempts to reject such invocations, and overall + there isn't a good reason to abuse -Xarch_ to + that end in practice.

    + +

    The upside is that the clang driver is more efficient and + does little extra work to support universal builds. It also + provides better error reporting and UI consistency.

    +
  • + +
  • + Specs +

    The clang driver has no direct correspondant for + "specs". The majority of the functionality that is + embedded in specs is in the Tool specific argument + translation routines. The parts of specs which control the + compilation pipeline are generally part of + the Pipeline stage.

    +
  • + +
  • + Toolchains +

    The gcc driver has no direct understanding of tool + chains. Each gcc binary roughly corresponds to the + information which is embedded inside a single + ToolChain.

    + +

    The clang driver is intended to be portable and support + complex compilation environments. All platform and tool + chain specific code should be protected behind either + abstract or well defined interfaces (such as whether the + platform supports use as a driver driver).

    +
  • +
+
+ + Modified: cfe/trunk/docs/InternalsManual.html URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/InternalsManual.html?rev=68030&r1=68029&r2=68030&view=diff ============================================================================== --- cfe/trunk/docs/InternalsManual.html (original) +++ cfe/trunk/docs/InternalsManual.html Mon Mar 30 01:50:01 2009 @@ -27,6 +27,14 @@ classes +
  • The Driver Library +
      +
    +
  • +
  • The Frontend Library +
      +
    +
  • The Lexer and Preprocessor Library