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.
+
+
+
+
+
+
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
+
+
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
+
+
+
+
The driver functionality is conceptually divided into five stages:
+
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+ 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.
+
+
+
+ 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 .
+
+
+
+
+
+
+
+
+
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.
+
+
+
+
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.
+
+
+
+
+
+
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
The Token class
@@ -532,6 +540,20 @@
This concept maps directly to the "spelling location" for the token.
+The Driver Library
+
+
+The clang Driver and library are documented here .
+
+
+
The Frontend Library
+
+
+The Frontend library contains functionality useful for building
+tools on top of the clang libraries, for example several methods for
+outputting diagnostics.
+
+
The Lexer and Preprocessor Library
From dgregor at apple.com Mon Mar 30 11:49:57 2009
From: dgregor at apple.com (Douglas Gregor)
Date: Mon, 30 Mar 2009 09:49:57 -0700
Subject: [cfe-commits] r67962 - in /cfe/trunk:
include/clang/AST/DeclCXX.h include/clang/AST/DeclNodes.def
lib/AST/DeclCXX.cpp lib/Sema/SemaDeclCXX.cpp
In-Reply-To: <200903282258.n2SMw2hd031330@zion.cs.uiuc.edu>
References: <200903282258.n2SMw2hd031330@zion.cs.uiuc.edu>
Message-ID:
On Mar 28, 2009, at 3:58 PM, Anders Carlsson wrote:
> Author: andersca
> Date: Sat Mar 28 17:58:02 2009
> New Revision: 67962
>
> URL: http://llvm.org/viewvc/llvm-project?rev=67962&view=rev
> Log:
> Create AST nodes for namespace aliases.
>
> Modified:
> cfe/trunk/include/clang/AST/DeclCXX.h
> cfe/trunk/include/clang/AST/DeclNodes.def
> cfe/trunk/lib/AST/DeclCXX.cpp
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=67962&r1=67961&r2=67962&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Mar 28 17:58:02 2009
> @@ -953,6 +953,46 @@
> friend class DeclContext;
> };
>
> +class NamespaceAliasDecl : public NamedDecl {
Some documentation, please? With an example of C++ source code that
would result in this declaration?
- Doug
> + SourceLocation AliasLoc;
> +
> + /// IdentLoc - Location of namespace identifier.
> + /// FIXME: We don't store location of scope specifier.
> + SourceLocation IdentLoc;
The typical way to store this information now would be to store a
SourceRange covering the nested-name-specifier along with a
NestedNameSpecifier*.
- Doug
From mrs at apple.com Mon Mar 30 12:44:51 2009
From: mrs at apple.com (Mike Stump)
Date: Mon, 30 Mar 2009 17:44:51 -0000
Subject: [cfe-commits] r68039 - /cfe/tags/Apple/clang/clang/Makefile
Message-ID: <200903301744.n2UHiptn014112@zion.cs.uiuc.edu>
Author: mrs
Date: Mon Mar 30 12:44:51 2009
New Revision: 68039
URL: http://llvm.org/viewvc/llvm-project?rev=68039&view=rev
Log:
Add ccc back for now.
Modified:
cfe/tags/Apple/clang/clang/Makefile
Modified: cfe/tags/Apple/clang/clang/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/tags/Apple/clang/clang/Makefile?rev=68039&r1=68038&r2=68039&view=diff
==============================================================================
--- cfe/tags/Apple/clang/clang/Makefile (original)
+++ cfe/tags/Apple/clang/clang/Makefile Mon Mar 30 12:44:51 2009
@@ -56,7 +56,7 @@
ifeq ($(MAKECMDGOALS),install-clang)
DIRS := tools/clang/tools/driver tools/clang/tools/clang-cc \
- tools/clang/lib/Headers
+ tools/clang/lib/Headers tools/clang/tools/ccc
OPTIONAL_DIRS :=
NO_INSTALL = 1
endif
From mrs at apple.com Mon Mar 30 12:45:42 2009
From: mrs at apple.com (Mike Stump)
Date: Mon, 30 Mar 2009 17:45:42 -0000
Subject: [cfe-commits] r68040 - /cfe/tags/Apple/clang-5/
Message-ID: <200903301745.n2UHjgMh014164@zion.cs.uiuc.edu>
Author: mrs
Date: Mon Mar 30 12:45:42 2009
New Revision: 68040
URL: http://llvm.org/viewvc/llvm-project?rev=68040&view=rev
Log:
Tag.
Added:
cfe/tags/Apple/clang-5/
- copied from r68039, cfe/tags/Apple/clang/
From kremenek at apple.com Mon Mar 30 12:53:06 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 17:53:06 -0000
Subject: [cfe-commits] r68041 - in /cfe/trunk:
include/clang/Analysis/PathSensitive/GRExprEngine.h
lib/Analysis/GRExprEngine.cpp
Message-ID: <200903301753.n2UHr6iJ014412@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 12:53:05 2009
New Revision: 68041
URL: http://llvm.org/viewvc/llvm-project?rev=68041&view=rev
Log:
Add version of GRExprEngine::AddCheck that registered a GRSimpleAPICheck that
will be called for every expression in a basic block.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
cfe/trunk/lib/Analysis/GRExprEngine.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=68041&r1=68040&r2=68041&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Mon Mar 30 12:53:05 2009
@@ -395,6 +395,7 @@
}
void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C);
+ void AddCheck(GRSimpleAPICheck* A);
/// ProcessStmt - Called by GRCoreEngine. Used to generate new successor
/// nodes by processing the 'effects' of a block-level statement.
Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=68041&r1=68040&r2=68041&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Mon Mar 30 12:53:05 2009
@@ -46,9 +46,11 @@
MapTy M;
Checks::Factory F;
+ Checks AllStmts;
public:
- MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) : F(Alloc) {}
+ MappedBatchAuditor(llvm::BumpPtrAllocator& Alloc) :
+ F(Alloc), AllStmts(F.GetEmptyList()) {}
virtual ~MappedBatchAuditor() {
llvm::DenseSet AlreadyVisited;
@@ -66,26 +68,33 @@
}
}
- void AddCheck(GRSimpleAPICheck* A, Stmt::StmtClass C) {
+ void AddCheck(GRSimpleAPICheck *A, Stmt::StmtClass C) {
assert (A && "Check cannot be null.");
void* key = reinterpret_cast((uintptr_t) C);
MapTy::iterator I = M.find(key);
M[key] = F.Concat(A, I == M.end() ? F.GetEmptyList() : I->second);
}
+
+ void AddCheck(GRSimpleAPICheck *A) {
+ assert (A && "Check cannot be null.");
+ AllStmts = F.Concat(A, AllStmts);
+ }
virtual bool Audit(NodeTy* N, GRStateManager& VMgr) {
+ // First handle the auditors that accept all statements.
+ bool isSink = false;
+ for (Checks::iterator I = AllStmts.begin(), E = AllStmts.end(); I!=E; ++I)
+ isSink |= (*I)->Audit(N, VMgr);
+
+ // Next handle the auditors that accept only specific statements.
Stmt* S = cast(N->getLocation()).getStmt();
void* key = reinterpret_cast((uintptr_t) S->getStmtClass());
MapTy::iterator MI = M.find(key);
-
- if (MI == M.end())
- return false;
-
- bool isSink = false;
+ if (MI != M.end()) {
+ for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
+ isSink |= (*I)->Audit(N, VMgr);
+ }
- for (Checks::iterator I=MI->second.begin(), E=MI->second.end(); I!=E; ++I)
- isSink |= (*I)->Audit(N, VMgr);
-
return isSink;
}
};
@@ -143,6 +152,13 @@
((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A, C);
}
+void GRExprEngine::AddCheck(GRSimpleAPICheck *A) {
+ if (!BatchAuditor)
+ BatchAuditor.reset(new MappedBatchAuditor(getGraph().getAllocator()));
+
+ ((MappedBatchAuditor*) BatchAuditor.get())->AddCheck(A);
+}
+
const GRState* GRExprEngine::getInitialState() {
return StateMgr.getInitialState();
}
From daniel at zuster.org Mon Mar 30 12:59:59 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 30 Mar 2009 17:59:59 -0000
Subject: [cfe-commits] r68042 - in /cfe/trunk: lib/Driver/Tools.cpp
test/Frontend/dependency-gen.c
Message-ID: <200903301800.n2UI00R8015056@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Mar 30 12:59:58 2009
New Revision: 68042
URL: http://llvm.org/viewvc/llvm-project?rev=68042&view=rev
Log:
Fix -MD with no -MT when -o is specified (and fix test case).
Modified:
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/test/Frontend/dependency-gen.c
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=68042&r1=68041&r2=68042&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Mon Mar 30 12:59:58 2009
@@ -246,7 +246,7 @@
// 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);
+ DepTarget = OutputOpt->getValue(Args);
} else {
// Otherwise derive from the base input.
//
Modified: cfe/trunk/test/Frontend/dependency-gen.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/dependency-gen.c?rev=68042&r1=68041&r2=68042&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/dependency-gen.c (original)
+++ cfe/trunk/test/Frontend/dependency-gen.c Mon Mar 30 12:59:58 2009
@@ -1,6 +1,6 @@
// 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 '.*dependency-gen.c.out.tmp.o:' %t.d &&
// RUN: grep '/dev/null' %t.d &&
// RUN: clang -M -x c /dev/null -o %t.deps &&
From fjahanian at apple.com Mon Mar 30 13:02:14 2009
From: fjahanian at apple.com (Fariborz Jahanian)
Date: Mon, 30 Mar 2009 18:02:14 -0000
Subject: [cfe-commits] r68043 - /cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
Message-ID: <200903301802.n2UI2Ejs015137@zion.cs.uiuc.edu>
Author: fjahanian
Date: Mon Mar 30 13:02:14 2009
New Revision: 68043
URL: http://llvm.org/viewvc/llvm-project?rev=68043&view=rev
Log:
Use CodeGenModule API for ObjC runtime function references.
Patch by David Chisnall.
Modified:
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=68043&r1=68042&r2=68043&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Mon Mar 30 13:02:14 2009
@@ -204,9 +204,12 @@
llvm::Value *ClassName = CGM.GetAddrOfConstantCString(OID->getNameAsString());
ClassName = Builder.CreateStructGEP(ClassName, 0);
+ std::vector Params(1, PtrToInt8Ty);
llvm::Constant *ClassLookupFn =
- TheModule.getOrInsertFunction("objc_lookup_class", IdTy, PtrToInt8Ty,
- NULL);
+ CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy,
+ Params,
+ true),
+ "objc_lookup_class");
return Builder.CreateCall(ClassLookupFn, ClassName);
}
@@ -304,11 +307,14 @@
CGF.Builder.CreateStore(ReceiverClass, CGF.Builder.CreateStructGEP(ObjCSuper, 1));
// Get the IMP
+ std::vector Params;
+ Params.push_back(llvm::PointerType::getUnqual(ObjCSuperTy));
+ Params.push_back(SelectorTy);
llvm::Constant *lookupFunction =
- TheModule.getOrInsertFunction("objc_msg_lookup_super",
- llvm::PointerType::getUnqual(impType),
- llvm::PointerType::getUnqual(ObjCSuperTy),
- SelectorTy, NULL);
+ CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+ llvm::PointerType::getUnqual(impType), Params, true),
+ "objc_msg_lookup_super");
+
llvm::Value *lookupArgs[] = {ObjCSuper, cmd};
llvm::Value *imp = CGF.Builder.CreateCall(lookupFunction, lookupArgs,
lookupArgs+2);
@@ -338,10 +344,14 @@
const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs);
const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, false);
+ std::vector Params;
+ Params.push_back(Receiver->getType());
+ Params.push_back(SelectorTy);
llvm::Constant *lookupFunction =
- TheModule.getOrInsertFunction("objc_msg_lookup",
- llvm::PointerType::getUnqual(impType),
- Receiver->getType(), SelectorTy, NULL);
+ CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+ llvm::PointerType::getUnqual(impType), Params, true),
+ "objc_msg_lookup");
+
llvm::Value *imp = CGF.Builder.CreateCall2(lookupFunction, Receiver, cmd);
return CGF.EmitCall(FnInfo, imp, ActualArgs);
@@ -939,8 +949,11 @@
llvm::BasicBlock *EntryBB = llvm::BasicBlock::Create("entry", LoadFunction);
CGBuilderTy Builder;
Builder.SetInsertPoint(EntryBB);
- llvm::Value *Register = TheModule.getOrInsertFunction("__objc_exec_class",
- llvm::Type::VoidTy, llvm::PointerType::getUnqual(ModuleTy), NULL);
+
+ std::vector Params(1,
+ llvm::PointerType::getUnqual(ModuleTy));
+ llvm::Value *Register = CGM.CreateRuntimeFunction(llvm::FunctionType::get(
+ llvm::Type::VoidTy, Params, true), "__objc_exec_class");
Builder.CreateCall(Register, Module);
Builder.CreateRetVoid();
return LoadFunction;
@@ -977,9 +990,10 @@
}
llvm::Function *CGObjCGNU::EnumerationMutationFunction() {
-return
- (llvm::Function*)TheModule.getOrInsertFunction(
- "objc_enumerationMutation", llvm::Type::VoidTy, IdTy, NULL);
+ std::vector Params(1, IdTy);
+ return cast(CGM.CreateRuntimeFunction(
+ llvm::FunctionType::get(llvm::Type::VoidTy, Params, true),
+ "objc_enumerationMutation"));
}
void CGObjCGNU::EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF,
From daniel at zuster.org Mon Mar 30 13:13:27 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 30 Mar 2009 18:13:27 -0000
Subject: [cfe-commits] r68044 - in /cfe/trunk: lib/Driver/ArgList.cpp
test/Driver/flags.c
Message-ID: <200903301813.n2UIDRAA015501@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Mar 30 13:13:26 2009
New Revision: 68044
URL: http://llvm.org/viewvc/llvm-project?rev=68044&view=rev
Log:
Driver: Unbreak ArgList::hasFlag.
- [driver] clang does not have -msoft-float
hooked up.
Added:
cfe/trunk/test/Driver/flags.c
Modified:
cfe/trunk/lib/Driver/ArgList.cpp
Modified: cfe/trunk/lib/Driver/ArgList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ArgList.cpp?rev=68044&r1=68043&r2=68044&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ArgList.cpp (original)
+++ cfe/trunk/lib/Driver/ArgList.cpp Mon Mar 30 13:13:26 2009
@@ -51,7 +51,7 @@
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
Arg *PosA = getLastArg(Pos);
- Arg *NegA = getLastArg(Pos);
+ Arg *NegA = getLastArg(Neg);
if (PosA && NegA)
return NegA->getIndex() < PosA->getIndex();
if (PosA) return true;
Added: cfe/trunk/test/Driver/flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/flags.c?rev=68044&view=auto
==============================================================================
--- cfe/trunk/test/Driver/flags.c (added)
+++ cfe/trunk/test/Driver/flags.c Mon Mar 30 13:13:26 2009
@@ -0,0 +1,9 @@
+// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S -msoft-float %s 2> %t.log &&
+// RUN: grep '"--soft-float"' %t.log &&
+
+// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S -msoft-float -mno-soft-float %s 2> %t.log &&
+// RUN: grep '"--soft-float"' %t.log | count 0 &&
+
+// RUN: clang -ccc-host-triple i386-apple-darwin9 -### -S -mno-soft-float %s -msoft-float 2> %t.log &&
+// RUN: grep '"--soft-float"' %t.log
+
From dgregor at apple.com Mon Mar 30 13:22:51 2009
From: dgregor at apple.com (Douglas Gregor)
Date: Mon, 30 Mar 2009 18:22:51 -0000
Subject: [cfe-commits] r68045 -
/cfe/trunk/include/clang/AST/NestedNameSpecifier.h
Message-ID: <200903301822.n2UIMpfw015894@zion.cs.uiuc.edu>
Author: dgregor
Date: Mon Mar 30 13:22:51 2009
New Revision: 68045
URL: http://llvm.org/viewvc/llvm-project?rev=68045&view=rev
Log:
Remove a trivial FIXME
Modified:
cfe/trunk/include/clang/AST/NestedNameSpecifier.h
Modified: cfe/trunk/include/clang/AST/NestedNameSpecifier.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/NestedNameSpecifier.h?rev=68045&r1=68044&r2=68045&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/NestedNameSpecifier.h (original)
+++ cfe/trunk/include/clang/AST/NestedNameSpecifier.h Mon Mar 30 13:22:51 2009
@@ -24,7 +24,6 @@
namespace clang {
class ASTContext;
-class DeclContext; // FIXME: die die die
class NamespaceDecl;
class IdentifierInfo;
class Type;
From kremenek at apple.com Mon Mar 30 13:29:28 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 18:29:28 -0000
Subject: [cfe-commits] r68046 - /cfe/trunk/test/Analysis/uninit-vals.c
Message-ID: <200903301829.n2UITSaP016312@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 13:29:27 2009
New Revision: 68046
URL: http://llvm.org/viewvc/llvm-project?rev=68046&view=rev
Log:
Add another uninitialized values test case illustrating that the CFG correctly
handles declarations with multiple variables.
Modified:
cfe/trunk/test/Analysis/uninit-vals.c
Modified: cfe/trunk/test/Analysis/uninit-vals.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals.c?rev=68046&r1=68045&r2=68046&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals.c (original)
+++ cfe/trunk/test/Analysis/uninit-vals.c Mon Mar 30 13:29:27 2009
@@ -44,3 +44,10 @@
x += y; // expected-warning {{use of uninitialized variable}}
}
}
+
+int f8(int j) {
+ int x = 1, y = x + 1;
+ if (y) // no-warning
+ return x;
+ return y;
+}
From kremenek at apple.com Mon Mar 30 13:39:15 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 18:39:15 -0000
Subject: [cfe-commits] r68048 - /cfe/trunk/lib/Analysis/BugReporter.cpp
Message-ID: <200903301839.n2UIdFYp016750@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 13:39:15 2009
New Revision: 68048
URL: http://llvm.org/viewvc/llvm-project?rev=68048&view=rev
Log:
Convert use of loc::SymbolVal and nonloc::SymbolVal to V.getAsSymbol(). This
also makes this code more correct as it transparently handles SVals that wrapped
TypedViewRegions(SymbolicRegions).
Modified:
cfe/trunk/lib/Analysis/BugReporter.cpp
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=68048&r1=68047&r2=68048&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Mon Mar 30 13:39:15 2009
@@ -537,18 +537,11 @@
PathDiagnostic& pd, BugReporter& br)
: Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {}
- bool HandleBinding(StoreManager& SMgr, Store store,
- const MemRegion* R, SVal V) {
+ bool HandleBinding(StoreManager& SMgr, Store store, const MemRegion* R,
+ SVal V) {
+
+ SymbolRef ScanSym = V.getAsSymbol();
- SymbolRef ScanSym = 0;
-
- if (loc::SymbolVal* SV = dyn_cast(&V))
- ScanSym = SV->getSymbol();
- else if (nonloc::SymbolVal* SV = dyn_cast(&V))
- ScanSym = SV->getSymbol();
- else
- return true;
-
if (ScanSym != Sym)
return true;
From kremenek at apple.com Mon Mar 30 13:45:36 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 18:45:36 -0000
Subject: [cfe-commits] r68049 - /cfe/trunk/lib/Analysis/GRState.cpp
Message-ID: <200903301845.n2UIjarS016964@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 13:45:36 2009
New Revision: 68049
URL: http://llvm.org/viewvc/llvm-project?rev=68049&view=rev
Log:
Simplify more code by using SVal::getAsSymbol() instead of
loc::SymbolVal/nonloc::SymbolVal probing.
Modified:
cfe/trunk/lib/Analysis/GRState.cpp
Modified: cfe/trunk/lib/Analysis/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRState.cpp?rev=68049&r1=68048&r2=68049&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/GRState.cpp (original)
+++ cfe/trunk/lib/Analysis/GRState.cpp Mon Mar 30 13:45:36 2009
@@ -243,12 +243,9 @@
bool ScanReachableSymbols::scan(SVal val) {
if (loc::MemRegionVal *X = dyn_cast(&val))
return scan(X->getRegion());
-
- if (loc::SymbolVal *X = dyn_cast(&val))
- return visitor.VisitSymbol(X->getSymbol());
-
- if (nonloc::SymbolVal *X = dyn_cast(&val))
- return visitor.VisitSymbol(X->getSymbol());
+
+ if (SymbolRef Sym = val.getAsSymbol())
+ return visitor.VisitSymbol(Sym);
if (nonloc::CompoundVal *X = dyn_cast(&val))
return scan(*X);
@@ -304,12 +301,9 @@
if (nonloc::ConcreteInt* X = dyn_cast(&V))
return X->getValue() == Y;
- if (nonloc::SymbolVal* X = dyn_cast(&V))
- return ConstraintMgr->isEqual(state, X->getSymbol(), Y);
-
- if (loc::SymbolVal* X = dyn_cast(&V))
- return ConstraintMgr->isEqual(state, X->getSymbol(), Y);
-
+ if (SymbolRef Sym = V.getAsSymbol())
+ return ConstraintMgr->isEqual(state, Sym, Y);
+
return false;
}
From kremenek at apple.com Mon Mar 30 14:53:37 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 19:53:37 -0000
Subject: [cfe-commits] r68052 - in /cfe/trunk/lib/Analysis: BasicStore.cpp
BugReporter.cpp CheckNSError.cpp
Message-ID: <200903301953.n2UJrcsl019604@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 14:53:37 2009
New Revision: 68052
URL: http://llvm.org/viewvc/llvm-project?rev=68052&view=rev
Log:
Simplify more code by using SVal::getAsSymbol().
Modified:
cfe/trunk/lib/Analysis/BasicStore.cpp
cfe/trunk/lib/Analysis/BugReporter.cpp
cfe/trunk/lib/Analysis/CheckNSError.cpp
Modified: cfe/trunk/lib/Analysis/BasicStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BasicStore.cpp?rev=68052&r1=68051&r2=68052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BasicStore.cpp (original)
+++ cfe/trunk/lib/Analysis/BasicStore.cpp Mon Mar 30 14:53:37 2009
@@ -239,7 +239,7 @@
// FIXME: Should we have symbolic regions be typed or typeless?
// Here we assume that these regions are typeless, even though the
// symbol is typed.
- SymbolRef Sym = cast(&BaseL)->getSymbol();
+ SymbolRef Sym = BaseL.getAsSymbol();
// Create a region to represent this symbol.
// FIXME: In the future we may just use symbolic regions instead of
// SymbolVals to reason about symbolic memory chunks.
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=68052&r1=68051&r2=68052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Mon Mar 30 14:53:37 2009
@@ -635,17 +635,12 @@
bool HandleBinding(StoreManager& SMgr, Store store,
const MemRegion* R, SVal V) {
- SymbolRef ScanSym = 0;
-
- if (loc::SymbolVal* SV = dyn_cast(&V))
- ScanSym = SV->getSymbol();
- else if (nonloc::SymbolVal* SV = dyn_cast(&V))
- ScanSym = SV->getSymbol();
- else
+
+ SymbolRef ScanSym = V.getAsSymbol();
+
+ if (!ScanSym)
return true;
- assert (ScanSym);
-
if (!BR.isNotable(ScanSym))
return true;
Modified: cfe/trunk/lib/Analysis/CheckNSError.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckNSError.cpp?rev=68052&r1=68051&r2=68052&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CheckNSError.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckNSError.cpp Mon Mar 30 14:53:37 2009
@@ -194,11 +194,11 @@
assert (ParamR && "Parameters always have VarRegions.");
SVal ParamSVal = rootState.GetSVal(ParamR);
-
// FIXME: For now assume that ParamSVal is symbolic. We need to generalize
// this later.
- loc::SymbolVal* SV = dyn_cast(&ParamSVal);
- if (!SV) return;
+ SymbolRef ParamSym = ParamSVal.getAsLocSymbol();
+ if (!ParamSym)
+ return;
// Iterate over the implicit-null dereferences.
for (GRExprEngine::null_deref_iterator I=Eng.implicit_null_derefs_begin(),
@@ -206,13 +206,11 @@
GRStateRef state = GRStateRef((*I)->getState(), Eng.getStateManager());
const SVal* X = state.get();
- const loc::SymbolVal* SVX = dyn_cast_or_null(X);
- if (!SVX || SVX->getSymbol() != SV->getSymbol()) continue;
- // Emit an error.
-
-
+ if (!X || X->getAsSymbol() != ParamSym)
+ continue;
+ // Emit an error.
std::string sbuf;
llvm::raw_string_ostream os(sbuf);
os << "Potential null dereference. According to coding standards ";
From fjahanian at apple.com Mon Mar 30 15:32:06 2009
From: fjahanian at apple.com (Fariborz Jahanian)
Date: Mon, 30 Mar 2009 20:32:06 -0000
Subject: [cfe-commits] r68058 - /cfe/trunk/lib/CodeGen/CGDecl.cpp
Message-ID: <200903302032.n2UKW6je021508@zion.cs.uiuc.edu>
Author: fjahanian
Date: Mon Mar 30 15:32:06 2009
New Revision: 68058
URL: http://llvm.org/viewvc/llvm-project?rev=68058&view=rev
Log:
Code gen does not yet supports __asm__ on a variable
declaration. Reject it.
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=68058&r1=68057&r2=68058&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Mar 30 15:32:06 2009
@@ -60,6 +60,9 @@
/// EmitBlockVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitBlockVarDecl(const VarDecl &D) {
+ if (D.getAttr())
+ CGM.ErrorUnsupported(&D, "__asm__");
+
switch (D.getStorageClass()) {
case VarDecl::Static:
return EmitStaticBlockVarDecl(D);
From daniel at zuster.org Mon Mar 30 16:06:07 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 30 Mar 2009 21:06:07 -0000
Subject: [cfe-commits] r68061 - in /cfe/trunk:
include/clang/Driver/HostInfo.h lib/Driver/Driver.cpp
lib/Driver/HostInfo.cpp lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h
Message-ID: <200903302106.n2UL68kI023339@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Mar 30 16:06:03 2009
New Revision: 68061
URL: http://llvm.org/viewvc/llvm-project?rev=68061&view=rev
Log:
Driver: Sketch FreeBSD tool chain.
- Patch by Ed Schouten!
Modified:
cfe/trunk/include/clang/Driver/HostInfo.h
cfe/trunk/lib/Driver/Driver.cpp
cfe/trunk/lib/Driver/HostInfo.cpp
cfe/trunk/lib/Driver/ToolChains.cpp
cfe/trunk/lib/Driver/ToolChains.h
Modified: cfe/trunk/include/clang/Driver/HostInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/HostInfo.h?rev=68061&r1=68060&r2=68061&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/HostInfo.h (original)
+++ cfe/trunk/include/clang/Driver/HostInfo.h Mon Mar 30 16:06:03 2009
@@ -67,6 +67,8 @@
const HostInfo *createDarwinHostInfo(const Driver &D, const char *Arch,
const char *Platform, const char *OS);
+const HostInfo *createFreeBSDHostInfo(const Driver &D, const char *Arch,
+ const char *Platform, const char *OS);
const HostInfo *createUnknownHostInfo(const Driver &D, const char *Arch,
const char *Platform, const char *OS);
Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=68061&r1=68060&r2=68061&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Mon Mar 30 16:06:03 2009
@@ -999,6 +999,9 @@
if (memcmp(&OS[0], "darwin", 6) == 0)
return createDarwinHostInfo(*this, Arch.c_str(), Platform.c_str(),
OS.c_str());
+ if (memcmp(&OS[0], "freebsd", 7) == 0)
+ return createFreeBSDHostInfo(*this, Arch.c_str(), Platform.c_str(),
+ OS.c_str());
return createUnknownHostInfo(*this, Arch.c_str(), Platform.c_str(),
OS.c_str());
Modified: cfe/trunk/lib/Driver/HostInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/HostInfo.cpp?rev=68061&r1=68060&r2=68061&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/HostInfo.cpp (original)
+++ cfe/trunk/lib/Driver/HostInfo.cpp Mon Mar 30 16:06:03 2009
@@ -205,6 +205,68 @@
return TC;
}
+// FreeBSD Host Info
+
+/// FreeBSDHostInfo - Similar to UnknownHostInfo, but doesn't depend on
+class FreeBSDHostInfo : public HostInfo {
+ /// Cache of tool chains we have created.
+ mutable llvm::StringMap ToolChains;
+
+public:
+ FreeBSDHostInfo(const Driver &D, const char *Arch,
+ const char *Platform, const char *OS);
+ ~FreeBSDHostInfo();
+
+ virtual bool useDriverDriver() const;
+
+ virtual types::ID lookupTypeForExtension(const char *Ext) const {
+ return types::lookupTypeForExtension(Ext);
+ }
+
+ virtual ToolChain *getToolChain(const ArgList &Args,
+ const char *ArchName) const;
+};
+
+FreeBSDHostInfo::FreeBSDHostInfo(const Driver &D, const char *Arch,
+ const char *Platform, const char *OS)
+ : HostInfo(D, Arch, Platform, OS) {
+}
+
+FreeBSDHostInfo::~FreeBSDHostInfo() {
+ for (llvm::StringMap::iterator
+ it = ToolChains.begin(), ie = ToolChains.end(); it != ie; ++it)
+ delete it->second;
+}
+
+bool FreeBSDHostInfo::useDriverDriver() const {
+ return false;
+}
+
+ToolChain *FreeBSDHostInfo::getToolChain(const ArgList &Args,
+ const char *ArchName) const {
+ bool Lib32 = false;
+
+ assert(!ArchName &&
+ "Unexpected arch name on platform without driver driver support.");
+
+ // On x86_64 we need to be able to compile 32-bits binaries as well.
+ // Compiling 64-bit binaries on i386 is not supported. We don't have a
+ // lib64.
+ ArchName = getArchName().c_str();
+ if (Args.hasArg(options::OPT_m32) && getArchName() == "x86_64") {
+ ArchName = "i386";
+ Lib32 = true;
+ }
+
+ ToolChain *&TC = ToolChains[ArchName];
+ if (!TC)
+ TC = new toolchains::FreeBSD(*this, ArchName,
+ getPlatformName().c_str(),
+ getOSName().c_str(), Lib32);
+
+ return TC;
+}
+
}
const HostInfo *clang::driver::createDarwinHostInfo(const Driver &D,
@@ -214,6 +276,13 @@
return new DarwinHostInfo(D, Arch, Platform, OS);
}
+const HostInfo *clang::driver::createFreeBSDHostInfo(const Driver &D,
+ const char *Arch,
+ const char *Platform,
+ const char *OS) {
+ return new FreeBSDHostInfo(D, Arch, Platform, OS);
+}
+
const HostInfo *clang::driver::createUnknownHostInfo(const Driver &D,
const char *Arch,
const char *Platform,
Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=68061&r1=68060&r2=68061&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Mon Mar 30 16:06:03 2009
@@ -367,3 +367,32 @@
DerivedArgList *Generic_GCC::TranslateArgs(InputArgList &Args) const {
return new DerivedArgList(Args, true);
}
+
+/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
+
+FreeBSD::FreeBSD(const HostInfo &Host, const char *Arch,
+ const char *Platform, const char *OS, bool Lib32)
+ : Generic_GCC(Host, Arch, Platform, OS) {
+ if (Lib32)
+ getFilePaths().push_back(getHost().getDriver().Dir + "/../lib32");
+ else
+ getFilePaths().push_back(getHost().getDriver().Dir + "/../lib");
+}
+
+Tool &FreeBSD::SelectTool(const Compilation &C, const JobAction &JA) const {
+ Action::ActionClass Key;
+ if (getHost().getDriver().ShouldUseClangCompiler(C, JA, getArchName()))
+ Key = Action::AnalyzeJobClass;
+ else
+ Key = JA.getKind();
+
+ Tool *&T = Tools[Key];
+ if (!T) {
+ switch (Key) {
+ default:
+ T = &Generic_GCC::SelectTool(C, JA);
+ }
+ }
+
+ return *T;
+}
Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=68061&r1=68060&r2=68061&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Mon Mar 30 16:06:03 2009
@@ -26,6 +26,7 @@
/// all subcommands; this relies on gcc translating the majority of
/// command line options.
class VISIBILITY_HIDDEN Generic_GCC : public ToolChain {
+protected:
mutable llvm::DenseMap Tools;
public:
@@ -107,6 +108,14 @@
virtual const char *GetDefaultRelocationModel() const { return "pic"; }
};
+class VISIBILITY_HIDDEN FreeBSD : public Generic_GCC {
+public:
+ FreeBSD(const HostInfo &Host, const char *Arch, const char *Platform,
+ const char *OS, bool Lib32);
+
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA) const;
+};
+
} // end namespace toolchains
} // end namespace driver
} // end namespace clang
From eli.friedman at gmail.com Mon Mar 30 16:09:39 2009
From: eli.friedman at gmail.com (Eli Friedman)
Date: Mon, 30 Mar 2009 14:09:39 -0700
Subject: [cfe-commits] r68061 - in /cfe/trunk:
include/clang/Driver/HostInfo.h lib/Driver/Driver.cpp
lib/Driver/HostInfo.cpp lib/Driver/ToolChains.cpp
lib/Driver/ToolChains.h
In-Reply-To: <200903302106.n2UL68kI023339@zion.cs.uiuc.edu>
References: <200903302106.n2UL68kI023339@zion.cs.uiuc.edu>
Message-ID:
On Mon, Mar 30, 2009 at 2:06 PM, Daniel Dunbar wrote:
> +/// FreeBSDHostInfo - ?Similar to UnknownHostInfo, but doesn't depend on
Did a few words get cut off here?
-Eli
From eli.friedman at gmail.com Mon Mar 30 16:20:09 2009
From: eli.friedman at gmail.com (Eli Friedman)
Date: Mon, 30 Mar 2009 21:20:09 -0000
Subject: [cfe-commits] r68062 - in /cfe/trunk:
include/clang/Driver/Options.def tools/clang-cc/Warnings.cpp
Message-ID: <200903302120.n2ULKD7a023916@zion.cs.uiuc.edu>
Author: efriedma
Date: Mon Mar 30 16:19:48 2009
New Revision: 68062
URL: http://llvm.org/viewvc/llvm-project?rev=68062&view=rev
Log:
Implement -Wno-pointer-sign.
Modified:
cfe/trunk/include/clang/Driver/Options.def
cfe/trunk/tools/clang-cc/Warnings.cpp
Modified: cfe/trunk/include/clang/Driver/Options.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.def?rev=68062&r1=68061&r2=68062&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.def (original)
+++ cfe/trunk/include/clang/Driver/Options.def Mon Mar 30 16:19:48 2009
@@ -283,6 +283,7 @@
OPTION("-Wno-four-char-constants", Wno_four_char_constants, Flag, clang_ignored_W_Group, INVALID, "", 0)
OPTION("-Wno-missing-field-initializers", Wno_missing_field_initializers, Flag, clang_ignored_W_Group, INVALID, "", 0)
OPTION("-Wno-nonportable-cfstrings", Wno_nonportable_cfstrings, Joined, W_Group, INVALID, "", 0)
+OPTION("-Wno-pointer-sign", Wno_pointer_sign, Flag, clang_W_Group, INVALID, "", 0)
OPTION("-Wno-strict-selector-match", Wno_strict_selector_match, Flag, clang_W_Group, INVALID, "", 0)
OPTION("-Wno-trigraphs", Wno_trigraphs, Flag, clang_ignored_W_Group, INVALID, "", 0)
OPTION("-Wno-unknown-pragmas", Wno_unknown_pragmas, Flag, clang_ignored_W_Group, INVALID, "", 0)
Modified: cfe/trunk/tools/clang-cc/Warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-cc/Warnings.cpp?rev=68062&r1=68061&r2=68062&view=diff
==============================================================================
--- cfe/trunk/tools/clang-cc/Warnings.cpp (original)
+++ cfe/trunk/tools/clang-cc/Warnings.cpp Mon Mar 30 16:19:48 2009
@@ -136,6 +136,9 @@
static const diag::kind ImplicitFunctionDeclarationDiags[] = {
diag::ext_implicit_function_decl, diag::warn_implicit_function_decl
};
+static const diag::kind PointerSignDiags[] = {
+ diag::ext_typecheck_convert_incompatible_pointer_sign
+};
// Hmm ... this option is currently actually completely ignored.
//static const diag::kind StrictSelectorMatchDiags[] = { };
// Second the table of options. MUST be sorted by name! Binary lookup is done.
@@ -143,6 +146,7 @@
{ "float-equal", DIAGS(FloatEqualDiags) },
{ "format-nonliteral", DIAGS(FormatNonLiteralDiags) },
{ "implicit-function-declaration", DIAGS(ImplicitFunctionDeclarationDiags) },
+ { "pointer-sign", DIAGS(PointerSignDiags) },
{ "readonly-setter-attrs", DIAGS(ReadOnlySetterAttrsDiags) },
{ "undef", DIAGS(UndefDiags) },
{ "unused-macros", DIAGS(UnusedMacrosDiags) },
From ed at 80386.nl Mon Mar 30 16:21:16 2009
From: ed at 80386.nl (Ed Schouten)
Date: Mon, 30 Mar 2009 23:21:16 +0200
Subject: [cfe-commits] r68061 - in
/cfe/trunk: include/clang/Driver/HostInfo.h
lib/Driver/Driver.cpp lib/Driver/HostInfo.cpp
lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h
In-Reply-To:
References: <200903302106.n2UL68kI023339@zion.cs.uiuc.edu>
Message-ID: <20090330212116.GD73108@hoeg.nl>
* Eli Friedman wrote:
> On Mon, Mar 30, 2009 at 2:06 PM, Daniel Dunbar wrote:
> > +/// FreeBSDHostInfo - ?Similar to UnknownHostInfo, but doesn't depend on
>
> Did a few words get cut off here?
Only one:
Index: lib/Driver/HostInfo.cpp
===================================================================
--- lib/Driver/HostInfo.cpp (revision 68061)
+++ lib/Driver/HostInfo.cpp (working copy)
@@ -207,7 +207,7 @@
// FreeBSD Host Info
-/// FreeBSDHostInfo - Similar to UnknownHostInfo, but doesn't depend on
+/// FreeBSDHostInfo - Similar to UnknownHostInfo, but doesn't depend on GCC.
class FreeBSDHostInfo : public HostInfo {
/// Cache of tool chains we have created.
mutable llvm::StringMap ToolChains;
--
Ed Schouten
WWW: http://80386.nl/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
Url : http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20090330/a9f758e7/attachment.bin
From kremenek at apple.com Mon Mar 30 16:27:52 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 21:27:52 -0000
Subject: [cfe-commits] r68063 - in /cfe/trunk:
include/clang/Analysis/PathSensitive/SVals.h lib/Analysis/SVals.cpp
Message-ID: <200903302127.n2ULRr3J024153@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 16:27:41 2009
New Revision: 68063
URL: http://llvm.org/viewvc/llvm-project?rev=68063&view=rev
Log:
Remove dead code.
Modified:
cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
cfe/trunk/lib/Analysis/SVals.cpp
Modified: cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h?rev=68063&r1=68062&r2=68063&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/SVals.h Mon Mar 30 16:27:41 2009
@@ -208,15 +208,18 @@
class Loc : public SVal {
protected:
Loc(unsigned SubKind, const void* D)
- : SVal(const_cast(D), true, SubKind) {}
+ : SVal(const_cast(D), true, SubKind) {}
- // Equality operators.
- NonLoc EQ(SymbolManager& SM, const Loc& R) const;
- NonLoc NE(SymbolManager& SM, const Loc& R) const;
+// // Equality operators.
+// NonLoc EQ(SymbolManager& SM, Loc R) const;
+// NonLoc NE(SymbolManager& SM, Loc R) const;
public:
void print(llvm::raw_ostream& Out) const;
+ Loc(const Loc& X) : SVal(X.Data, true, X.getSubKind()) {}
+ Loc& operator=(const Loc& X) { memcpy(this, &X, sizeof(Loc)); return *this; }
+
static Loc MakeVal(const MemRegion* R);
static Loc MakeVal(AddrLabelExpr* E);
Modified: cfe/trunk/lib/Analysis/SVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/SVals.cpp?rev=68063&r1=68062&r2=68063&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/SVals.cpp (original)
+++ cfe/trunk/lib/Analysis/SVals.cpp Mon Mar 30 16:27:41 2009
@@ -201,109 +201,6 @@
return UndefinedVal();
}
-NonLoc Loc::EQ(SymbolManager& SymMgr, const Loc& R) const {
-
- switch (getSubKind()) {
- default:
- assert(false && "EQ not implemented for this Loc.");
- break;
-
- case loc::ConcreteIntKind:
- if (isa(R)) {
- bool b = cast(this)->getValue() ==
- cast(R).getValue();
-
- return NonLoc::MakeIntTruthVal(SymMgr.getBasicVals(), b);
- }
- else if (isa(R)) {
- const SymIntExpr *SE =
- SymMgr.getSymIntExpr(cast(R).getSymbol(),
- BinaryOperator::EQ,
- cast(this)->getValue(),
- SymMgr.getContext().IntTy);
-
- return nonloc::SymExprVal(SE);
- }
-
- break;
-
- case loc::SymbolValKind: {
- if (isa(R)) {
- const SymIntExpr *SE =
- SymMgr.getSymIntExpr(cast(this)->getSymbol(),
- BinaryOperator::EQ,
- cast(R).getValue(),
- SymMgr.getContext().IntTy);
-
- return nonloc::SymExprVal(SE);
- }
-
- assert (!isa(R) && "FIXME: Implement unification.");
- break;
- }
-
- case loc::MemRegionKind:
- if (isa(R)) {
- bool b = cast(*this) == cast(R);
- return NonLoc::MakeIntTruthVal(SymMgr.getBasicVals(), b);
- }
-
- break;
- }
-
- return NonLoc::MakeIntTruthVal(SymMgr.getBasicVals(), false);
-}
-
-NonLoc Loc::NE(SymbolManager& SymMgr, const Loc& R) const {
- switch (getSubKind()) {
- default:
- assert(false && "NE not implemented for this Loc.");
- break;
-
- case loc::ConcreteIntKind:
- if (isa(R)) {
- bool b = cast(this)->getValue() !=
- cast(R).getValue();
-
- return NonLoc::MakeIntTruthVal(SymMgr.getBasicVals(), b);
- }
- else if (isa(R)) {
- const SymIntExpr *SE =
- SymMgr.getSymIntExpr(cast(R).getSymbol(),
- BinaryOperator::NE,
- cast(this)->getValue(),
- SymMgr.getContext().IntTy);
- return nonloc::SymExprVal(SE);
- }
- break;
-
- case loc::SymbolValKind: {
- if (isa(R)) {
- const SymIntExpr *SE =
- SymMgr.getSymIntExpr(cast(this)->getSymbol(),
- BinaryOperator::NE,
- cast(R).getValue(),
- SymMgr.getContext().IntTy);
-
- return nonloc::SymExprVal(SE);
- }
-
- assert (!isa(R) && "FIXME: Implement sym !=.");
- break;
- }
-
- case loc::MemRegionKind:
- if (isa(R)) {
- bool b = cast(*this)==cast(R);
- return NonLoc::MakeIntTruthVal(SymMgr.getBasicVals(), b);
- }
-
- break;
- }
-
- return NonLoc::MakeIntTruthVal(SymMgr.getBasicVals(), true);
-}
-
//===----------------------------------------------------------------------===//
// Utility methods for constructing Non-Locs.
//===----------------------------------------------------------------------===//
From fjahanian at apple.com Mon Mar 30 16:33:57 2009
From: fjahanian at apple.com (Fariborz Jahanian)
Date: Mon, 30 Mar 2009 21:33:57 -0000
Subject: [cfe-commits] r68064 - /cfe/trunk/include/clang/AST/DeclObjC.h
Message-ID: <200903302133.n2ULXwLF024358@zion.cs.uiuc.edu>
Author: fjahanian
Date: Mon Mar 30 16:33:50 2009
New Revision: 68064
URL: http://llvm.org/viewvc/llvm-project?rev=68064&view=rev
Log:
Added new info to property impl. AST node to support
objc2's ivar synthesis.
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=68064&r1=68063&r2=68064&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Mar 30 16:33:50 2009
@@ -1091,6 +1091,7 @@
Dynamic
};
private:
+ unsigned IvarKind : 1;
SourceLocation AtLoc; // location of @synthesize or @dynamic
/// Property declaration being implemented
ObjCPropertyDecl *PropertyDecl;
@@ -1102,7 +1103,7 @@
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl)
- : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
+ : Decl(ObjCPropertyImpl, DC, L), IvarKind(false), AtLoc(atLoc),
PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
assert (PK == Dynamic || PropertyIvarDecl);
}
@@ -1127,6 +1128,16 @@
ObjCIvarDecl *getPropertyIvarDecl() const {
return PropertyIvarDecl;
}
+ void SetPropertyIvarDecl(ObjCIvarDecl *Ivar) {
+ assert(PropertyIvarDecl && "PropertyIvarDecl is already defined");
+ PropertyIvarDecl = Ivar;
+ }
+ void SetIvarSynthesized() {
+ IvarKind = true;
+ }
+ bool IsIvarSynthesized() const {
+ return IvarKind;
+ }
static bool classof(const Decl *D) {
return D->getKind() == ObjCPropertyImpl;
From kremenek at apple.com Mon Mar 30 16:45:46 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 14:45:46 -0700
Subject: [cfe-commits] r68001 -
/cfe/trunk/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h
In-Reply-To: <200903291635.n2TGZL3M028912@zion.cs.uiuc.edu>
References: <200903291635.n2TGZL3M028912@zion.cs.uiuc.edu>
Message-ID:
On Mar 29, 2009, at 9:35 AM, Chris Lattner wrote:
> Author: lattner
> Date: Sun Mar 29 11:35:09 2009
> New Revision: 68001
>
> URL: http://llvm.org/viewvc/llvm-project?rev=68001&view=rev
> Log:
> DeclRefExpr refers to one decl, not all the declarators in a
> declaration.
>
> Ted, please check this, this change causes no regression tests to
> fail.
Everything looks fine.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.cs.uiuc.edu/pipermail/cfe-commits/attachments/20090330/616552b0/attachment.html
From kremenek at apple.com Mon Mar 30 16:56:17 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 21:56:17 -0000
Subject: [cfe-commits] r68068 - in /cfe/trunk:
include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/MemRegion.cpp
lib/Analysis/RegionStore.cpp
Message-ID: <200903302156.n2ULuIXj025245@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 16:56:17 2009
New Revision: 68068
URL: http://llvm.org/viewvc/llvm-project?rev=68068&view=rev
Log:
Revert 68028.
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=68068&r1=68067&r2=68068&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Mon Mar 30 16:56:17 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,18 +179,21 @@
/// 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 SubRegion {
+class SymbolicRegion : public TypedRegion {
protected:
const SymbolRef sym;
public:
SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
- : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
+ : TypedRegion(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=68068&r1=68067&r2=68068&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Mon Mar 30 16:56:17 2009
@@ -111,6 +111,28 @@
// 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=68068&r1=68067&r2=68068&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Mon Mar 30 16:56:17 2009
@@ -362,13 +362,9 @@
BaseR = cast(BaseL).getRegion();
break;
- 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);
+ case loc::SymbolValKind:
+ BaseR = MRMgr.getSymbolicRegion(cast(&BaseL)->getSymbol());
break;
- }
case loc::GotoLabelKind:
case loc::FuncValKind:
@@ -411,14 +407,9 @@
const TypedRegion* BaseRegion = 0;
- 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());
+ BaseRegion = isa(Base)
+ ? MRMgr.getSymbolicRegion(cast(Base).getSymbol())
+ : 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 17:11:41 2009
From: daniel at zuster.org (Daniel Dunbar)
Date: Mon, 30 Mar 2009 22:11:41 -0000
Subject: [cfe-commits] r68069 - /cfe/trunk/lib/Driver/HostInfo.cpp
Message-ID: <200903302211.n2UMBf7I025670@zion.cs.uiuc.edu>
Author: ddunbar
Date: Mon Mar 30 17:11:38 2009
New Revision: 68069
URL: http://llvm.org/viewvc/llvm-project?rev=68069&view=rev
Log:
Comment fix.
Modified:
cfe/trunk/lib/Driver/HostInfo.cpp
Modified: cfe/trunk/lib/Driver/HostInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/HostInfo.cpp?rev=68069&r1=68068&r2=68069&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/HostInfo.cpp (original)
+++ cfe/trunk/lib/Driver/HostInfo.cpp Mon Mar 30 17:11:38 2009
@@ -207,7 +207,7 @@
// FreeBSD Host Info
-/// FreeBSDHostInfo - Similar to UnknownHostInfo, but doesn't depend on
+/// FreeBSDHostInfo - FreeBSD host information implementation.
class FreeBSDHostInfo : public HostInfo {
/// Cache of tool chains we have created.
mutable llvm::StringMap ToolChains;
From kremenek at apple.com Mon Mar 30 17:20:54 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 22:20:54 -0000
Subject: [cfe-commits] r68070 - in /cfe/trunk:
include/clang/Analysis/PathSensitive/MemRegion.h lib/Analysis/MemRegion.cpp
lib/Analysis/RegionStore.cpp
Message-ID: <200903302220.n2UMKsuH026041@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 17:20:54 2009
New Revision: 68070
URL: http://llvm.org/viewvc/llvm-project?rev=68070&view=rev
Log:
Re-apply 68028. The code had drifted enough that the tests would fail without
it. Will discuss offline whether symbolic regions should by typed or typeless.
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=68070&r1=68069&r2=68070&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/MemRegion.h Mon Mar 30 17:20:54 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=68070&r1=68069&r2=68070&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/MemRegion.cpp (original)
+++ cfe/trunk/lib/Analysis/MemRegion.cpp Mon Mar 30 17:20:54 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=68070&r1=68069&r2=68070&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Mon Mar 30 17:20:54 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 kremenek at apple.com Mon Mar 30 17:29:21 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Mon, 30 Mar 2009 22:29:21 -0000
Subject: [cfe-commits] r68072 - /cfe/trunk/lib/AST/CFG.cpp
Message-ID: <200903302229.n2UMTL5p026367@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 17:29:21 2009
New Revision: 68072
URL: http://llvm.org/viewvc/llvm-project?rev=68072&view=rev
Log:
Add partial CFG support for Objective-C exception-handling blocks. We basically
assume that @catch blocks are never executed.
Modified:
cfe/trunk/lib/AST/CFG.cpp
Modified: cfe/trunk/lib/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CFG.cpp?rev=68072&r1=68071&r2=68072&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CFG.cpp (original)
+++ cfe/trunk/lib/AST/CFG.cpp Mon Mar 30 17:29:21 2009
@@ -129,10 +129,13 @@
return Block;
}
- CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S) { return NYS(); }
- CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) { return NYS(); }
- CFGBlock* VisitObjCAtFinallyStmt(ObjCAtFinallyStmt* S) { return NYS(); }
-
+ CFGBlock* VisitObjCAtTryStmt(ObjCAtTryStmt* S);
+ CFGBlock* VisitObjCAtCatchStmt(ObjCAtCatchStmt* S) {
+ // FIXME: For now we pretend that @catch and the code it contains
+ // does not exit.
+ return Block;
+ }
+
// FIXME: This is not completely supported. We basically @throw like
// a 'return'.
CFGBlock* VisitObjCAtThrowStmt(ObjCAtThrowStmt* S);
@@ -888,7 +891,17 @@
Block = createBlock();
return addStmt(S->getCollection());
}
-
+
+CFGBlock* CFGBuilder::VisitObjCAtTryStmt(ObjCAtTryStmt* S) {
+ // Process the statements of the @finally block.
+ if (ObjCAtFinallyStmt *FS = S->getFinallyStmt())
+ Visit(FS->getFinallyBody());
+
+ // FIXME: Handle the @catch statements.
+
+ // Process the try body
+ return Visit(S->getTryBody());
+}
CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
// "while" is a control-flow statement. Thus we stop processing the
From dgregor at apple.com Mon Mar 30 17:58:21 2009
From: dgregor at apple.com (Douglas Gregor)
Date: Mon, 30 Mar 2009 22:58:21 -0000
Subject: [cfe-commits] r68074 - in /cfe/trunk: include/clang/AST/
include/clang/Parse/ lib/AST/ lib/CodeGen/ lib/Parse/ lib/Sema/
Message-ID: <200903302258.n2UMwMtk027459@zion.cs.uiuc.edu>
Author: dgregor
Date: Mon Mar 30 17:58:21 2009
New Revision: 68074
URL: http://llvm.org/viewvc/llvm-project?rev=68074&view=rev
Log:
Improve the representation of template names in the AST. This
representation handles the various ways in which one can name a
template, including unqualified references ("vector"), qualified
references ("std::vector"), and dependent template names
("MetaFun::template apply").
One immediate effect of this change is that the representation of
nested-name-specifiers in type names for class template
specializations (e.g., std::vector) is more accurate. Rather than
representing std::vector as
std::(vector)
we represent it as
(std::vector)
which more closely follows the C++ grammar.
Additionally, templates are no longer represented as declarations
(DeclPtrTy) in Parse-Sema interactions. Instead, I've introduced a new
OpaquePtr type (TemplateTy) that holds the representation of a
TemplateName. This will simplify the handling of dependent
template-names, once we get there.
Added:
cfe/trunk/include/clang/AST/TemplateName.h
cfe/trunk/lib/AST/TemplateName.cpp
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/DeclTemplate.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/AST/TypeNodes.def
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/AST/TypeSerialization.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
cfe/trunk/lib/Parse/MinimalAction.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Mar 30 17:58:21 2009
@@ -19,6 +19,7 @@
#include "clang/AST/Builtins.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
@@ -71,13 +72,15 @@
llvm::FoldingSet FunctionNoProtoTypes;
llvm::FoldingSet FunctionProtoTypes;
llvm::FoldingSet TemplateTypeParmTypes;
- llvm::FoldingSet
- ClassTemplateSpecializationTypes;
+ llvm::FoldingSet TemplateSpecializationTypes;
llvm::FoldingSet QualifiedNameTypes;
llvm::FoldingSet TypenameTypes;
llvm::FoldingSet ObjCQualifiedInterfaceTypes;
llvm::FoldingSet ObjCQualifiedIdTypes;
+ llvm::FoldingSet QualifiedTemplateNames;
+ llvm::FoldingSet DependentTemplateNames;
+
/// \brief The set of nested name specifiers.
///
/// This set is managed by the NestedNameSpecifier class.
@@ -291,10 +294,10 @@
QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
IdentifierInfo *Name = 0);
- QualType getClassTemplateSpecializationType(TemplateDecl *Template,
- const TemplateArgument *Args,
- unsigned NumArgs,
- QualType Canon = QualType());
+ QualType getTemplateSpecializationType(TemplateName T,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
+ QualType Canon = QualType());
QualType getQualifiedNameType(NestedNameSpecifier *NNS,
QualType NamedType);
@@ -407,6 +410,13 @@
QualType getFixedWidthIntType(unsigned Width, bool Signed);
+ TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
+ bool TemplateKeyword,
+ TemplateDecl *Template);
+
+ TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name);
+
private:
QualType getFromTargetType(unsigned Type) const;
Modified: cfe/trunk/include/clang/AST/DeclTemplate.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclTemplate.h?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h (original)
+++ cfe/trunk/include/clang/AST/DeclTemplate.h Mon Mar 30 17:58:21 2009
@@ -705,7 +705,7 @@
llvm::FoldingSet Specializations;
};
- /// \brief Previous declaration of
+ /// \brief Previous declaration of this class template.
ClassTemplateDecl *PreviousDeclaration;
/// \brief Pointer to the data that is common to all of the
Added: cfe/trunk/include/clang/AST/TemplateName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateName.h?rev=68074&view=auto
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateName.h (added)
+++ cfe/trunk/include/clang/AST/TemplateName.h Mon Mar 30 17:58:21 2009
@@ -0,0 +1,246 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_TEMPLATENAME_H
+#define LLVM_CLANG_AST_TEMPLATENAME_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+
+namespace llvm {
+ class raw_ostream;
+}
+
+namespace clang {
+
+class DependentTemplateName;
+class IdentifierInfo;
+class NestedNameSpecifier;
+class QualifiedTemplateName;
+class TemplateDecl;
+
+/// \brief Represents a C++ template name within the type system.
+///
+/// A C++ template name refers to a template within the C++ type
+/// system. In most cases, a template name is simply a reference to a
+/// class template, e.g.
+///
+/// \code
+/// template class X { };
+///
+/// X xi;
+/// \endcode
+///
+/// Here, the 'X' in \c X is a template name that refers to the
+/// declaration of the class template X, above. Template names can
+/// also refer to function templates, C++0x template aliases, etc.
+///
+/// Some template names are dependent. For example, consider:
+///
+/// \code
+/// template struct apply2 {
+/// typedef typename MetaFun::template apply::type type;
+/// };
+/// \endcode
+///
+/// Here, "apply" is treated as a template name within the typename
+/// specifier in the typedef. "apply" is a nested template, and can
+/// only be understood in the context of
+class TemplateName {
+ typedef llvm::PointerUnion3 StorageType;
+
+ StorageType Storage;
+
+ explicit TemplateName(void *Ptr) {
+ Storage = StorageType::getFromOpaqueValue(Ptr);
+ }
+
+public:
+ TemplateName() : Storage() { }
+ explicit TemplateName(TemplateDecl *Template) : Storage(Template) { }
+ explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { }
+ explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { }
+
+ /// \brief Retrieve the the underlying template declaration that
+ /// this template name refers to, if known.
+ ///
+ /// \returns The template declaration that this template name refers
+ /// to, if any. If the template name does not refer to a specific
+ /// declaration because it is a dependent name, returns NULL.
+ TemplateDecl *getAsTemplateDecl() const;
+
+ /// \brief Retrieve the underlying qualified template name
+ /// structure, if any.
+ QualifiedTemplateName *getAsQualifiedTemplateName() const {
+ return Storage.dyn_cast();
+ }
+
+ /// \brief Retrieve the underlying dependent template name
+ /// structure, if any.
+ DependentTemplateName *getAsDependentTemplateName() const {
+ return Storage.dyn_cast();
+ }
+
+ /// \brief Determines whether this is a dependent template name.
+ bool isDependent() const;
+
+ /// \brief Print the template name.
+ void Print(llvm::raw_ostream &OS) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ ID.AddPointer(Storage.getOpaqueValue());
+ }
+
+ /// \brief Retrieve the template name as a void pointer.
+ void *getAsVoidPointer() const { return Storage.getOpaqueValue(); }
+
+ /// \brief Build a template name from a void pointer.
+ static TemplateName getFromVoidPointer(void *Ptr) {
+ return TemplateName(Ptr);
+ }
+};
+
+/// \brief Represents a template name that was expressed as a
+/// qualified name.
+///
+/// This kind of template name refers to a template name that was
+/// preceded by a nested name specifier, e.g., \c std::vector. Here,
+/// the nested name specifier is "std::" and the template name is the
+/// declaration for "vector". The QualifiedTemplateName class is only
+/// used to provide "sugar" for template names that were expressed
+/// with a qualified name, and has no semantic meaning. In this
+/// manner, it is to TemplateName what QualifiedNameType is to Type,
+/// providing extra syntactic sugar for downstream clients.
+class QualifiedTemplateName : public llvm::FoldingSetNode {
+ /// \brief The nested name specifier that qualifies the template name.
+ ///
+ /// The bit is used to indicate whether the "template" keyword was
+ /// present before the template name itself. Note that the
+ /// "template" keyword is always redundant in this case (otherwise,
+ /// the template name would be a dependent name and we would express
+ /// this name with DependentTemplateName).
+ llvm::PointerIntPair Qualifier;
+
+ /// \brief The template declaration that this qualified name refers
+ /// to.
+ TemplateDecl *Template;
+
+ friend class ASTContext;
+
+ QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
+ TemplateDecl *Template)
+ : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) { }
+
+public:
+ /// \brief Return the nested name specifier that qualifies this name.
+ NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+
+ /// \brief Whether the template name was prefixed by the "template"
+ /// keyword.
+ bool hasTemplateKeyword() const { return Qualifier.getInt(); }
+
+ /// \brief The template declaration to which this qualified name
+ /// refers.
+ TemplateDecl *getTemplateDecl() const { return Template; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+ bool TemplateKeyword, TemplateDecl *Template) {
+ ID.AddPointer(NNS);
+ ID.AddBoolean(TemplateKeyword);
+ ID.AddPointer(Template);
+ }
+};
+
+/// \brief Represents a dependent template name that cannot be
+/// resolved prior to template instantiation.
+///
+/// This kind of template name refers to a dependent template name,
+/// including its nested name specifier. For example,
+/// DependentTemplateName can refer to "MetaFun::template apply",
+/// where "MetaFun::" is the nested name specifier and "apply" is the
+/// template name referenced. The "template" keyword is implied.
+class DependentTemplateName : public llvm::FoldingSetNode {
+ /// \brief The nested name specifier that qualifies the template
+ /// name.
+ NestedNameSpecifier *Qualifier;
+
+ /// \brief The dependent template name.
+ const IdentifierInfo *Name;
+
+ /// \brief The canonical template name to which this dependent
+ /// template name refers.
+ ///
+ /// The canonical template name for a dependent template name is
+ /// another dependent template name whose nested name specifier is
+ /// canonical.
+ TemplateName CanonicalTemplateName;
+
+ friend class ASTContext;
+
+ DependentTemplateName(NestedNameSpecifier *Qualifier,
+ const IdentifierInfo *Name)
+ : Qualifier(Qualifier), Name(Name), CanonicalTemplateName(this) { }
+
+ DependentTemplateName(NestedNameSpecifier *Qualifier,
+ const IdentifierInfo *Name,
+ TemplateName Canon)
+ : Qualifier(Qualifier), Name(Name), CanonicalTemplateName(Canon) { }
+
+public:
+ /// \brief Return the nested name specifier that qualifies this name.
+ NestedNameSpecifier *getQualifier() const { return Qualifier; }
+
+ /// \brief Return the name to which this dependent template name
+ /// refers.
+ const IdentifierInfo *getName() const { return Name; }
+
+ void Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getQualifier(), getName());
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name) {
+ ID.AddPointer(NNS);
+ ID.AddPointer(Name);
+ }
+};
+
+}
+
+namespace llvm {
+
+/// \brief The clang::TemplateName class is effectively a pointer.
+template<>
+class PointerLikeTypeTraits {
+public:
+ static inline void *getAsVoidPointer(clang::TemplateName TN) {
+ return TN.getAsVoidPointer();
+ }
+
+ static inline clang::TemplateName getFromVoidPointer(void *Ptr) {
+ return clang::TemplateName::getFromVoidPointer(Ptr);
+ }
+
+ // No bits are available!
+ enum { NumLowBitsAvailable = 0 };
+};
+
+}
+
+#endif
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Mon Mar 30 17:58:21 2009
@@ -16,11 +16,13 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateName.h"
#include "llvm/Support/Casting.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Bitcode/SerializationFwd.h"
+
using llvm::isa;
using llvm::cast;
using llvm::cast_or_null;
@@ -39,7 +41,7 @@
class TemplateDecl;
class TemplateTypeParmDecl;
class NonTypeTemplateParmDecl;
- class TemplateTemplateParamDecl;
+ class TemplateTemplateParmDecl;
class TagDecl;
class RecordDecl;
class CXXRecordDecl;
@@ -437,8 +439,8 @@
const ObjCQualifiedIdType *getAsObjCQualifiedIdType() const;
const TemplateTypeParmType *getAsTemplateTypeParmType() const;
- const ClassTemplateSpecializationType *
- getAsClassTemplateSpecializationType() const;
+ const TemplateSpecializationType *
+ getAsTemplateSpecializationType() const;
/// getAsPointerToObjCInterfaceType - If this is a pointer to an ObjC
/// interface, return the interface type, otherwise return null.
@@ -1494,32 +1496,34 @@
friend class Type;
};
-/// \brief Represents the type of a class template specialization as
-/// written in the source code.
+/// \brief Represents the type of a template specialization as written
+/// in the source code.
///
-/// Class template specialization types represent the syntactic form
-/// of a template-id that refers to a type, e.g., @c vector. All
-/// class template specialization types are syntactic sugar, whose
-/// canonical type will point to some other type node that represents
-/// the instantiation or class template specialization. For example, a
+/// Template specialization types represent the syntactic form of a
+/// template-id that refers to a type, e.g., @c vector. Some
+/// template specialization types are syntactic sugar, whose canonical
+/// type will point to some other type node that represents the
+/// instantiation or class template specialization. For example, a
/// class template specialization type of @c vector will refer to
-/// a tag type for the instantiation
+/// a tag type for the instantiation
/// @c std::vector>.
-class ClassTemplateSpecializationType
+///
+/// Other template specialization types, for which the template name
+/// is dependent, may be canonical types. These types are always
+/// dependent.
+class TemplateSpecializationType
: public Type, public llvm::FoldingSetNode {
- // FIXME: Do we want templates to have a representation in the type
- // system? It will probably help with dependent templates and
- // possibly with template-names preceded by a nested-name-specifier.
- TemplateDecl *Template;
+ /// \brief The name of the template being specialized.
+ TemplateName Template;
/// \brief - The number of template arguments named in this class
/// template specialization.
unsigned NumArgs;
- ClassTemplateSpecializationType(TemplateDecl *T,
- const TemplateArgument *Args,
- unsigned NumArgs, QualType Canon);
+ TemplateSpecializationType(TemplateName T,
+ const TemplateArgument *Args,
+ unsigned NumArgs, QualType Canon);
virtual void Destroy(ASTContext& C);
@@ -1541,8 +1545,8 @@
iterator begin() const { return getArgs(); }
iterator end() const;
- /// \brief Retrieve the template that we are specializing.
- TemplateDecl *getTemplate() const { return Template; }
+ /// \brief Retrieve the name of the template that we are specializing.
+ TemplateName getTemplateName() const { return Template; }
/// \brief Retrieve the template arguments.
const TemplateArgument *getArgs() const {
@@ -1562,13 +1566,13 @@
Profile(ID, Template, getArgs(), NumArgs);
}
- static void Profile(llvm::FoldingSetNodeID &ID, TemplateDecl *T,
+ static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T,
const TemplateArgument *Args, unsigned NumArgs);
static bool classof(const Type *T) {
- return T->getTypeClass() == ClassTemplateSpecialization;
+ return T->getTypeClass() == TemplateSpecialization;
}
- static bool classof(const ClassTemplateSpecializationType *T) { return true; }
+ static bool classof(const TemplateSpecializationType *T) { return true; }
protected:
virtual void EmitImpl(llvm::Serializer& S) const;
Modified: cfe/trunk/include/clang/AST/TypeNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TypeNodes.def (original)
+++ cfe/trunk/include/clang/AST/TypeNodes.def Mon Mar 30 17:58:21 2009
@@ -72,7 +72,7 @@
TYPE(Record, TagType)
TYPE(Enum, TagType)
DEPENDENT_TYPE(TemplateTypeParm, Type)
-NON_CANONICAL_TYPE(ClassTemplateSpecialization, Type)
+TYPE(TemplateSpecialization, Type)
NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Mar 30 17:58:21 2009
@@ -72,7 +72,8 @@
typedef ActionBase::StmtTy StmtTy;
typedef OpaquePtr<0> DeclPtrTy;
typedef OpaquePtr<1> DeclGroupPtrTy;
- typedef void TypeTy; // FIXME: Change TypeTy to use OpaquePtr<1>.
+ typedef void TypeTy; // FIXME: Change TypeTy to use OpaquePtr.
+ typedef OpaquePtr<2> TemplateTy;
typedef void AttrTy;
typedef void BaseTy;
typedef void MemInitTy;
@@ -157,7 +158,7 @@
/// optional CXXScope can be passed to indicate the C++ scope in
/// which the identifier will be found.
virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
- DeclPtrTy &TemplateDecl,
+ TemplateTy &Template,
const CXXScopeSpec *SS = 0) = 0;
/// ActOnCXXGlobalScopeSpecifier - Return the object that represents the
@@ -1206,8 +1207,8 @@
return DeclResult();
}
- /// \brief Form a class template specialization from a template and
- /// a list of template arguments.
+ /// \brief Form a type from a template and a list of template
+ /// arguments.
///
/// This action merely forms the type for the template-id, possibly
/// checking well-formedness of the template arguments. It does not
@@ -1219,13 +1220,12 @@
/// \param IsSpecialization true when we are naming the class
/// template specialization as part of an explicit class
/// specialization or class template partial specialization.
- virtual TypeResult ActOnClassTemplateId(DeclPtrTy Template,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc,
- const CXXScopeSpec *SS) {
+ virtual TypeResult ActOnTemplateIdType(TemplateTy Template,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
return TypeResult();
};
@@ -1279,7 +1279,7 @@
ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
SourceLocation KWLoc,
const CXXScopeSpec &SS,
- DeclPtrTy Template,
+ TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
@@ -1569,7 +1569,7 @@
const CXXScopeSpec *SS);
virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
- DeclPtrTy &TemplateDecl,
+ TemplateTy &Template,
const CXXScopeSpec *SS = 0);
/// ActOnDeclarator - If this is a typedef declarator, we modify the
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Mar 30 17:58:21 2009
@@ -126,6 +126,7 @@
typedef Action::MemInitTy MemInitTy;
typedef Action::CXXScopeTy CXXScopeTy;
typedef Action::TemplateParamsTy TemplateParamsTy;
+ typedef Action::TemplateTy TemplateTy;
typedef llvm::SmallVector TemplateParameterLists;
@@ -1050,7 +1051,7 @@
typedef llvm::SmallVector TemplateArgIsTypeList;
typedef llvm::SmallVector TemplateArgLocationList;
- bool ParseTemplateIdAfterTemplateName(DeclPtrTy Template,
+ bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
SourceLocation TemplateNameLoc,
const CXXScopeSpec *SS,
bool ConsumeLastToken,
@@ -1060,7 +1061,7 @@
TemplateArgLocationList &TemplateArgLocations,
SourceLocation &RAngleLoc);
- void AnnotateTemplateIdToken(DeclPtrTy Template, TemplateNameKind TNK,
+ void AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar 30 17:58:21 2009
@@ -483,6 +483,10 @@
Align = Layout.getAlignment();
break;
}
+
+ case Type::TemplateSpecialization:
+ assert(false && "Dependent types have no size");
+ break;
}
assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
@@ -1358,30 +1362,31 @@
}
QualType
-ASTContext::getClassTemplateSpecializationType(TemplateDecl *Template,
- const TemplateArgument *Args,
- unsigned NumArgs,
- QualType Canon) {
+ASTContext::getTemplateSpecializationType(TemplateName Template,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
+ QualType Canon) {
+ // FIXME: If Template is dependent, canonicalize it!
+
if (!Canon.isNull())
Canon = getCanonicalType(Canon);
llvm::FoldingSetNodeID ID;
- ClassTemplateSpecializationType::Profile(ID, Template, Args, NumArgs);
+ TemplateSpecializationType::Profile(ID, Template, Args, NumArgs);
void *InsertPos = 0;
- ClassTemplateSpecializationType *Spec
- = ClassTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
+ TemplateSpecializationType *Spec
+ = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
if (Spec)
return QualType(Spec, 0);
- void *Mem = Allocate((sizeof(ClassTemplateSpecializationType) +
+ void *Mem = Allocate((sizeof(TemplateSpecializationType) +
sizeof(TemplateArgument) * NumArgs),
8);
- Spec = new (Mem) ClassTemplateSpecializationType(Template, Args, NumArgs,
- Canon);
+ Spec = new (Mem) TemplateSpecializationType(Template, Args, NumArgs, Canon);
Types.push_back(Spec);
- ClassTemplateSpecializationTypes.InsertNode(Spec, InsertPos);
+ TemplateSpecializationTypes.InsertNode(Spec, InsertPos);
return QualType(Spec, 0);
}
@@ -2486,6 +2491,53 @@
ObjCConstantStringType = getObjCInterfaceType(Decl);
}
+/// \brief Retrieve the template name that represents a qualified
+/// template name such as \c std::vector.
+TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
+ bool TemplateKeyword,
+ TemplateDecl *Template) {
+ llvm::FoldingSetNodeID ID;
+ QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
+
+ void *InsertPos = 0;
+ QualifiedTemplateName *QTN =
+ QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+ if (!QTN) {
+ QTN = new (*this,4) QualifiedTemplateName(NNS, TemplateKeyword, Template);
+ QualifiedTemplateNames.InsertNode(QTN, InsertPos);
+ }
+
+ return TemplateName(QTN);
+}
+
+/// \brief Retrieve the template name that represents a dependent
+/// template name such as \c MetaFun::template apply.
+TemplateName ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
+ const IdentifierInfo *Name) {
+ assert(NNS->isDependent() && "Nested name specifier must be dependent");
+
+ llvm::FoldingSetNodeID ID;
+ DependentTemplateName::Profile(ID, NNS, Name);
+
+ void *InsertPos = 0;
+ DependentTemplateName *QTN =
+ DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+
+ if (QTN)
+ return TemplateName(QTN);
+
+ NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+ if (CanonNNS == NNS) {
+ QTN = new (*this,4) DependentTemplateName(NNS, Name);
+ } else {
+ TemplateName Canon = getDependentTemplateName(CanonNNS, Name);
+ QTN = new (*this,4) DependentTemplateName(NNS, Name, Canon);
+ }
+
+ DependentTemplateNames.InsertNode(QTN, InsertPos);
+ return TemplateName(QTN);
+}
+
/// getFromTargetType - Given one of the integer types provided by
/// TargetInfo, produce the corresponding type. The unsigned @p Type
/// is actually a value of type @c TargetInfo::IntType.
@@ -3033,6 +3085,10 @@
ResultType.setCVRQualifiers(LHSCan.getCVRQualifiers());
return ResultType;
#endif
+
+ case Type::TemplateSpecialization:
+ assert(false && "Dependent types have no size");
+ break;
}
return QualType();
Added: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=68074&view=auto
==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (added)
+++ cfe/trunk/lib/AST/TemplateName.cpp Mon Mar 30 17:58:21 2009
@@ -0,0 +1,54 @@
+//===--- TemplateName.h - C++ Template Name Representation-------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TemplateName interface and subclasses.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+
+TemplateDecl *TemplateName::getAsTemplateDecl() const {
+ if (TemplateDecl *Template = Storage.dyn_cast())
+ return Template;
+
+ if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName())
+ return QTN->getTemplateDecl();
+
+ return 0;
+}
+
+bool TemplateName::isDependent() const {
+ if (TemplateDecl *Template = getAsTemplateDecl()) {
+ // FIXME: We don't yet have a notion of dependent
+ // declarations. When we do, check that. This hack won't last
+ // long!.
+ return isa(Template);
+ }
+
+ return true;
+}
+
+void TemplateName::Print(llvm::raw_ostream &OS) const {
+ if (TemplateDecl *Template = Storage.dyn_cast())
+ OS << Template->getIdentifier()->getName();
+ else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
+ QTN->getQualifier()->Print(OS);
+ if (QTN->hasTemplateKeyword())
+ OS << "template ";
+ OS << QTN->getTemplateDecl()->getIdentifier()->getName();
+ } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
+ DTN->getQualifier()->Print(OS);
+ OS << "template ";
+ OS << DTN->getName()->getName();
+ }
+}
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Mar 30 17:58:21 2009
@@ -93,8 +93,8 @@
return TOE->getUnderlyingExpr()->getType().getDesugaredType();
if (const TypeOfType *TOT = dyn_cast(this))
return TOT->getUnderlyingType().getDesugaredType();
- if (const ClassTemplateSpecializationType *Spec
- = dyn_cast(this))
+ if (const TemplateSpecializationType *Spec
+ = dyn_cast(this))
return Spec->getCanonicalTypeInternal().getDesugaredType();
if (const QualifiedNameType *QualName = dyn_cast(this))
return QualName->getNamedType().getDesugaredType();
@@ -549,11 +549,11 @@
return dyn_cast(CanonicalType);
}
-const ClassTemplateSpecializationType *
-Type::getAsClassTemplateSpecializationType() const {
+const TemplateSpecializationType *
+Type::getAsTemplateSpecializationType() const {
// There is no sugar for class template specialization types, so
// just return the canonical type pointer if it is the right class.
- return dyn_cast(CanonicalType);
+ return dyn_cast(CanonicalType);
}
bool Type::isIntegerType() const {
@@ -972,7 +972,7 @@
}
bool
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
switch (Args[Idx].getKind()) {
@@ -997,17 +997,16 @@
return false;
}
-ClassTemplateSpecializationType::
-ClassTemplateSpecializationType(TemplateDecl *T, const TemplateArgument *Args,
- unsigned NumArgs, QualType Canon)
- : Type(ClassTemplateSpecialization,
+TemplateSpecializationType::
+TemplateSpecializationType(TemplateName T, const TemplateArgument *Args,
+ unsigned NumArgs, QualType Canon)
+ : Type(TemplateSpecialization,
Canon.isNull()? QualType(this, 0) : Canon,
- /*FIXME: Check for dependent template */
- anyDependentTemplateArguments(Args, NumArgs)),
+ T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)),
Template(T), NumArgs(NumArgs)
{
assert((!Canon.isNull() ||
- anyDependentTemplateArguments(Args, NumArgs)) &&
+ T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) &&
"No canonical type for non-dependent class template specialization");
TemplateArgument *TemplateArgs
@@ -1016,7 +1015,7 @@
new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
}
-void ClassTemplateSpecializationType::Destroy(ASTContext& C) {
+void TemplateSpecializationType::Destroy(ASTContext& C) {
for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
// FIXME: Not all expressions get cloned, so we can't yet perform
// this destruction.
@@ -1025,24 +1024,23 @@
}
}
-ClassTemplateSpecializationType::iterator
-ClassTemplateSpecializationType::end() const {
+TemplateSpecializationType::iterator
+TemplateSpecializationType::end() const {
return begin() + getNumArgs();
}
const TemplateArgument &
-ClassTemplateSpecializationType::getArg(unsigned Idx) const {
+TemplateSpecializationType::getArg(unsigned Idx) const {
assert(Idx < getNumArgs() && "Template argument out of range");
return getArgs()[Idx];
}
void
-ClassTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
- TemplateDecl *T,
- const TemplateArgument *Args,
- unsigned NumArgs) {
- ID.AddPointer(T);
-
+TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+ TemplateName T,
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ T.Profile(ID);
for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
Args[Idx].Profile(ID);
}
@@ -1351,7 +1349,7 @@
InnerString = Name->getName() + InnerString;
}
-std::string ClassTemplateSpecializationType::PrintTemplateArgumentList(
+std::string TemplateSpecializationType::PrintTemplateArgumentList(
const TemplateArgument *Args,
unsigned NumArgs) {
std::string SpecString;
@@ -1403,9 +1401,15 @@
}
void
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
getAsStringInternal(std::string &InnerString) const {
- std::string SpecString = Template->getNameAsString();
+ std::string SpecString;
+
+ {
+ llvm::raw_string_ostream OS(SpecString);
+ Template.Print(OS);
+ }
+
SpecString += PrintTemplateArgumentList(getArgs(), getNumArgs());
if (InnerString.empty())
InnerString.swap(SpecString);
@@ -1515,7 +1519,7 @@
if (ClassTemplateSpecializationDecl *Spec
= dyn_cast(getDecl())) {
std::string TemplateArgs
- = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+ = TemplateSpecializationType::PrintTemplateArgumentList(
Spec->getTemplateArgs(),
Spec->getNumTemplateArgs());
InnerString = TemplateArgs + InnerString;
@@ -1534,7 +1538,7 @@
} else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast(DC)) {
std::string TemplateArgs
- = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+ = TemplateSpecializationType::PrintTemplateArgumentList(
Spec->getTemplateArgs(),
Spec->getNumTemplateArgs());
MyPart = Spec->getIdentifier()->getName() + TemplateArgs;
Modified: cfe/trunk/lib/AST/TypeSerialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeSerialization.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypeSerialization.cpp (original)
+++ cfe/trunk/lib/AST/TypeSerialization.cpp Mon Mar 30 17:58:21 2009
@@ -391,29 +391,17 @@
}
//===----------------------------------------------------------------------===//
-// ClassTemplateSpecializationType
+// TemplateSpecializationType
//===----------------------------------------------------------------------===//
-void ClassTemplateSpecializationType::EmitImpl(Serializer& S) const {
- S.Emit(getCanonicalTypeInternal());
- S.EmitPtr(Template);
- S.EmitInt(NumArgs);
- // FIXME: Serialize class template specialization types
+void TemplateSpecializationType::EmitImpl(Serializer& S) const {
+ // FIXME: Serialization support
}
Type*
-ClassTemplateSpecializationType::
+TemplateSpecializationType::
CreateImpl(ASTContext& Context, Deserializer& D) {
- llvm::SmallVector Args;
- llvm::SmallVector ArgIsType;
-
- QualType Canon = QualType::ReadVal(D);
- TemplateDecl *Template = cast(D.ReadPtr());
- unsigned NumArgs = D.ReadInt();
-
- // FIXME: De-serialize class template specialization types
- (void)Template;
- (void)NumArgs;
+ // FIXME: Deserialization support
return 0;
}
Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Mar 30 17:58:21 2009
@@ -561,7 +561,7 @@
case Type::FixedWidthInt:
case Type::BlockPointer:
case Type::MemberPointer:
- case Type::ClassTemplateSpecialization:
+ case Type::TemplateSpecialization:
case Type::QualifiedName:
case Type::ObjCQualifiedClass:
// Unsupported types
Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Mar 30 17:58:21 2009
@@ -392,6 +392,9 @@
// http://gcc.gnu.org/onlinedocs/gccint/Type-Layout.html#Type-Layout
assert(0 && "FIXME: We can't handle member pointers yet.");
return llvm::OpaqueType::get();
+
+ case Type::TemplateSpecialization:
+ assert(false && "Dependent types can't get here");
}
// FIXME: implement.
Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Mon Mar 30 17:58:21 2009
@@ -135,7 +135,7 @@
TemplateNameKind
MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
- DeclPtrTy &TemplateDecl,
+ TemplateTy &TemplateDecl,
const CXXScopeSpec *SS) {
return TNK_Non_template;
}
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Mar 30 17:58:21 2009
@@ -474,7 +474,7 @@
TagOrTempResult
= Actions.ActOnClassTemplateSpecialization(CurScope, TagType, TK,
StartLoc, SS,
- DeclPtrTy::make(TemplateId->Template),
+ TemplateTy::make(TemplateId->Template),
TemplateId->TemplateNameLoc,
TemplateId->LAngleLoc,
TemplateArgsPtr,
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Mar 30 17:58:21 2009
@@ -117,7 +117,7 @@
// an operator and not as part of a simple-template-id.
}
- DeclPtrTy Template;
+ TemplateTy Template;
TemplateNameKind TNK = TNK_Non_template;
// FIXME: If the nested-name-specifier thus far is dependent,
// set TNK = TNK_Dependent_template_name and skip the
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Mar 30 17:58:21 2009
@@ -406,7 +406,7 @@
/// last token in the stream (e.g., so that it can be replaced with an
/// annotation token).
bool
-Parser::ParseTemplateIdAfterTemplateName(DeclPtrTy Template,
+Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
SourceLocation TemplateNameLoc,
const CXXScopeSpec *SS,
bool ConsumeLastToken,
@@ -499,7 +499,7 @@
/// replaced with a type annotation token. Otherwise, the
/// simple-template-id is always replaced with a template-id
/// annotation token.
-void Parser::AnnotateTemplateIdToken(DeclPtrTy Template, TemplateNameKind TNK,
+void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
const CXXScopeSpec *SS,
SourceLocation TemplateKWLoc,
bool AllowTypeAnnotation) {
@@ -531,12 +531,13 @@
return;
// Build the annotation token.
+ // FIXME: Not just for class templates!
if (TNK == TNK_Class_template && AllowTypeAnnotation) {
Action::TypeResult Type
- = Actions.ActOnClassTemplateId(Template, TemplateNameLoc,
- LAngleLoc, TemplateArgsPtr,
- &TemplateArgLocations[0],
- RAngleLoc, SS);
+ = Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
+ LAngleLoc, TemplateArgsPtr,
+ &TemplateArgLocations[0],
+ RAngleLoc);
if (Type.isInvalid()) // FIXME: better recovery?
return;
@@ -603,12 +604,12 @@
TemplateId->NumArgs);
Action::TypeResult Type
- = Actions.ActOnClassTemplateId(DeclPtrTy::make(TemplateId->Template),
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->getTemplateArgLocations(),
- TemplateId->RAngleLoc, SS);
+ = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template),
+ TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc,
+ TemplateArgsPtr,
+ TemplateId->getTemplateArgLocations(),
+ TemplateId->RAngleLoc);
if (Type.isInvalid()) {
// FIXME: better recovery?
ConsumeToken();
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Mar 30 17:58:21 2009
@@ -885,7 +885,7 @@
// If this is a template-id, annotate with a template-id or type token.
if (NextToken().is(tok::less)) {
- DeclPtrTy Template;
+ TemplateTy Template;
if (TemplateNameKind TNK
= Actions.isTemplateName(*Tok.getIdentifierInfo(),
CurScope, Template, &SS))
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Mar 30 17:58:21 2009
@@ -1691,7 +1691,7 @@
// C++ Templates [C++ 14]
//
virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
- DeclPtrTy &TemplateDecl,
+ TemplateTy &Template,
const CXXScopeSpec *SS = 0);
bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
TemplateDecl *AdjustDeclIfTemplate(DeclPtrTy &Decl);
@@ -1742,20 +1742,19 @@
MultiTemplateParamsArg TemplateParameterLists,
AccessSpecifier AS);
- QualType CheckClassTemplateId(ClassTemplateDecl *ClassTemplate,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc);
+ QualType CheckTemplateIdType(TemplateName Template,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc);
virtual TypeResult
- ActOnClassTemplateId(DeclPtrTy Template, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc,
- const CXXScopeSpec *SS);
+ ActOnTemplateIdType(TemplateTy Template, SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgs,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc);
bool CheckClassTemplateSpecializationScope(ClassTemplateDecl *ClassTemplate,
ClassTemplateSpecializationDecl *PrevDecl,
@@ -1766,7 +1765,7 @@
ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
SourceLocation KWLoc,
const CXXScopeSpec &SS,
- DeclPtrTy Template,
+ TemplateTy Template,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs,
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Mar 30 17:58:21 2009
@@ -27,19 +27,23 @@
/// passed to indicate the C++ scope in which the identifier will be
/// found.
TemplateNameKind Sema::isTemplateName(IdentifierInfo &II, Scope *S,
- DeclPtrTy &Template,
+ TemplateTy &TemplateResult,
const CXXScopeSpec *SS) {
NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
+ TemplateNameKind TNK = TNK_Non_template;
+ TemplateDecl *Template = 0;
+
if (IIDecl) {
- if (isa(IIDecl)) {
- Template = DeclPtrTy::make(IIDecl);
+ if ((Template = dyn_cast(IIDecl))) {
if (isa(IIDecl))
- return TNK_Function_template;
- if (isa(IIDecl))
- return TNK_Class_template;
- assert(isa(IIDecl) && "Unknown TemplateDecl");
- return TNK_Template_template_parm;
+ TNK = TNK_Function_template;
+ else if (isa(IIDecl))
+ TNK = TNK_Class_template;
+ else if (isa(IIDecl))
+ TNK = TNK_Template_template_parm;
+ else
+ assert(false && "Unknown template declaration kind");
} else if (CXXRecordDecl *Record = dyn_cast(IIDecl)) {
// C++ [temp.local]p1:
// Like normal (non-template) classes, class templates have an
@@ -54,12 +58,12 @@
// specialization.
if (Record->isInjectedClassName()) {
Record = cast(Context.getCanonicalDecl(Record));
- if ((Template = DeclPtrTy::make(Record->getDescribedClassTemplate())))
- return TNK_Class_template;
- if (ClassTemplateSpecializationDecl *Spec
+ if ((Template = Record->getDescribedClassTemplate()))
+ TNK = TNK_Class_template;
+ else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast(Record)) {
- Template = DeclPtrTy::make(Spec->getSpecializedTemplate());
- return TNK_Class_template;
+ Template = Spec->getSpecializedTemplate();
+ TNK = TNK_Class_template;
}
}
}
@@ -67,7 +71,7 @@
// FIXME: What follows is a gross hack.
if (FunctionDecl *FD = dyn_cast(IIDecl)) {
if (FD->getType()->isDependentType()) {
- Template = DeclPtrTy::make(FD);
+ TemplateResult = TemplateTy::make(FD);
return TNK_Function_template;
}
} else if (OverloadedFunctionDecl *Ovl
@@ -76,13 +80,25 @@
FEnd = Ovl->function_end();
F != FEnd; ++F) {
if ((*F)->getType()->isDependentType()) {
- Template = DeclPtrTy::make(Ovl);
+ TemplateResult = TemplateTy::make(Ovl);
return TNK_Function_template;
}
}
}
+
+ if (TNK != TNK_Non_template) {
+ if (SS && SS->isSet() && !SS->isInvalid()) {
+ NestedNameSpecifier *Qualifier
+ = static_cast(SS->getScopeRep());
+ TemplateResult
+ = TemplateTy::make(Context.getQualifiedTemplateName(Qualifier,
+ false,
+ Template));
+ } else
+ TemplateResult = TemplateTy::make(TemplateName(Template));
+ }
}
- return TNK_Non_template;
+ return TNK;
}
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
@@ -700,27 +716,30 @@
}
}
-QualType Sema::CheckClassTemplateId(ClassTemplateDecl *ClassTemplate,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs,
- SourceLocation RAngleLoc) {
+QualType Sema::CheckTemplateIdType(TemplateName Name,
+ SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ SourceLocation RAngleLoc) {
+ TemplateDecl *Template = Name.getAsTemplateDecl();
+ assert(Template && "Cannot handle dependent template-names yet");
+
// Check that the template argument list is well-formed for this
// template.
llvm::SmallVector ConvertedTemplateArgs;
- if (CheckTemplateArgumentList(ClassTemplate, TemplateLoc, LAngleLoc,
+ if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
TemplateArgs, NumTemplateArgs, RAngleLoc,
ConvertedTemplateArgs))
return QualType();
assert((ConvertedTemplateArgs.size() ==
- ClassTemplate->getTemplateParameters()->size()) &&
+ Template->getTemplateParameters()->size()) &&
"Converted template argument list is too short!");
QualType CanonType;
- if (ClassTemplateSpecializationType::anyDependentTemplateArguments(
+ if (TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs,
NumTemplateArgs)) {
// This class template specialization is a dependent
@@ -731,10 +750,11 @@
//
// template struct A;
- CanonType = Context.getClassTemplateSpecializationType(ClassTemplate,
+ CanonType = Context.getTemplateSpecializationType(Name,
&ConvertedTemplateArgs[0],
ConvertedTemplateArgs.size());
- } else {
+ } else if (ClassTemplateDecl *ClassTemplate
+ = dyn_cast(Template)) {
// Find the class template specialization declaration that
// corresponds to these arguments.
llvm::FoldingSetNodeID ID;
@@ -764,35 +784,26 @@
// Build the fully-sugared type for this class template
// specialization, which refers back to the class template
// specialization we created or found.
- return Context.getClassTemplateSpecializationType(ClassTemplate,
- TemplateArgs,
- NumTemplateArgs,
- CanonType);
+ return Context.getTemplateSpecializationType(Name, TemplateArgs,
+ NumTemplateArgs, CanonType);
}
Action::TypeResult
-Sema::ActOnClassTemplateId(DeclPtrTy TemplateD, SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc,
- const CXXScopeSpec *SS) {
- TemplateDecl *Template = cast(TemplateD.getAs());
- ClassTemplateDecl *ClassTemplate = cast(Template);
+Sema::ActOnTemplateIdType(TemplateTy TemplateD, SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
+ ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation *TemplateArgLocs,
+ SourceLocation RAngleLoc) {
+ TemplateName Template = TemplateD.getAsVal();
// Translate the parser's template argument list in our AST format.
llvm::SmallVector TemplateArgs;
translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
- QualType Result = CheckClassTemplateId(ClassTemplate, TemplateLoc,
- LAngleLoc,
- &TemplateArgs[0],
- TemplateArgs.size(),
- RAngleLoc);
+ QualType Result = CheckTemplateIdType(Template, TemplateLoc, LAngleLoc,
+ &TemplateArgs[0], TemplateArgs.size(),
+ RAngleLoc);
- if (SS)
- Result = getQualifiedNameType(*SS, Result);
-
TemplateArgsIn.release();
return Result.getAsOpaquePtr();
}
@@ -1795,7 +1806,7 @@
Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
SourceLocation KWLoc,
const CXXScopeSpec &SS,
- DeclPtrTy TemplateD,
+ TemplateTy TemplateD,
SourceLocation TemplateNameLoc,
SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgsIn,
@@ -1804,10 +1815,9 @@
AttributeList *Attr,
MultiTemplateParamsArg TemplateParameterLists) {
// Find the class template we're specializing
+ TemplateName Name = TemplateD.getAsVal();
ClassTemplateDecl *ClassTemplate
- = dyn_cast_or_null(TemplateD.getAs());
- if (!ClassTemplate)
- return true;
+ = cast(Name.getAsTemplateDecl());
// Check the validity of the template headers that introduce this
// template.
@@ -1937,11 +1947,11 @@
// name based on the "canonical" representation used to store the
// template arguments in the specialization.
QualType WrittenTy
- = Context.getClassTemplateSpecializationType(ClassTemplate,
- &TemplateArgs[0],
- TemplateArgs.size(),
+ = Context.getTemplateSpecializationType(Name,
+ &TemplateArgs[0],
+ TemplateArgs.size(),
Context.getTypeDeclType(Specialization));
- Specialization->setTypeAsWritten(getQualifiedNameType(SS, WrittenTy));
+ Specialization->setTypeAsWritten(WrittenTy);
TemplateArgsIn.release();
// C++ [temp.expl.spec]p9:
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=68074&r1=68073&r2=68074&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Mar 30 17:58:21 2009
@@ -114,7 +114,7 @@
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation: {
TemplateDecl *Template = cast((Decl *)Active->Entity);
std::string TemplateArgsStr
- = ClassTemplateSpecializationType::PrintTemplateArgumentList(
+ = TemplateSpecializationType::PrintTemplateArgumentList(
Active->TemplateArgs,
Active->NumTemplateArgs);
Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
@@ -433,13 +433,12 @@
QualType
TemplateTypeInstantiator::
-InstantiateClassTemplateSpecializationType(
- const ClassTemplateSpecializationType *T,
+InstantiateTemplateSpecializationType(
+ const TemplateSpecializationType *T,
unsigned Quals) const {
llvm::SmallVector InstantiatedTemplateArgs;
InstantiatedTemplateArgs.reserve(T->getNumArgs());
- for (ClassTemplateSpecializationType::iterator Arg = T->begin(),
- ArgEnd = T->end();
+ for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
Arg != ArgEnd; ++Arg) {
switch (Arg->getKind()) {
case TemplateArgument::Type: {
@@ -473,12 +472,13 @@
// FIXME: We're missing the locations of the template name, '<', and
// '>'.
- return SemaRef.CheckClassTemplateId(cast(T->getTemplate()),
- Loc,
- SourceLocation(),
- &InstantiatedTemplateArgs[0],
- InstantiatedTemplateArgs.size(),
- SourceLocation());
+ // FIXME: Need to instantiate into the template name.
+ return SemaRef.CheckTemplateIdType(T->getTemplateName(),
+ Loc,
+ SourceLocation(),
+ &InstantiatedTemplateArgs[0],
+ InstantiatedTemplateArgs.size(),
+ SourceLocation());
}
QualType
From eli.friedman at gmail.com Mon Mar 30 18:39:02 2009
From: eli.friedman at gmail.com (Eli Friedman)
Date: Mon, 30 Mar 2009 23:39:02 -0000
Subject: [cfe-commits] r68075 - /cfe/trunk/lib/AST/ExprConstant.cpp
Message-ID: <200903302339.n2UNd3oi029052@zion.cs.uiuc.edu>
Author: efriedma
Date: Mon Mar 30 18:39:01 2009
New Revision: 68075
URL: http://llvm.org/viewvc/llvm-project?rev=68075&view=rev
Log:
Slight generalization for Evaluate with const variables.
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=68075&r1=68074&r2=68075&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Mar 30 18:39:01 2009
@@ -685,8 +685,8 @@
}
// In C++, const, non-volatile integers initialized with ICEs are ICEs.
- if (Info.Ctx.getLangOptions().CPlusPlus &&
- E->getType().getCVRQualifiers() == QualType::Const) {
+ // In C, they can also be folded, although they are not ICEs.
+ if (E->getType().getCVRQualifiers() == QualType::Const) {
if (const VarDecl *D = dyn_cast(E->getDecl())) {
if (const Expr *Init = D->getInit())
return Visit(const_cast(Init));
From snaroff at apple.com Mon Mar 30 18:46:03 2009
From: snaroff at apple.com (Steve Naroff)
Date: Mon, 30 Mar 2009 23:46:03 -0000
Subject: [cfe-commits] r68076 - in /cfe/trunk:
include/clang/Basic/DiagnosticLexKinds.td lib/Lex/LiteralSupport.cpp
test/Sema/ucn-cstring.c
Message-ID: <200903302346.n2UNk3v2029337@zion.cs.uiuc.edu>
Author: snaroff
Date: Mon Mar 30 18:46:03 2009
New Revision: 68076
URL: http://llvm.org/viewvc/llvm-project?rev=68076&view=rev
Log:
Implement UCN support for C string literals (C99 6.4.3) and add some very basic tests. Chris Goller has graciously offered to write some test to help validate UCN support.
>From a front-end perspective, I believe this code should work for ObjC @-strings. At the moment, I believe we need to tweak the code generation for @-strings (which doesn't appear to handle them). Will be investigating.
Added:
cfe/trunk/test/Sema/ucn-cstring.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
cfe/trunk/lib/Lex/LiteralSupport.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=68076&r1=68075&r2=68076&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Mon Mar 30 18:46:03 2009
@@ -52,6 +52,10 @@
"use of non-standard escape character '\\%0'">;
def ext_unknown_escape : Extension<"unknown escape sequence '\\%0'">;
def err_hex_escape_no_digits : Error<"\\x used with no following hex digits">;
+def err_ucn_escape_no_digits : Error<"\\u used with no following hex digits">;
+def err_ucn_escape_invalid : Error<"invalid universal character">;
+def err_ucn_escape_incomplete : Error<"incomplete universal character name">;
+def err_ucn_escape_too_big : Error<"universal character name is too long">;
def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">;
def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">;
def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">;
Modified: cfe/trunk/lib/Lex/LiteralSupport.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/LiteralSupport.cpp?rev=68076&r1=68075&r2=68076&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/LiteralSupport.cpp (original)
+++ cfe/trunk/lib/Lex/LiteralSupport.cpp Mon Mar 30 18:46:03 2009
@@ -71,8 +71,6 @@
case 'v':
ResultChar = 11;
break;
-
- //case 'u': case 'U': // FIXME: UCNs.
case 'x': { // Hex escape.
ResultChar = 0;
if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
@@ -151,7 +149,90 @@
return ResultChar;
}
-
+/// ProcessUCNEscape - Read the Universal Character Name, check constraints and
+/// convert the UTF32 to UTF8. This is a subroutine of StringLiteralParser.
+/// When we decide to implement UCN's for character constants and identifiers,
+/// we will likely rework our support for UCN's.
+static void ProcessUCNEscape(const char *&ThisTokBuf, const char *ThisTokEnd,
+ char *&ResultBuf, const char *ResultBufEnd,
+ bool &HadError,
+ SourceLocation Loc, Preprocessor &PP) {
+ // FIXME: Add a warning - UCN's are only valid in C++ & C99.
+
+ // Skip the '\u' char's.
+ ThisTokBuf += 2;
+
+ if (ThisTokBuf == ThisTokEnd || !isxdigit(*ThisTokBuf)) {
+ PP.Diag(Loc, diag::err_ucn_escape_no_digits);
+ HadError = 1;
+ return;
+ }
+ typedef unsigned int UTF32;
+
+ UTF32 UcnVal = 0;
+ unsigned short UcnLen = (ThisTokBuf[-1] == 'u' ? 4 : 8);
+ for (; ThisTokBuf != ThisTokEnd && UcnLen; ++ThisTokBuf, UcnLen--) {
+ int CharVal = HexDigitValue(ThisTokBuf[0]);
+ if (CharVal == -1) break;
+ UcnVal <<= 4;
+ UcnVal |= CharVal;
+ }
+ // If we didn't consume the proper number of digits, there is a problem.
+ if (UcnLen) {
+ PP.Diag(Loc, diag::err_ucn_escape_incomplete);
+ HadError = 1;
+ return;
+ }
+ // Check UCN constraints (C99 6.4.3p2)
+ if ((UcnVal < 0xa0 &&
+ (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60 )) // $, @, `
+ || (UcnVal >= 0xD800 && UcnVal <= 0xDFFF)) {
+ PP.Diag(Loc, diag::err_ucn_escape_invalid);
+ HadError = 1;
+ return;
+ }
+ // Now that we've parsed/checked the UCN, we convert from UTF32->UTF8.
+ // The conversion below was inspired by:
+ // http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
+ // First, we determine how many bytes the result will require.
+ typedef unsigned char UTF8;
+
+ unsigned short bytesToWrite = 0;
+ if (UcnVal < (UTF32)0x80)
+ bytesToWrite = 1;
+ else if (UcnVal < (UTF32)0x800)
+ bytesToWrite = 2;
+ else if (UcnVal < (UTF32)0x10000)
+ bytesToWrite = 3;
+ else
+ bytesToWrite = 4;
+
+ // If the buffer isn't big enough, bail.
+ if ((ResultBuf + bytesToWrite) >= ResultBufEnd) {
+ PP.Diag(Loc, diag::err_ucn_escape_too_big);
+ HadError = 1;
+ return;
+ }
+ const unsigned byteMask = 0xBF;
+ const unsigned byteMark = 0x80;
+
+ // Once the bits are split out into bytes of UTF8, this is a mask OR-ed
+ // into the first byte, depending on how many bytes follow. There are
+ // as many entries in this table as there are UTF8 sequence types.
+ static const UTF8 firstByteMark[7] = {
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
+ };
+ // Finally, we write the bytes into ResultBuf.
+ ResultBuf += bytesToWrite;
+ switch (bytesToWrite) { // note: everything falls through.
+ case 4: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+ case 3: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+ case 2: *--ResultBuf = (UTF8)((UcnVal | byteMark) & byteMask); UcnVal >>= 6;
+ case 1: *--ResultBuf = (UTF8) (UcnVal | firstByteMark[bytesToWrite]);
+ }
+ // Update the buffer.
+ ResultBuf += bytesToWrite;
+}
/// integer-constant: [C99 6.4.4.1]
@@ -757,23 +838,29 @@
*ResultPtr++ = InStart[0];
// Add zeros at the end.
for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
- *ResultPtr++ = 0;
+ *ResultPtr++ = 0;
}
}
continue;
}
- // Otherwise, this is an escape character. Process it.
- unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
- StringToks[i].getLocation(),
- ThisIsWide, PP);
-
- // Note: our internal rep of wide char tokens is always little-endian.
- *ResultPtr++ = ResultChar & 0xFF;
-
- if (AnyWide) {
- for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
- *ResultPtr++ = ResultChar >> i*8;
+ if (ThisTokBuf[1] == 'u' || ThisTokBuf[1] == 'U') {
+ ProcessUCNEscape(ThisTokBuf, ThisTokEnd, ResultPtr,
+ GetString() + ResultBuf.size(),
+ hadError, StringToks[i].getLocation(), PP);
+ } else {
+ // Otherwise, this is a non-UCN escape character. Process it.
+ unsigned ResultChar = ProcessCharEscape(ThisTokBuf, ThisTokEnd, hadError,
+ StringToks[i].getLocation(),
+ ThisIsWide, PP);
+
+ // Note: our internal rep of wide char tokens is always little-endian.
+ *ResultPtr++ = ResultChar & 0xFF;
+
+ if (AnyWide) {
+ for (unsigned i = 1, e = wchar_tByteWidth; i != e; ++i)
+ *ResultPtr++ = ResultChar >> i*8;
+ }
}
}
}
Added: cfe/trunk/test/Sema/ucn-cstring.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ucn-cstring.c?rev=68076&view=auto
==============================================================================
--- cfe/trunk/test/Sema/ucn-cstring.c (added)
+++ cfe/trunk/test/Sema/ucn-cstring.c Mon Mar 30 18:46:03 2009
@@ -0,0 +1,15 @@
+// RUN: clang-cc %s -verify -fsyntax-only -pedantic
+
+#include
+
+int main(void) {
+ printf("%s (%d)\n", "hello \u2192 \u2603 \u2190 world", sizeof("hello \u2192 \u2603 \u2190 world"));
+ printf("%s (%d)\n", "\U00010400\U0001D12B", sizeof("\U00010400\U0001D12B"));
+ // Some error conditions...
+ printf("%s\n", "\U"); // expected-error{{\u used with no following hex digits}}
+ printf("%s\n", "\U00"); // expected-error{{incomplete universal character name}}
+ printf("%s\n", "\U0001"); // expected-error{{incomplete universal character name}}
+ printf("%s\n", "\u0001"); // expected-error{{invalid universal character}}
+ return 0;
+}
+
From fjahanian at apple.com Mon Mar 30 19:06:30 2009
From: fjahanian at apple.com (Fariborz Jahanian)
Date: Tue, 31 Mar 2009 00:06:30 -0000
Subject: [cfe-commits] r68077 - in /cfe/trunk: include/clang/AST/DeclObjC.h
lib/AST/ASTContext.cpp lib/AST/DeclObjC.cpp lib/Sema/SemaDeclObjC.cpp
test/SemaObjC/property-nonfragile-abi.m test/SemaObjC/synthesized-ivar.m
Message-ID: <200903310006.n2V06U4S030091@zion.cs.uiuc.edu>
Author: fjahanian
Date: Mon Mar 30 19:06:29 2009
New Revision: 68077
URL: http://llvm.org/viewvc/llvm-project?rev=68077&view=rev
Log:
fe support for objc2's nonfragile-abi synthesized ivars.
Added:
cfe/trunk/test/SemaObjC/synthesized-ivar.m
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/DeclObjC.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/test/SemaObjC/property-nonfragile-abi.m
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=68077&r1=68076&r2=68077&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Mon Mar 30 19:06:29 2009
@@ -1009,6 +1009,7 @@
ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
+ ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property
ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
QualType T)
@@ -1016,7 +1017,7 @@
PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None),
GetterName(Selector()),
SetterName(Selector()),
- GetterMethodDecl(0), SetterMethodDecl(0) {}
+ GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -1074,6 +1075,13 @@
return PropertyControl(PropertyImplementation);
}
+ void setPropertyIvarDecl(ObjCIvarDecl *Ivar) {
+ PropertyIvarDecl = Ivar;
+ }
+ ObjCIvarDecl *getPropertyIvarDecl() const {
+ return PropertyIvarDecl;
+ }
+
static bool classof(const Decl *D) {
return D->getKind() == ObjCProperty;
}
@@ -1091,7 +1099,6 @@
Dynamic
};
private:
- unsigned IvarKind : 1;
SourceLocation AtLoc; // location of @synthesize or @dynamic
/// Property declaration being implemented
ObjCPropertyDecl *PropertyDecl;
@@ -1103,7 +1110,7 @@
ObjCPropertyDecl *property,
Kind PK,
ObjCIvarDecl *ivarDecl)
- : Decl(ObjCPropertyImpl, DC, L), IvarKind(false), AtLoc(atLoc),
+ : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
PropertyDecl(property), PropertyIvarDecl(ivarDecl) {
assert (PK == Dynamic || PropertyIvarDecl);
}
@@ -1128,16 +1135,6 @@
ObjCIvarDecl *getPropertyIvarDecl() const {
return PropertyIvarDecl;
}
- void SetPropertyIvarDecl(ObjCIvarDecl *Ivar) {
- assert(PropertyIvarDecl && "PropertyIvarDecl is already defined");
- PropertyIvarDecl = Ivar;
- }
- void SetIvarSynthesized() {
- IvarKind = true;
- }
- bool IsIvarSynthesized() const {
- return IvarKind;
- }
static bool classof(const Decl *D) {
return D->getKind() == ObjCPropertyImpl;
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=68077&r1=68076&r2=68077&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar 30 19:06:29 2009
@@ -608,6 +608,13 @@
if (!IVDecl->isInvalidDecl())
Fields.push_back(cast(IVDecl));
}
+ // look into properties.
+ for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
+ E = OI->prop_end(); I != E; ++I) {
+ ObjCPropertyDecl *PDecl = (*I);
+ if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
+ Fields.push_back(cast(IV));
+ }
}
/// addRecordToClass - produces record info. for the class for its
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=68077&r1=68076&r2=68077&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Mon Mar 30 19:06:29 2009
@@ -137,6 +137,16 @@
return *I;
}
}
+ // look into properties.
+ for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(),
+ E = ClassDecl->prop_end(); I != E; ++I) {
+ ObjCPropertyDecl *PDecl = (*I);
+ if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
+ if (IV->getIdentifier() == ID) {
+ clsDeclared = ClassDecl;
+ return IV;
+ }
+ }
ClassDecl = ClassDecl->getSuperClass();
}
return NULL;
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=68077&r1=68076&r2=68077&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Mar 30 19:06:29 2009
@@ -1765,17 +1765,22 @@
// @synthesize
if (!PropertyIvar)
PropertyIvar = PropertyId;
+ QualType PropType = Context.getCanonicalType(property->getType());
// Check that this is a previously declared 'ivar' in 'IDecl' interface
Ivar = IDecl->lookupInstanceVariable(PropertyIvar);
if (!Ivar) {
- if (getLangOptions().ObjCNonFragileABI)
- Diag(PropertyLoc, diag::error_synthesized_ivar_yet_not_supported)
- << PropertyId;
- else
+ if (getLangOptions().ObjCNonFragileABI) {
+ Ivar = ObjCIvarDecl::Create(Context, CurContext, PropertyLoc,
+ PropertyIvar, PropType,
+ ObjCIvarDecl::Private,
+ (Expr *)0);
+ property->setPropertyIvarDecl(Ivar);
+ }
+ else {
Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId;
- return DeclPtrTy();
+ return DeclPtrTy();
+ }
}
- QualType PropType = Context.getCanonicalType(property->getType());
QualType IvarType = Context.getCanonicalType(Ivar->getType());
// Check that type of property and its ivar are type compatible.
Modified: cfe/trunk/test/SemaObjC/property-nonfragile-abi.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/property-nonfragile-abi.m?rev=68077&r1=68076&r2=68077&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/property-nonfragile-abi.m (original)
+++ cfe/trunk/test/SemaObjC/property-nonfragile-abi.m Mon Mar 30 19:06:29 2009
@@ -16,7 +16,6 @@
@end
@implementation XCDeviceWillExecuteInfoBaton
- // Produce an error when compiling for -arch x86_64 (or "non-fragile" ABI)
- @synthesize sdkPath; // expected-error{{instance variable synthesis not yet supported (need to declare 'sdkPath' explicitly)}}
+ @synthesize sdkPath;
@end
Added: cfe/trunk/test/SemaObjC/synthesized-ivar.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/synthesized-ivar.m?rev=68077&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/synthesized-ivar.m (added)
+++ cfe/trunk/test/SemaObjC/synthesized-ivar.m Mon Mar 30 19:06:29 2009
@@ -0,0 +1,13 @@
+// RUN: clang-cc -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
+ at interface I
+{
+}
+ at property int IP;
+ at end
+
+ at implementation I
+ at synthesize IP;
+- (int) Meth {
+ return IP;
+}
+ at end
From eli.friedman at gmail.com Mon Mar 30 19:09:39 2009
From: eli.friedman at gmail.com (Eli Friedman)
Date: Mon, 30 Mar 2009 17:09:39 -0700
Subject: [cfe-commits] r68076 - in /cfe/trunk:
include/clang/Basic/DiagnosticLexKinds.td
lib/Lex/LiteralSupport.cpp test/Sema/ucn-cstring.c
In-Reply-To: <200903302346.n2UNk3v2029337@zion.cs.uiuc.edu>
References: <200903302346.n2UNk3v2029337@zion.cs.uiuc.edu>
Message-ID:
On Mon, Mar 30, 2009 at 4:46 PM, Steve Naroff wrote:
> + ?// Check UCN constraints (C99 6.4.3p2)
> + ?if ((UcnVal < 0xa0 &&
> + ? ? ?(UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60 )) // $, @, `
> + ? ? ?|| (UcnVal >= 0xD800 && UcnVal <= 0xDFFF)) {
> + ? ?PP.Diag(Loc, diag::err_ucn_escape_invalid);
> + ? ?HadError = 1;
> + ? ?return;
> + ?}
This should also check that UcnVal is less that 0x110000.
> + ?// Now that we've parsed/checked the UCN, we convert from UTF32->UTF8.
> + ?// The conversion below was inspired by:
> + ?// ? http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
> + ?// First, we determine how many bytes the result will require.
> + ?typedef unsigned char UTF8;
> +
> + ?unsigned short bytesToWrite = 0;
> + ?if (UcnVal < (UTF32)0x80)
> + ? ?bytesToWrite = 1;
> + ?else if (UcnVal < (UTF32)0x800)
> + ? ?bytesToWrite = 2;
> + ?else if (UcnVal < (UTF32)0x10000)
> + ? ?bytesToWrite = 3;
> + ?else
> + ? ?bytesToWrite = 4;
> +
> + ?// If the buffer isn't big enough, bail.
> + ?if ((ResultBuf + bytesToWrite) >= ResultBufEnd) {
> + ? ?PP.Diag(Loc, diag::err_ucn_escape_too_big);
> + ? ?HadError = 1;
> + ? ?return;
> + ?}
This should be impossible: the largest UTF-8 character is 4 bytes, and
the smallest escape is 6 bytes.
> + ?static const UTF8 firstByteMark[7] = {
> + ? ?0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
> + ?};
The last 3 elements of this array are unused.
> + ?printf("%s (%d)\n", "hello \u2192 \u2603 \u2190 world", sizeof("hello \u2192 \u2603 \u2190 world"));
> + ?printf("%s (%d)\n", "\U00010400\U0001D12B", sizeof("\U00010400\U0001D12B"));
It would be nice to add a compile-time test, like "int a[sizeof("hello
\u2192 \u2603 \u2190 world") == 24 ? 1 : -1];".
I'm assuming you're aware this doesn't handle wide strings correctly...
-Eli
From mrs at apple.com Mon Mar 30 19:31:09 2009
From: mrs at apple.com (Mike Stump)
Date: Tue, 31 Mar 2009 00:31:09 -0000
Subject: [cfe-commits] r68078 - /cfe/tags/Apple/clang/Makefile
Message-ID: <200903310031.n2V0VAo7031162@zion.cs.uiuc.edu>
Author: mrs
Date: Mon Mar 30 19:31:08 2009
New Revision: 68078
URL: http://llvm.org/viewvc/llvm-project?rev=68078&view=rev
Log:
Avoid running svn for all targets.
Modified:
cfe/tags/Apple/clang/Makefile
Modified: cfe/tags/Apple/clang/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/tags/Apple/clang/Makefile?rev=68078&r1=68077&r2=68078&view=diff
==============================================================================
--- cfe/tags/Apple/clang/Makefile (original)
+++ cfe/tags/Apple/clang/Makefile Mon Mar 30 19:31:08 2009
@@ -62,9 +62,9 @@
$(INSTALL_FILE) $(Sources)/LICENSE.TXT $(OSL)/$(Project)-llvm.txt
$(INSTALL_FILE) $(Sources)/tools/clang/LICENSE.TXT $(OSL)/$(Project).txt
-SVN_BASE := $(shell svn info | sed -n 's/^URL: //; s,/llvm-project/.*$$,/llvm-project,p')
-SVN_CLANG := $(shell svn info | sed -n 's/^URL: //p')
-SVN_TAGS := $(shell dirname $(SVN_CLANG))
+SVN_BASE = $(shell svn info | sed -n 's/^URL: //; s,/llvm-project/.*$$,/llvm-project,p')
+SVN_CLANG = $(shell svn info | sed -n 's/^URL: //p')
+SVN_TAGS = $(shell dirname $(SVN_CLANG))
update-clang:
svn rm -m 'Update.' $(SVN_CLANG)/clang
From dgregor at apple.com Mon Mar 30 19:43:59 2009
From: dgregor at apple.com (Douglas Gregor)
Date: Tue, 31 Mar 2009 00:43:59 -0000
Subject: [cfe-commits] r68081 - in /cfe/trunk:
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/TemplateKinds.h include/clang/Parse/Action.h
lib/AST/ASTContext.cpp lib/AST/Type.cpp lib/Parse/MinimalAction.cpp
lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp
lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp
lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp
lib/Sema/SemaTemplateInstantiate.cpp test/SemaTemplate/metafun-apply.cpp
test/SemaTemplate/nested-name-spec-template.cpp
Message-ID: <200903310043.n2V0hxd0031748@zion.cs.uiuc.edu>
Author: dgregor
Date: Mon Mar 30 19:43:58 2009
New Revision: 68081
URL: http://llvm.org/viewvc/llvm-project?rev=68081&view=rev
Log:
Parsing and AST representation for dependent template names that occur
within nested-name-specifiers, e.g., for the "apply" in
typename MetaFun::template apply::type
At present, we can't instantiate these nested-name-specifiers, so our
testing is sketchy.
Added:
cfe/trunk/test/SemaTemplate/metafun-apply.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Basic/TemplateKinds.h
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Parse/MinimalAction.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar 30 19:43:58 2009
@@ -699,6 +699,9 @@
def note_typename_refers_here : Note<
"referenced member %0 is declared here">;
+def err_template_kw_refers_to_non_template : Error<
+ "%0 following the 'template' keyword does not refer to a template">;
+
def err_unexpected_typedef : Error<
"unexpected type name %0: expected expression">;
def err_unexpected_namespace : Error<
Modified: cfe/trunk/include/clang/Basic/TemplateKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TemplateKinds.h?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TemplateKinds.h (original)
+++ cfe/trunk/include/clang/Basic/TemplateKinds.h Mon Mar 30 19:43:58 2009
@@ -22,12 +22,14 @@
/// The name refers to a function template or a set of overloaded
/// functions that includes at least one function template.
TNK_Function_template,
- /// The name refers to a class template.
- TNK_Class_template,
- /// The name referes to a template template parameter.
- TNK_Template_template_parm,
- /// The name is dependent and is known to be a template name based
- /// on syntax, e.g., "Alloc::template rebind".
+ /// The name refers to a template whose specialization produces a
+ /// type. The template itself could be a class template, template
+ /// template parameter, or C++0x template alias.
+ TNK_Type_template,
+ /// The name refers to a dependent template name. Whether the
+ /// template name is assumed to refer to a type template or a
+ /// function template depends on the context in which the template
+ /// name occurs.
TNK_Dependent_template_name
};
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Mar 30 19:43:58 2009
@@ -157,7 +157,7 @@
/// returned, and \p TemplateDecl receives the declaration. An
/// optional CXXScope can be passed to indicate the C++ scope in
/// which the identifier will be found.
- virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
+ virtual TemplateNameKind isTemplateName(const IdentifierInfo &II, Scope *S,
TemplateTy &Template,
const CXXScopeSpec *SS = 0) = 0;
@@ -1229,6 +1229,20 @@
return TypeResult();
};
+ /// \brief Form a dependent template name.
+ ///
+ /// This action forms a dependent template name given the template
+ /// name and its (presumably dependent) scope specifier. For
+ /// example, given "MetaFun::template apply", the scope specifier \p
+ /// SS will be "MetaFun::", \p TemplateKWLoc contains the location
+ /// of the "template" keyword, and "apply" is the \p Name.
+ virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+ const IdentifierInfo &Name,
+ SourceLocation NameLoc,
+ const CXXScopeSpec &SS) {
+ return TemplateTy();
+ }
+
/// \brief Process the declaration or definition of an explicit
/// class template specialization or a class template partial
/// specialization.
@@ -1568,7 +1582,7 @@
virtual bool isCurrentClassName(const IdentifierInfo& II, Scope *S,
const CXXScopeSpec *SS);
- virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
+ virtual TemplateNameKind isTemplateName(const IdentifierInfo &II, Scope *S,
TemplateTy &Template,
const CXXScopeSpec *SS = 0);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Mar 30 19:43:58 2009
@@ -1373,8 +1373,6 @@
const TemplateArgument *Args,
unsigned NumArgs,
QualType Canon) {
- // FIXME: If Template is dependent, canonicalize it!
-
if (!Canon.isNull())
Canon = getCanonicalType(Canon);
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Mon Mar 30 19:43:58 2009
@@ -94,8 +94,12 @@
if (const TypeOfType *TOT = dyn_cast(this))
return TOT->getUnderlyingType().getDesugaredType();
if (const TemplateSpecializationType *Spec
- = dyn_cast(this))
- return Spec->getCanonicalTypeInternal().getDesugaredType();
+ = dyn_cast(this)) {
+ QualType Canon = Spec->getCanonicalTypeInternal();
+ if (Canon->getAsTemplateSpecializationType())
+ return QualType(this, 0);
+ return Canon->getDesugaredType();
+ }
if (const QualifiedNameType *QualName = dyn_cast(this))
return QualName->getNamedType().getDesugaredType();
Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Mon Mar 30 19:43:58 2009
@@ -134,7 +134,7 @@
}
TemplateNameKind
-MinimalAction::isTemplateName(IdentifierInfo &II, Scope *S,
+MinimalAction::isTemplateName(const IdentifierInfo &II, Scope *S,
TemplateTy &TemplateDecl,
const CXXScopeSpec *SS) {
return TNK_Non_template;
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Mar 30 19:43:58 2009
@@ -513,7 +513,7 @@
Token Next = NextToken();
if (Next.is(tok::annot_template_id) &&
static_cast(Next.getAnnotationValue())
- ->Kind == TNK_Class_template) {
+ ->Kind == TNK_Type_template) {
// We have a qualified template-id, e.g., N::A
CXXScopeSpec SS;
ParseOptionalCXXScopeSpecifier(SS);
@@ -640,7 +640,7 @@
case tok::annot_template_id: {
TemplateIdAnnotation *TemplateId
= static_cast(Tok.getAnnotationValue());
- if (TemplateId->Kind != TNK_Class_template) {
+ if (TemplateId->Kind != TNK_Type_template) {
// This template-id does not refer to a type name, so we're
// done with the type-specifiers.
goto DoneWithDeclSpec;
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Mar 30 19:43:58 2009
@@ -307,7 +307,7 @@
if (Tok.is(tok::annot_template_id)) {
TemplateIdAnnotation *TemplateId
= static_cast(Tok.getAnnotationValue());
- if (TemplateId->Kind == TNK_Class_template) {
+ if (TemplateId->Kind == TNK_Type_template) {
if (AnnotateTemplateIdTokenAsType(SS))
return 0;
@@ -419,7 +419,7 @@
TemplateId = static_cast(Tok.getAnnotationValue());
NameLoc = ConsumeToken();
- if (TemplateId->Kind != TNK_Class_template) {
+ if (TemplateId->Kind != TNK_Type_template) {
// The template-name in the simple-template-id refers to
// something other than a class template. Give an appropriate
// error message and skip to the ';'.
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Mar 30 19:43:58 2009
@@ -92,9 +92,8 @@
Tok.is(tok::kw_template)) {
// Parse the optional 'template' keyword, then make sure we have
// 'identifier <' after it.
- SourceLocation TemplateKWLoc;
if (Tok.is(tok::kw_template)) {
- TemplateKWLoc = ConsumeToken();
+ SourceLocation TemplateKWLoc = ConsumeToken();
if (Tok.isNot(tok::identifier)) {
Diag(Tok.getLocation(),
@@ -110,20 +109,20 @@
<< SourceRange(TemplateKWLoc, Tok.getLocation());
break;
}
- }
- else {
- // FIXME: If the nested-name-specifier thus far is dependent,
- // we need to break out of here, because this '<' is taken as
- // an operator and not as part of a simple-template-id.
+
+ TemplateTy Template
+ = Actions.ActOnDependentTemplateName(TemplateKWLoc,
+ *Tok.getIdentifierInfo(),
+ Tok.getLocation(),
+ SS);
+ AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
+ &SS, TemplateKWLoc, false);
+ continue;
}
TemplateTy Template;
- TemplateNameKind TNK = TNK_Non_template;
- // FIXME: If the nested-name-specifier thus far is dependent,
- // set TNK = TNK_Dependent_template_name and skip the
- // "isTemplateName" check.
- TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(),
- CurScope, Template, &SS);
+ TemplateNameKind TNK = Actions.isTemplateName(*Tok.getIdentifierInfo(),
+ CurScope, Template, &SS);
if (TNK) {
// We have found a template name, so annotate this this token
// with a template-id annotation. We do not permit the
@@ -131,7 +130,7 @@
// because some clients (e.g., the parsing of class template
// specializations) still want to see the original template-id
// token.
- AnnotateTemplateIdToken(Template, TNK, &SS, TemplateKWLoc, false);
+ AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false);
continue;
}
}
@@ -142,12 +141,13 @@
// simple-template-id '::'
//
// So we need to check whether the simple-template-id is of the
- // right kind (it should name a type), and then convert it into
- // a type within the nested-name-specifier.
+ // right kind (it should name a type or be dependent), and then
+ // convert it into a type within the nested-name-specifier.
TemplateIdAnnotation *TemplateId
= static_cast(Tok.getAnnotationValue());
- if (TemplateId->Kind == TNK_Class_template) {
+ if (TemplateId->Kind == TNK_Type_template ||
+ TemplateId->Kind == TNK_Dependent_template_name) {
if (AnnotateTemplateIdTokenAsType(&SS))
SS.clear();
@@ -172,7 +172,7 @@
SS.setEndLoc(CCLoc);
continue;
} else
- assert(false && "FIXME: Only class template names supported here");
+ assert(false && "FIXME: Only type template names supported here");
}
// We don't have any tokens that form the beginning of a
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Mar 30 19:43:58 2009
@@ -531,8 +531,7 @@
return;
// Build the annotation token.
- // FIXME: Not just for class templates!
- if (TNK == TNK_Class_template && AllowTypeAnnotation) {
+ if (TNK == TNK_Type_template && AllowTypeAnnotation) {
Action::TypeResult Type
= Actions.ActOnTemplateIdType(Template, TemplateNameLoc,
LAngleLoc, TemplateArgsPtr,
@@ -550,8 +549,8 @@
else
Tok.setLocation(TemplateNameLoc);
} else {
- // This is a function template. We'll be building a template-id
- // annotation token.
+ // Build a template-id annotation token that can be processed
+ // later.
Tok.setKind(tok::annot_template_id);
TemplateIdAnnotation *TemplateId
= TemplateIdAnnotation::Allocate(TemplateArgs.size());
@@ -595,8 +594,9 @@
TemplateIdAnnotation *TemplateId
= static_cast(Tok.getAnnotationValue());
- assert(TemplateId->Kind == TNK_Class_template &&
- "Only works for class templates");
+ assert((TemplateId->Kind == TNK_Type_template ||
+ TemplateId->Kind == TNK_Dependent_template_name) &&
+ "Only works for type and dependent templates");
ASTTemplateArgsPtr TemplateArgsPtr(Actions,
TemplateId->getTemplateArgs(),
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Mar 30 19:43:58 2009
@@ -901,7 +901,7 @@
if (Tok.is(tok::annot_template_id)) {
TemplateIdAnnotation *TemplateId
= static_cast(Tok.getAnnotationValue());
- if (TemplateId->Kind == TNK_Class_template) {
+ if (TemplateId->Kind == TNK_Type_template) {
// A template-id that refers to a type was parsed into a
// template-id annotation in a context where we weren't allowed
// to produce a type annotation token. Update the template-id
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Mar 30 19:43:58 2009
@@ -1690,7 +1690,7 @@
//===--------------------------------------------------------------------===//
// C++ Templates [C++ 14]
//
- virtual TemplateNameKind isTemplateName(IdentifierInfo &II, Scope *S,
+ virtual TemplateNameKind isTemplateName(const IdentifierInfo &II, Scope *S,
TemplateTy &Template,
const CXXScopeSpec *SS = 0);
bool DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl);
@@ -1756,6 +1756,11 @@
SourceLocation *TemplateArgLocs,
SourceLocation RAngleLoc);
+ virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+ const IdentifierInfo &Name,
+ SourceLocation NameLoc,
+ const CXXScopeSpec &SS);
+
bool CheckClassTemplateSpecializationScope(ClassTemplateDecl *ClassTemplate,
ClassTemplateSpecializationDecl *PrevDecl,
SourceLocation TemplateNameLoc,
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Mar 30 19:43:58 2009
@@ -26,7 +26,7 @@
/// declaration if II names a template. An optional CXXScope can be
/// passed to indicate the C++ scope in which the identifier will be
/// found.
-TemplateNameKind Sema::isTemplateName(IdentifierInfo &II, Scope *S,
+TemplateNameKind Sema::isTemplateName(const IdentifierInfo &II, Scope *S,
TemplateTy &TemplateResult,
const CXXScopeSpec *SS) {
NamedDecl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
@@ -38,10 +38,9 @@
if ((Template = dyn_cast(IIDecl))) {
if (isa(IIDecl))
TNK = TNK_Function_template;
- else if (isa(IIDecl))
- TNK = TNK_Class_template;
- else if (isa(IIDecl))
- TNK = TNK_Template_template_parm;
+ else if (isa(IIDecl) ||
+ isa(IIDecl))
+ TNK = TNK_Type_template;
else
assert(false && "Unknown template declaration kind");
} else if (CXXRecordDecl *Record = dyn_cast(IIDecl)) {
@@ -59,11 +58,11 @@
if (Record->isInjectedClassName()) {
Record = cast(Context.getCanonicalDecl(Record));
if ((Template = Record->getDescribedClassTemplate()))
- TNK = TNK_Class_template;
+ TNK = TNK_Type_template;
else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast(Record)) {
Template = Spec->getSpecializedTemplate();
- TNK = TNK_Class_template;
+ TNK = TNK_Type_template;
}
}
}
@@ -716,6 +715,56 @@
}
}
+/// \brief Build a canonical version of a template argument list.
+///
+/// This function builds a canonical version of the given template
+/// argument list, where each of the template arguments has been
+/// converted into its canonical form. This routine is typically used
+/// to canonicalize a template argument list when the template name
+/// itself is dependent. When the template name refers to an actual
+/// template declaration, Sema::CheckTemplateArgumentList should be
+/// used to check and canonicalize the template arguments.
+///
+/// \param TemplateArgs The incoming template arguments.
+///
+/// \param NumTemplateArgs The number of template arguments in \p
+/// TemplateArgs.
+///
+/// \param Canonical A vector to be filled with the canonical versions
+/// of the template arguments.
+///
+/// \param Context The ASTContext in which the template arguments live.
+static void CanonicalizeTemplateArguments(const TemplateArgument *TemplateArgs,
+ unsigned NumTemplateArgs,
+ llvm::SmallVectorImpl &Canonical,
+ ASTContext &Context) {
+ Canonical.reserve(NumTemplateArgs);
+ for (unsigned Idx = 0; Idx < NumTemplateArgs; ++Idx) {
+ switch (TemplateArgs[Idx].getKind()) {
+ case TemplateArgument::Expression:
+ // FIXME: Build canonical expression (!)
+ Canonical.push_back(TemplateArgs[Idx]);
+ break;
+
+ case TemplateArgument::Declaration:
+ Canonical.push_back(TemplateArgument(SourceLocation(),
+ TemplateArgs[Idx].getAsDecl()));
+ break;
+
+ case TemplateArgument::Integral:
+ Canonical.push_back(TemplateArgument(SourceLocation(),
+ *TemplateArgs[Idx].getAsIntegral(),
+ TemplateArgs[Idx].getIntegralType()));
+
+ case TemplateArgument::Type: {
+ QualType CanonType
+ = Context.getCanonicalType(TemplateArgs[Idx].getAsType());
+ Canonical.push_back(TemplateArgument(SourceLocation(), CanonType));
+ }
+ }
+ }
+}
+
QualType Sema::CheckTemplateIdType(TemplateName Name,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
@@ -723,7 +772,25 @@
unsigned NumTemplateArgs,
SourceLocation RAngleLoc) {
TemplateDecl *Template = Name.getAsTemplateDecl();
- assert(Template && "Cannot handle dependent template-names yet");
+ if (!Template) {
+ // The template name does not resolve to a template, so we just
+ // build a dependent template-id type.
+
+ // Canonicalize the template arguments to build the canonical
+ // template-id type.
+ llvm::SmallVector CanonicalTemplateArgs;
+ CanonicalizeTemplateArguments(TemplateArgs, NumTemplateArgs,
+ CanonicalTemplateArgs, Context);
+
+ // FIXME: Get the canonical template-name
+ QualType CanonType
+ = Context.getTemplateSpecializationType(Name, &CanonicalTemplateArgs[0],
+ CanonicalTemplateArgs.size());
+
+ // Build the dependent template-id type.
+ return Context.getTemplateSpecializationType(Name, TemplateArgs,
+ NumTemplateArgs, CanonType);
+ }
// Check that the template argument list is well-formed for this
// template.
@@ -808,6 +875,57 @@
return Result.getAsOpaquePtr();
}
+/// \brief Form a dependent template name.
+///
+/// This action forms a dependent template name given the template
+/// name and its (presumably dependent) scope specifier. For
+/// example, given "MetaFun::template apply", the scope specifier \p
+/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
+/// of the "template" keyword, and "apply" is the \p Name.
+Sema::TemplateTy
+Sema::ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
+ const IdentifierInfo &Name,
+ SourceLocation NameLoc,
+ const CXXScopeSpec &SS) {
+ if (!SS.isSet() || SS.isInvalid())
+ return TemplateTy();
+
+ NestedNameSpecifier *Qualifier
+ = static_cast(SS.getScopeRep());
+
+ // FIXME: member of the current instantiation
+
+ if (!Qualifier->isDependent()) {
+ // C++0x [temp.names]p5:
+ // If a name prefixed by the keyword template is not the name of
+ // a template, the program is ill-formed. [Note: the keyword
+ // template may not be applied to non-template members of class
+ // templates. -end note ] [ Note: as is the case with the
+ // typename prefix, the template prefix is allowed in cases
+ // where it is not strictly necessary; i.e., when the
+ // nested-name-specifier or the expression on the left of the ->
+ // or . is not dependent on a template-parameter, or the use
+ // does not appear in the scope of a template. -end note]
+ //
+ // Note: C++03 was more strict here, because it banned the use of
+ // the "template" keyword prior to a template-name that was not a
+ // dependent name. C++ DR468 relaxed this requirement (the
+ // "template" keyword is now permitted). We follow the C++0x
+ // rules, even in C++03 mode, retroactively applying the DR.
+ TemplateTy Template;
+ TemplateNameKind TNK = isTemplateName(Name, 0, Template, &SS);
+ if (TNK == TNK_Non_template) {
+ Diag(NameLoc, diag::err_template_kw_refers_to_non_template)
+ << &Name;
+ return TemplateTy();
+ }
+
+ return Template;
+ }
+
+ return TemplateTy::make(Context.getDependentTemplateName(Qualifier, &Name));
+}
+
/// \brief Check that the given template argument list is well-formed
/// for specializing the given template.
bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Mar 30 19:43:58 2009
@@ -475,7 +475,7 @@
// FIXME: Need to instantiate into the template name.
return SemaRef.CheckTemplateIdType(T->getTemplateName(),
Loc,
- SourceLocation(),
+ SourceLocation(),
&InstantiatedTemplateArgs[0],
InstantiatedTemplateArgs.size(),
SourceLocation());
Added: cfe/trunk/test/SemaTemplate/metafun-apply.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/metafun-apply.cpp?rev=68081&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/metafun-apply.cpp (added)
+++ cfe/trunk/test/SemaTemplate/metafun-apply.cpp Mon Mar 30 19:43:58 2009
@@ -0,0 +1,29 @@
+// RUN: clang-cc -fsyntax-only %s
+
+struct add_pointer {
+ template
+ struct apply {
+ typedef T* type;
+ };
+};
+
+struct add_reference {
+ template
+ struct apply {
+ typedef T& type;
+ };
+};
+
+template
+struct apply1 {
+ typedef typename MetaFun::template apply::type type;
+};
+
+#if 0
+// FIXME: The code below requires template instantiation for dependent
+// template-names that occur within nested-name-specifiers.
+int i;
+
+apply1::type ip = &i;
+apply1::type ir = i;
+#endif
Modified: cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp?rev=68081&r1=68080&r2=68081&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/nested-name-spec-template.cpp Mon Mar 30 19:43:58 2009
@@ -42,8 +42,21 @@
struct A {
struct X;
};
+
+ struct B;
}
struct ::N::A::X {
int foo;
};
+
+#if 0
+// FIXME: the following crashes the parser, because Sema has no way to
+// community that the "dependent" template-name N::template B doesn't
+// actually refer to a template.
+template
+struct TestA {
+ typedef typename N::template B::type type; // xpected-error{{'B' following the 'template' keyword does not refer to a template}}
+ // FIXME: should show what B *does* refer to.
+};
+#endif
From eli.friedman at gmail.com Mon Mar 30 19:47:51 2009
From: eli.friedman at gmail.com (Eli Friedman)
Date: Mon, 30 Mar 2009 17:47:51 -0700
Subject: [cfe-commits] r68081 - in /cfe/trunk:
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/TemplateKinds.h
include/clang/Parse/Action.h lib/AST/ASTContext.cpp
lib/AST/Type.cpp lib/Parse/MinimalAction.cpp
lib/Parse/ParseDecl.cpp lib/Pars
Message-ID:
On Mon, Mar 30, 2009 at 5:43 PM, Douglas Gregor wrote:
> + ? ?// Note: C++03 was more strict here, because it banned the use of
> + ? ?// the "template" keyword prior to a template-name that was not a
> + ? ?// dependent name. C++ DR468 relaxed this requirement (the
> + ? ?// "template" keyword is now permitted). We follow the C++0x
> + ? ?// rules, even in C++03 mode, retroactively applying the DR.
Maybe an extension warning would be appropriate here?
-Eli
From kremenek at apple.com Mon Mar 30 22:34:43 2009
From: kremenek at apple.com (Ted Kremenek)
Date: Tue, 31 Mar 2009 03:34:43 -0000
Subject: [cfe-commits] r68084 - /cfe/trunk/test/Analysis/dead-stores.c
Message-ID: <200903310334.n2V3YhNc005111@zion.cs.uiuc.edu>
Author: kremenek
Date: Mon Mar 30 22:34:38 2009
New Revision: 68084
URL: http://llvm.org/viewvc/llvm-project?rev=68084&view=rev
Log:
Update test case.
Modified:
cfe/trunk/test/Analysis/dead-stores.c
Modified: cfe/trunk/test/Analysis/dead-stores.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dead-stores.c?rev=68084&r1=68083&r2=68084&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/dead-stores.c (original)
+++ cfe/trunk/test/Analysis/dead-stores.c Mon Mar 30 22:34:38 2009
@@ -161,9 +161,9 @@
return x;
}
-int f19b(void) { // FIXME: Should this case be considered the same as f19?
+int f19b(void) { // This case is the same as f19.
const int MyConstant = 0;
- int x = MyConstant; // expected-warning{{never read}}
+ int x = MyConstant; // no-warning
x = 1;
return x;
}
From dgregor at apple.com Mon Mar 30 22:39:08 2009
From: dgregor at apple.com (Douglas Gregor)
Date: Mon, 30 Mar 2009 20:39:08 -0700
Subject: [cfe-commits] r68081 - in /cfe/trunk:
include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/TemplateKinds.h
include/clang/Parse/Action.h lib/AST/ASTContext.cpp lib/AST/Type.cpp
lib/Parse/MinimalAction.cpp lib/Parse/ParseDecl.cpp lib/Pars
In-Reply-To:
References:
Message-ID:
On Mar 30, 2009, at 5:47 PM, Eli Friedman wrote:
> On Mon, Mar 30, 2009 at 5:43 PM, Douglas Gregor
> wrote:
>> + // Note: C++03 was more strict here, because it banned the use
>> of
>> + // the "template" keyword prior to a template-name that was
>> not a
>> + // dependent name. C++ DR468 relaxed this requirement (the
>> + // "template" keyword is now permitted). We follow the C++0x
>> + // rules, even in C++03 mode, retroactively applying the DR.
>
> Maybe an extension warning would be appropriate here?
I've gone back and forth on this one. It's my understanding that a DR
retroactively applies to previous standards (since it fixes a defect
in that standard). Moreover, the whole point of DR468 is that it is
there to help users and library developers who generate code where
special-casing the non-dependent case leads to a big mess. Those
clients would probably not use the feature if it emitted an extension
warning.
- Doug
From andersca at mac.com Mon Mar 30 23:51:13 2009
From: andersca at mac.com (Anders Carlsson)
Date: Tue, 31 Mar 2009 04:51:13 -0000
Subject: [cfe-commits] r68085 - /cfe/trunk/include/clang/AST/DeclCXX.h
Message-ID: <200903310451.n2V4pEf8007472@zion.cs.uiuc.edu>
Author: andersca
Date: Mon Mar 30 23:51:13 2009
New Revision: 68085
URL: http://llvm.org/viewvc/llvm-project?rev=68085&view=rev
Log:
Document NamespaceAliasDecl.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=68085&r1=68084&r2=68085&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Mar 30 23:51:13 2009
@@ -957,6 +957,11 @@
friend class DeclContext;
};
+/// NamespaceAliasDecl - Represents a C++ namespace alias. For example:
+///
+/// @code
+/// namespace Foo = Bar;
+/// @endcode
class NamespaceAliasDecl : public NamedDecl {
SourceLocation AliasLoc;
From andersca at mac.com Tue Mar 31 00:47:20 2009
From: andersca at mac.com (Anders Carlsson)
Date: Tue, 31 Mar 2009 05:47:20 -0000
Subject: [cfe-commits] r68086 - /cfe/trunk/test/SemaCXX/namespace-alias.cpp
Message-ID: <200903310547.n2V5lKnh009216@zion.cs.uiuc.edu>
Author: andersca
Date: Tue Mar 31 00:47:19 2009
New Revision: 68086
URL: http://llvm.org/viewvc/llvm-project?rev=68086&view=rev
Log:
Check in test for namespace aliases+using directives.
Modified:
cfe/trunk/test/SemaCXX/namespace-alias.cpp
Modified: cfe/trunk/test/SemaCXX/namespace-alias.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/namespace-alias.cpp?rev=68086&r1=68085&r2=68086&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/namespace-alias.cpp (original)
+++ cfe/trunk/test/SemaCXX/namespace-alias.cpp Tue Mar 31 00:47:19 2009
@@ -48,3 +48,17 @@
int f() {
return I::A2::i;
}
+
+namespace J {
+ namespace A {
+ namespace B { void func (); }
+ }
+
+ namespace C = A;
+
+ using namespace C::B;
+
+ void g() {
+ func();
+ }
+}
From sebastian.redl at getdesigned.at Tue Mar 31 01:13:26 2009
From: sebastian.redl at getdesigned.at (Sebastian Redl)
Date: Tue, 31 Mar 2009 08:13:26 +0200
Subject: [cfe-commits]
=?utf-8?q?r68081_-_in_/cfe/trunk=3A_include/clang/B?=
=?utf-8?q?asic/DiagnosticSemaKinds=2Etd=09include/clang/Basic/TemplateKin?=
=?utf-8?q?ds=2Eh_include/clang/Parse/Action=2Eh=09lib/AST/ASTContext=2Ecp?=
=?utf-8?q?p_lib/AST/Type=2Ecpp_lib/Parse/MinimalAction=2Ecpp=09lib/Parse/?=
=?utf-8?q?ParseDecl=2Ecpp_lib/Pars?=
In-Reply-To:
References:
Message-ID: <2a4712f537279445b808e176fc26c7d8@localhost>
On Mon, 30 Mar 2009 20:39:08 -0700, Douglas Gregor
wrote:
> On Mar 30, 2009, at 5:47 PM, Eli Friedman wrote:
>
>> On Mon, Mar 30, 2009 at 5:43 PM, Douglas Gregor
>> wrote:
>>> + // Note: C++03 was more strict here, because it banned the use
>>> of
>>> + // the "template" keyword prior to a template-name that was
>>> not a
>>> + // dependent name. C++ DR468 relaxed this requirement (the
>>> + // "template" keyword is now permitted). We follow the C++0x
>>> + // rules, even in C++03 mode, retroactively applying the DR.
>>
>> Maybe an extension warning would be appropriate here?
>
> I've gone back and forth on this one. It's my understanding that a DR
> retroactively applies to previous standards (since it fixes a defect
> in that standard). Moreover, the whole point of DR468 is that it is
> there to help users and library developers who generate code where
> special-casing the non-dependent case leads to a big mess. Those
> clients would probably not use the feature if it emitted an extension
> warning.
>
I agree. I think DRs should be made to apply in our implementation of
C++03, even if they were only introduced with C++0x.
Sebastian
From sabre at nondot.org Tue Mar 31 02:46:54 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 31 Mar 2009 07:46:54 -0000
Subject: [cfe-commits] r68088 - in /cfe/trunk:
include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp
test/CodeGen/ext-vector.c test/Sema/exprs.c
Message-ID: <200903310746.n2V7ksIO015135@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Mar 31 02:46:52 2009
New Revision: 68088
URL: http://llvm.org/viewvc/llvm-project?rev=68088&view=rev
Log:
Codegen sometimes crashes on comparisons that aren't legal, just
disable this feature for now, to err on the side of rejecting instead
of sometimes crashing. rdar://6326239
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/CodeGen/ext-vector.c
cfe/trunk/test/Sema/exprs.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=68088&r1=68087&r2=68088&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 31 02:46:52 2009
@@ -948,6 +948,8 @@
"comparison between pointer and integer (%0 and %1)">;
def ext_typecheck_comparison_of_distinct_pointers : Warning<
"comparison of distinct pointer types (%0 and %1)">;
+def err_typecheck_vector_comparison : Error<
+ "comparison of vector types (%0 and %1) not supported yet">;
def err_typecheck_assign_const : Error<"read-only variable is not assignable">;
def err_stmtexpr_file_scope : Error<
"statement expression not allowed at file scope">;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=68088&r1=68087&r2=68088&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Mar 31 02:46:52 2009
@@ -3566,6 +3566,14 @@
CheckFloatComparison(Loc,lex,rex);
}
+ // FIXME: Vector compare support in the LLVM backend is not fully reliable,
+ // just reject all vector comparisons for now.
+ if (1) {
+ Diag(Loc, diag::err_typecheck_vector_comparison)
+ << lType << rType << lex->getSourceRange() << rex->getSourceRange();
+ return QualType();
+ }
+
// Return the type for the comparison, which is the same as vector type for
// integer vectors, or an integer type of identical size and number of
// elements for floating point vectors.
@@ -3576,7 +3584,7 @@
unsigned TypeSize = Context.getTypeSize(VTy->getElementType());
if (TypeSize == Context.getTypeSize(Context.IntTy))
return Context.getExtVectorType(Context.IntTy, VTy->getNumElements());
- else if (TypeSize == Context.getTypeSize(Context.LongTy))
+ if (TypeSize == Context.getTypeSize(Context.LongTy))
return Context.getExtVectorType(Context.LongTy, VTy->getNumElements());
assert(TypeSize == Context.getTypeSize(Context.LongLongTy) &&
Modified: cfe/trunk/test/CodeGen/ext-vector.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ext-vector.c?rev=68088&r1=68087&r2=68088&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/ext-vector.c (original)
+++ cfe/trunk/test/CodeGen/ext-vector.c Tue Mar 31 02:46:52 2009
@@ -74,14 +74,17 @@
a *= c;
a /= c;
+ // Vector comparisons can sometimes crash the x86 backend: rdar://6326239,
+ // reject them until the implementation is stable.
+#if 0
int4 cmp;
-
cmp = a < b;
cmp = a <= b;
cmp = a < b;
cmp = a >= b;
cmp = a == b;
cmp = a != b;
+#endif
}
void test7(int4 *ap, int4 *bp, int c) {
@@ -112,12 +115,15 @@
a /= c;
a %= c;
+ // Vector comparisons can sometimes crash the x86 backend: rdar://6326239,
+ // reject them until the implementation is stable.
+#if 0
int4 cmp;
-
cmp = a < b;
cmp = a <= b;
cmp = a < b;
cmp = a >= b;
cmp = a == b;
cmp = a != b;
+#endif
}
Modified: cfe/trunk/test/Sema/exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/exprs.c?rev=68088&r1=68087&r2=68088&view=diff
==============================================================================
--- cfe/trunk/test/Sema/exprs.c (original)
+++ cfe/trunk/test/Sema/exprs.c Tue Mar 31 02:46:52 2009
@@ -91,3 +91,16 @@
P();
P = ^(){}; // expected-error {{blocks support disabled - compile with -fblocks}}
}
+
+
+// rdar://6326239 - Vector comparisons are not fully trusted yet, until the
+// backend is known to work, just unconditionally reject them.
+void test14() {
+ typedef long long __m64 __attribute__((__vector_size__(8))); // expected-warning {{extension used}}
+ typedef short __v4hi __attribute__((__vector_size__(8))); // expected-warning {{extension used}}
+
+ __v4hi a;
+ __m64 mask = (__m64)((__v4hi)a > // expected-error {{comparison of vector types ('__v4hi' and '__v4hi') not supported yet}}
+ (__v4hi)a);
+}
+
From sabre at nondot.org Tue Mar 31 03:18:49 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 31 Mar 2009 08:18:49 -0000
Subject: [cfe-commits] r68091 - /cfe/trunk/lib/Sema/SemaExpr.cpp
Message-ID: <200903310818.n2V8InUk021415@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Mar 31 03:18:48 2009
New Revision: 68091
URL: http://llvm.org/viewvc/llvm-project?rev=68091&view=rev
Log:
reduce nesting.
Modified:
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=68091&r1=68090&r2=68091&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Mar 31 03:18:48 2009
@@ -1783,16 +1783,16 @@
= LookupQualifiedName(RDecl, DeclarationName(&Member),
LookupMemberName, false);
- NamedDecl *MemberDecl = 0;
if (!Result)
return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member)
<< &Member << BaseExpr->getSourceRange());
- else if (Result.isAmbiguous()) {
+ if (Result.isAmbiguous()) {
DiagnoseAmbiguousLookup(Result, DeclarationName(&Member),
MemberLoc, BaseExpr->getSourceRange());
return ExprError();
- } else
- MemberDecl = Result;
+ }
+
+ NamedDecl *MemberDecl = Result;
// If the decl being referenced had an error, return an error for this
// sub-expr without emitting another error, in order to avoid cascading
@@ -1826,21 +1826,24 @@
return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow, FD,
MemberLoc, MemberType));
- } else if (VarDecl *Var = dyn_cast(MemberDecl))
+ }
+
+ if (VarDecl *Var = dyn_cast(MemberDecl))
return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow,
- Var, MemberLoc,
- Var->getType().getNonReferenceType()));
- else if (FunctionDecl *MemberFn = dyn_cast(MemberDecl))
+ Var, MemberLoc,
+ Var->getType().getNonReferenceType()));
+ if (FunctionDecl *MemberFn = dyn_cast(MemberDecl))
return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow,
- MemberFn, MemberLoc, MemberFn->getType()));
- else if (OverloadedFunctionDecl *Ovl
- = dyn_cast(MemberDecl))
+ MemberFn, MemberLoc,
+ MemberFn->getType()));
+ if (OverloadedFunctionDecl *Ovl
+ = dyn_cast(MemberDecl))
return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow, Ovl,
- MemberLoc, Context.OverloadTy));
- else if (EnumConstantDecl *Enum = dyn_cast(MemberDecl))
+ MemberLoc, Context.OverloadTy));
+ if (EnumConstantDecl *Enum = dyn_cast(MemberDecl))
return Owned(new (Context) MemberExpr(BaseExpr, OpKind == tok::arrow,
Enum, MemberLoc, Enum->getType()));
- else if (isa(MemberDecl))
+ if (isa(MemberDecl))
return ExprError(Diag(MemberLoc,diag::err_typecheck_member_reference_type)
<< DeclarationName(&Member) << int(OpKind == tok::arrow));
@@ -1887,6 +1890,7 @@
dyn_cast(ImplDecl))
ClassOfMethodDecl = CatImplClass->getClassInterface();
}
+
if (IV->getAccessControl() == ObjCIvarDecl::Private) {
if (ClassDeclared != IFTy->getDecl() ||
ClassOfMethodDecl != ClassDeclared)
From sabre at nondot.org Tue Mar 31 03:31:14 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 31 Mar 2009 08:31:14 -0000
Subject: [cfe-commits] r68094 - in /cfe/trunk: include/clang/AST/DeclObjC.h
lib/AST/ASTContext.cpp
Message-ID: <200903310831.n2V8VExv024990@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Mar 31 03:31:13 2009
New Revision: 68094
URL: http://llvm.org/viewvc/llvm-project?rev=68094&view=rev
Log:
add a const version of the lookupFieldDeclForIvar method.
Modified:
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/lib/AST/ASTContext.cpp
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=68094&r1=68093&r2=68094&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Tue Mar 31 03:31:13 2009
@@ -412,6 +412,11 @@
FieldDecl *lookupFieldDeclForIvar(ASTContext &Context,
const ObjCIvarDecl *ivar);
+ const FieldDecl *lookupFieldDeclForIvar(ASTContext &Ctx,
+ const ObjCIvarDecl *IV) const {
+ return const_cast(this)->lookupFieldDeclForIvar(Ctx,IV);
+ }
+
bool isForwardDecl() const { return ForwardDecl; }
void setForwardDecl(bool val) { ForwardDecl = val; }
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=68094&r1=68093&r2=68094&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Mar 31 03:31:13 2009
@@ -650,9 +650,7 @@
void ASTContext::setFieldDecl(const ObjCInterfaceDecl *OI,
const ObjCIvarDecl *Ivar,
const ObjCIvarRefExpr *MRef) {
- FieldDecl *FD = (const_cast(OI))->
- lookupFieldDeclForIvar(*this, Ivar);
- ASTFieldForIvarRef[MRef] = FD;
+ ASTFieldForIvarRef[MRef] = OI->lookupFieldDeclForIvar(*this, Ivar);
}
/// getASTObjcInterfaceLayout - Get or compute information about the layout of
From sabre at nondot.org Tue Mar 31 03:33:17 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 31 Mar 2009 08:33:17 -0000
Subject: [cfe-commits] r68095 - /cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Message-ID: <200903310833.n2V8XHcR025086@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Mar 31 03:33:16 2009
New Revision: 68095
URL: http://llvm.org/viewvc/llvm-project?rev=68095&view=rev
Log:
small cleanups.
Modified:
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=68095&r1=68094&r2=68095&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Tue Mar 31 03:33:16 2009
@@ -456,12 +456,12 @@
/// GetIvarBaseOffset - returns ivars byte offset.
uint64_t GetIvarBaseOffset(const llvm::StructLayout *Layout,
- FieldDecl *Field);
+ const FieldDecl *Field);
- /// GetFieldBaseOffset - return's field byt offset.
+ /// GetFieldBaseOffset - return's field byte offset.
uint64_t GetFieldBaseOffset(const ObjCInterfaceDecl *OI,
const llvm::StructLayout *Layout,
- FieldDecl *Field);
+ const FieldDecl *Field);
/// CreateMetadataVar - Create a global variable with internal
/// linkage for use by the Objective-C runtime.
@@ -1829,7 +1829,7 @@
}
uint64_t CGObjCCommonMac::GetIvarBaseOffset(const llvm::StructLayout *Layout,
- FieldDecl *Field) {
+ const FieldDecl *Field) {
if (!Field->isBitField())
return Layout->getElementOffset(
CGM.getTypes().getLLVMFieldNo(Field));
@@ -1844,12 +1844,10 @@
/// GetFieldBaseOffset - return's field byt offset.
uint64_t CGObjCCommonMac::GetFieldBaseOffset(const ObjCInterfaceDecl *OI,
const llvm::StructLayout *Layout,
- FieldDecl *Field) {
+ const FieldDecl *Field) {
const ObjCIvarDecl *Ivar = cast(Field);
- Field = const_cast(OI)->lookupFieldDeclForIvar(
- CGM.getContext(), Ivar);
- uint64_t Offset = GetIvarBaseOffset(Layout, Field);
- return Offset;
+ const FieldDecl *FD = OI->lookupFieldDeclForIvar(CGM.getContext(), Ivar);
+ return GetIvarBaseOffset(Layout, FD);
}
llvm::GlobalVariable *
From sabre at nondot.org Tue Mar 31 03:36:09 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 31 Mar 2009 08:36:09 -0000
Subject: [cfe-commits] r68098 - /cfe/trunk/lib/AST/DeclObjC.cpp
Message-ID: <200903310836.n2V8a9RB025204@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Mar 31 03:36:08 2009
New Revision: 68098
URL: http://llvm.org/viewvc/llvm-project?rev=68098&view=rev
Log:
simplify some casting
Modified:
cfe/trunk/lib/AST/DeclObjC.cpp
Modified: cfe/trunk/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclObjC.cpp?rev=68098&r1=68097&r2=68098&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclObjC.cpp (original)
+++ cfe/trunk/lib/AST/DeclObjC.cpp Tue Mar 31 03:36:08 2009
@@ -338,7 +338,7 @@
}
void ObjCInterfaceDecl::Destroy(ASTContext &C) {
- for (ivar_iterator I=ivar_begin(), E=ivar_end(); I!=E; ++I)
+ for (ivar_iterator I = ivar_begin(), E = ivar_end(); I != E; ++I)
if (*I) (*I)->Destroy(C);
IVars.Destroy(C);
@@ -371,13 +371,10 @@
const ObjCIvarDecl *IVar) {
const RecordDecl *RecordForDecl = Context.addRecordToClass(this);
assert(RecordForDecl && "lookupFieldDeclForIvar no storage for class");
- DeclarationName Member = IVar->getDeclName();
- DeclContext::lookup_result Lookup =
- (const_cast< RecordDecl *>(RecordForDecl))->lookup(Member);
+ DeclContext::lookup_const_result Lookup =
+ RecordForDecl->lookup(IVar->getDeclName());
assert((Lookup.first != Lookup.second) && "field decl not found");
- FieldDecl *MemberDecl = dyn_cast(*Lookup.first);
- assert(MemberDecl && "field decl not found");
- return MemberDecl;
+ return cast(*Lookup.first);
}
//===----------------------------------------------------------------------===//
From sabre at nondot.org Tue Mar 31 03:48:11 2009
From: sabre at nondot.org (Chris Lattner)
Date: Tue, 31 Mar 2009 08:48:11 -0000
Subject: [cfe-commits] r68101 - in /cfe/trunk:
include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp
lib/CodeGen/CGObjCMac.cpp
Message-ID: <200903310848.n2V8mDQ3025762@zion.cs.uiuc.edu>
Author: lattner
Date: Tue Mar 31 03:48:01 2009
New Revision: 68101
URL: http://llvm.org/viewvc/llvm-project?rev=68101&view=rev
Log:
fill in temporary smallvectors instead of vectors for performance.
Fix BuildAggrIvarLayout to not access vectors out of range.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=68101&r1=68100&r2=68101&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Mar 31 03:48:01 2009
@@ -492,7 +492,7 @@
const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
const RecordDecl *addRecordToClass(const ObjCInterfaceDecl *D);
void CollectObjCIvars(const ObjCInterfaceDecl *OI,
- std::vector &Fields) const;
+ llvm::SmallVectorImpl &Fields) const;
const FieldDecl *getFieldDecl(const ObjCIvarRefExpr *MRef) {
llvm::DenseMap::iterator I
= ASTFieldForIvarRef.find(MRef);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=68101&r1=68100&r2=68101&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Mar 31 03:48:01 2009
@@ -598,21 +598,20 @@
}
void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
- std::vector &Fields) const {
+ llvm::SmallVectorImpl &Fields) const {
const ObjCInterfaceDecl *SuperClass = OI->getSuperClass();
if (SuperClass)
CollectObjCIvars(SuperClass, Fields);
for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
E = OI->ivar_end(); I != E; ++I) {
- ObjCIvarDecl *IVDecl = (*I);
+ ObjCIvarDecl *IVDecl = *I;
if (!IVDecl->isInvalidDecl())
Fields.push_back(cast(IVDecl));
}
// look into properties.
for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(),
E = OI->prop_end(); I != E; ++I) {
- ObjCPropertyDecl *PDecl = (*I);
- if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl())
+ if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
Fields.push_back(cast(IV));
}
}
@@ -620,12 +619,12 @@
/// addRecordToClass - produces record info. for the class for its
/// ivars and all those inherited.
///
-const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D)
-{
+const RecordDecl *ASTContext::addRecordToClass(const ObjCInterfaceDecl *D) {
const RecordDecl *&RD = ASTRecordForInterface[D];
if (RD)
return RD;
- std::vector RecFields;
+
+ llvm::SmallVector RecFields;
CollectObjCIvars(D, RecFields);
RecordDecl *NewRD = RecordDecl::Create(*this, TagDecl::TK_struct, 0,
D->getLocation(),
@@ -633,13 +632,13 @@
/// FIXME! Can do collection of ivars and adding to the record while
/// doing it.
for (unsigned int i = 0; i != RecFields.size(); i++) {
- FieldDecl *Field = FieldDecl::Create(*this, NewRD,
- RecFields[i]->getLocation(),
- RecFields[i]->getIdentifier(),
- RecFields[i]->getType(),
- RecFields[i]->getBitWidth(), false);
- NewRD->addDecl(Field);
+ NewRD->addDecl(FieldDecl::Create(*this, NewRD,
+ RecFields[i]->getLocation(),
+ RecFields[i]->getIdentifier(),
+ RecFields[i]->getType(),
+ RecFields[i]->getBitWidth(), false));
}
+
NewRD->completeDefinition(*this);
RD = NewRD;
return RD;
@@ -2401,9 +2400,9 @@
const IdentifierInfo *II = OI->getIdentifier();
S += II->getName();
S += '=';
- std::vector RecFields;
+ llvm::SmallVector