[cfe-commits] r125813 - in /cfe/trunk: include/clang/Sema/Scope.h include/clang/Sema/ScopeInfo.h include/clang/Sema/Sema.h lib/Parse/ParseExpr.cpp lib/Parse/ParseStmt.cpp lib/Sema/Sema.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclObjC.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaStmt.cpp
Chris Lattner
sabre at nondot.org
Thu Feb 17 17:27:55 PST 2011
Author: lattner
Date: Thu Feb 17 19:27:55 2011
New Revision: 125813
URL: http://llvm.org/viewvc/llvm-project?rev=125813&view=rev
Log:
Switch labels over to using normal name lookup, instead of their
own weird little DenseMap. Hey look, we now emit unused label
warnings deterministically, amazing.
Modified:
cfe/trunk/include/clang/Sema/Scope.h
cfe/trunk/include/clang/Sema/ScopeInfo.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseStmt.cpp
cfe/trunk/lib/Sema/Sema.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
Modified: cfe/trunk/include/clang/Sema/Scope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Scope.h?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Scope.h (original)
+++ cfe/trunk/include/clang/Sema/Scope.h Thu Feb 17 19:27:55 2011
@@ -53,7 +53,7 @@
/// ClassScope - The scope of a struct/union/class definition.
ClassScope = 0x20,
- /// BlockScope - This is a scope that corresponds to a block object.
+ /// BlockScope - This is a scope that corresponds to a block/closure object.
/// Blocks serve as top-level scopes for some objects like labels, they
/// also prevent things like break and continue. BlockScopes always have
/// the FnScope, BreakScope, ContinueScope, and DeclScope flags set as well.
@@ -146,8 +146,7 @@
unsigned getFlags() const { return Flags; }
void setFlags(unsigned F) { Flags = F; }
- /// isBlockScope - Return true if this scope does not correspond to a
- /// closure.
+ /// isBlockScope - Return true if this scope correspond to a closure.
bool isBlockScope() const { return Flags & BlockScope; }
/// getParent - Return the scope that this is nested in.
Modified: cfe/trunk/include/clang/Sema/ScopeInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ScopeInfo.h?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/ScopeInfo.h (original)
+++ cfe/trunk/include/clang/Sema/ScopeInfo.h Thu Feb 17 19:27:55 2011
@@ -52,11 +52,6 @@
/// \brief Used to determine if errors occurred in this function or block.
DiagnosticErrorTrap ErrorTrap;
- /// LabelMap - This is a mapping from label identifiers to the LabelDecl for
- /// it. Forward referenced labels have a LabelDecl created for them with a
- /// null statement.
- llvm::DenseMap<IdentifierInfo*, LabelDecl*> LabelMap;
-
/// SwitchStack - This is the current set of active switch statements in the
/// block.
llvm::SmallVector<SwitchStmt*, 8> SwitchStack;
@@ -92,11 +87,6 @@
virtual ~FunctionScopeInfo();
- /// checkLabelUse - This checks to see if any labels are used without being
- /// defined, emiting errors and returning true if any are found. This also
- /// warns about unused labels.
- bool checkLabelUse(Stmt *Body, Sema &S);
-
/// \brief Clear out the information in this function scope, making it
/// suitable for reuse.
void Clear();
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb 17 19:27:55 2011
@@ -1344,6 +1344,8 @@
/// Tag name lookup, which finds the names of enums, classes,
/// structs, and unions.
LookupTagName,
+ /// Label name lookup.
+ LookupLabel,
/// Member name lookup, which finds the names of
/// class/struct/union members.
LookupMemberName,
@@ -1412,6 +1414,8 @@
QualType T1, QualType T2,
UnresolvedSetImpl &Functions);
+ LabelDecl *LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc);
+
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class);
CXXDestructorDecl *LookupDestructor(CXXRecordDecl *Class);
@@ -1715,9 +1719,6 @@
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc,
SourceLocation ColonLoc,
Stmt *SubStmt, Scope *CurScope);
- StmtResult ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, Stmt *SubStmt,
- AttributeList *Attr);
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
SourceLocation ColonLoc, Stmt *SubStmt);
@@ -1752,9 +1753,6 @@
StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
SourceLocation LabelLoc,
- IdentifierInfo *LabelII);
- StmtResult ActOnGotoStmt(SourceLocation GotoLoc,
- SourceLocation LabelLoc,
LabelDecl *TheDecl);
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc,
SourceLocation StarLoc,
@@ -2078,11 +2076,7 @@
Expr *Cond, Expr *LHS, Expr *RHS);
/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
- ExprResult ActOnAddrLabel(SourceLocation OpLoc,
- SourceLocation LabLoc,
- IdentifierInfo *LabelII);
- ExprResult ActOnAddrLabel(SourceLocation OpLoc,
- SourceLocation LabLoc,
+ ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
LabelDecl *LD);
ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Thu Feb 17 19:27:55 2011
@@ -795,8 +795,9 @@
return ExprError(Diag(Tok, diag::err_expected_ident));
Diag(AmpAmpLoc, diag::ext_gnu_address_of_label);
- Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(),
- Tok.getIdentifierInfo());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
+ Tok.getLocation());
+ Res = Actions.ActOnAddrLabel(AmpAmpLoc, Tok.getLocation(), LD);
ConsumeToken();
return move(Res);
}
Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Thu Feb 17 19:27:55 2011
@@ -236,10 +236,14 @@
// Broken substmt shouldn't prevent the label from being added to the AST.
if (SubStmt.isInvalid())
SubStmt = Actions.ActOnNullStmt(ColonLoc);
-
- return Actions.ActOnLabelStmt(IdentTok.getLocation(),
- IdentTok.getIdentifierInfo(),
- ColonLoc, SubStmt.get(), attrs.getList());
+
+ LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
+ IdentTok.getLocation());
+ if (AttributeList *Attrs = attrs.getList())
+ Actions.ProcessDeclAttributeList(Actions.CurScope, LD, Attrs);
+
+ return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
+ SubStmt.get());
}
/// ParseCaseStatement
@@ -1168,8 +1172,9 @@
StmtResult Res;
if (Tok.is(tok::identifier)) {
- Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(),
- Tok.getIdentifierInfo());
+ LabelDecl *LD = Actions.LookupOrCreateLabel(Tok.getIdentifierInfo(),
+ Tok.getLocation());
+ Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), LD);
ConsumeToken();
} else if (Tok.is(tok::star)) {
// GNU indirect goto extension.
Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Feb 17 19:27:55 2011
@@ -45,60 +45,11 @@
HasBranchIntoScope = false;
HasIndirectGoto = false;
- LabelMap.clear();
SwitchStack.clear();
Returns.clear();
ErrorTrap.reset();
}
-bool FunctionScopeInfo::checkLabelUse(Stmt *Body, Sema &S) {
- bool AnyErrors = false;
- // FIXME: The iteration order of this (and thus, the order of errors and
- // warnings produced) is nondeterminstic.
- for (llvm::DenseMap<IdentifierInfo*, LabelDecl*>::iterator
- I = LabelMap.begin(), E = LabelMap.end(); I != E; ++I) {
- LabelDecl *L = I->second;
-
- // Verify that we have no forward references left. If so, there was a goto
- // or address of a label taken, but no definition of it. Label fwd
- // definitions are indicated with a null substmt.
- if (L->getStmt() != 0) {
- S.DiagnoseUnusedDecl(L);
- continue;
- }
-
- AnyErrors = true;
-
- // Emit error.
- S.Diag(L->getLocation(), diag::err_undeclared_label_use) << L->getDeclName();
-
- // At this point, we have gotos that use the bogus label. Stitch it into
- // the function body so that the AST is well formed.
- if (Body == 0) {
- // The whole function wasn't parsed correctly.
- continue;
- }
-
- // Otherwise, the body is valid: we want to stitch the label decl into the
- // function somewhere so that it is properly owned and so that the goto
- // has a valid target. Do this by creating LabelStmt and adding it to the
- // end of the outer CompoundStmt.
- LabelStmt *LS = new (S.Context) LabelStmt(L->getLocation(), L,
- new (S.Context) NullStmt(L->getLocation()));
-
- CompoundStmt *Compound = isa<CXXTryStmt>(Body) ?
- cast<CXXTryStmt>(Body)->getTryBlock() :
- cast<CompoundStmt>(Body);
- llvm::SmallVector<Stmt*, 64> Elements(Compound->body_begin(),
- Compound->body_end());
- Elements.push_back(LS);
- Compound->setStmts(S.Context, Elements.data(), Elements.size());
- }
- return AnyErrors;
-}
-
-
-
BlockScopeInfo::~BlockScopeInfo() { }
void Sema::ActOnTranslationUnitScope(Scope *S) {
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Feb 17 19:27:55 2011
@@ -674,6 +674,8 @@
return true;
}
+/// DiagnoseUnusedDecl - Emit warnings about declarations that are not used
+/// unless they are marked attr(unused).
void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
if (!ShouldDiagnoseUnusedDecl(D))
return;
@@ -689,6 +691,14 @@
Diag(D->getLocation(), DiagID) << D->getDeclName();
}
+static void CheckPoppedLabel(LabelDecl *L, Sema &S) {
+ // Verify that we have no forward references left. If so, there was a goto
+ // or address of a label taken, but no definition of it. Label fwd
+ // definitions are indicated with a null substmt.
+ if (L->getStmt() == 0)
+ S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName();
+}
+
void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
if (S->decl_empty()) return;
assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
@@ -708,6 +718,10 @@
if (!S->hasErrorOccurred())
DiagnoseUnusedDecl(D);
+ // If this was a forward reference to a label, verify it was defined.
+ if (LabelDecl *LD = dyn_cast<LabelDecl>(D))
+ CheckPoppedLabel(LD, *this);
+
// Remove this name from our lexical scope.
IdResolver.RemoveDecl(D);
}
@@ -5480,11 +5494,6 @@
}
// Verify and clean out per-function state.
-
- // Check goto/label use.
- FunctionScopeInfo *CurFn = getCurFunction();
- CurFn->checkLabelUse(Body, *this);
-
if (Body) {
// C++ constructors that have function-try-blocks can't have return
// statements in the handlers of that block. (C++ [except.handle]p14)
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Thu Feb 17 19:27:55 2011
@@ -1710,7 +1710,6 @@
// Make sure we can establish a context for the method.
if (!ClassDecl) {
Diag(MethodLoc, diag::error_missing_method_context);
- getCurFunction()->LabelMap.clear();
return 0;
}
QualType resultDeclType;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 17 19:27:55 2011
@@ -1566,8 +1566,7 @@
Name.getCXXNameType()->isDependentType()) {
DependentID = true;
} else if (SS.isSet()) {
- DeclContext *DC = computeDeclContext(SS, false);
- if (DC) {
+ if (DeclContext *DC = computeDeclContext(SS, false)) {
if (RequireCompleteDeclContext(SS, DC))
return ExprError();
} else {
@@ -1575,10 +1574,10 @@
}
}
- if (DependentID) {
+ if (DependentID)
return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand,
TemplateArgs);
- }
+
bool IvarLookupFollowUp = false;
// Perform the required lookup.
LookupResult R(*this, NameInfo, LookupOrdinaryName);
@@ -1613,9 +1612,10 @@
if (E.isInvalid())
return ExprError();
- Expr *Ex = E.takeAs<Expr>();
- if (Ex) return Owned(Ex);
- // Synthesize ivars lazily
+ if (Expr *Ex = E.takeAs<Expr>())
+ return Owned(Ex);
+
+ // Synthesize ivars lazily.
if (getLangOptions().ObjCDefaultSynthProperties &&
getLangOptions().ObjCNonFragileABI2) {
if (SynthesizeProvisionalIvar(*this, R, II, NameLoc)) {
@@ -8354,18 +8354,6 @@
/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
- IdentifierInfo *LabelII) {
- // Look up the record for this label identifier.
- LabelDecl *&TheDecl = getCurFunction()->LabelMap[LabelII];
-
- // If we haven't seen this label yet, create a forward reference. It
- // will be validated and/or cleaned up in ActOnFinishFunctionBody.
- if (TheDecl == 0)
- TheDecl = LabelDecl::Create(Context, CurContext, LabLoc, LabelII);
- return ActOnAddrLabel(OpLoc, LabLoc, TheDecl);
-}
-
-ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,
LabelDecl *TheDecl) {
TheDecl->setUsed();
// Create the AST node. The address of a label always has type 'void*'.
@@ -8866,9 +8854,6 @@
if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction())
DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
- // Check goto/label use.
- BSI->checkLabelUse(Body, *this);
-
BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy);
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Feb 17 19:27:55 2011
@@ -210,7 +210,8 @@
IDNS = Decl::IDNS_Ordinary;
if (CPlusPlus) {
IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member | Decl::IDNS_Namespace;
- if (Redeclaration) IDNS |= Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend;
+ if (Redeclaration)
+ IDNS |= Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend;
}
break;
@@ -236,7 +237,10 @@
IDNS = Decl::IDNS_Tag;
}
break;
-
+ case Sema::LookupLabel:
+ IDNS = Decl::IDNS_Label;
+ break;
+
case Sema::LookupMemberName:
IDNS = Decl::IDNS_Member;
if (CPlusPlus)
@@ -270,8 +274,7 @@
}
void LookupResult::configure() {
- IDNS = getIDNS(LookupKind,
- SemaRef.getLangOptions().CPlusPlus,
+ IDNS = getIDNS(LookupKind, SemaRef.getLangOptions().CPlusPlus,
isForRedeclaration());
// If we're looking for one of the allocation or deallocation
@@ -1059,7 +1062,6 @@
if (!getLangOptions().CPlusPlus) {
// Unqualified name lookup in C/Objective-C is purely lexical, so
// search in the declarations attached to the name.
-
if (NameKind == Sema::LookupRedeclarationWithLinkage) {
// Find the nearest non-transparent declaration scope.
while (!(S->getFlags() & Scope::DeclScope) ||
@@ -1392,6 +1394,7 @@
case LookupOperatorName:
case LookupNamespaceName:
case LookupObjCProtocolName:
+ case LookupLabel:
// These lookups will never find a member in a C++ class (or base class).
return false;
@@ -2757,9 +2760,27 @@
/*InBaseClass=*/false, Consumer, Visited);
}
-//----------------------------------------------------------------------------
+LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc) {
+ // Do a lookup to see if we have a label with this name already.
+ NamedDecl *Res = LookupSingleName(CurScope, II, Loc, LookupLabel,
+ NotForRedeclaration);
+ // If we found a label, check to see if it is in the same context as us. When
+ // in a Block, we don't want to reuse a label in an enclosing function.
+ if (Res && Res->getDeclContext() != CurContext)
+ Res = 0;
+
+ if (Res == 0) {
+ // If not forward referenced or defined already, create the backing decl.
+ Res = LabelDecl::Create(Context, CurContext, Loc, II);
+ PushOnScopeChains(Res, CurScope->getFnParent(), true);
+ }
+
+ return cast<LabelDecl>(Res);
+}
+
+//===----------------------------------------------------------------------===//
// Typo correction
-//----------------------------------------------------------------------------
+//===----------------------------------------------------------------------===//
namespace {
class TypoCorrectionConsumer : public VisibleDeclConsumer {
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=125813&r1=125812&r2=125813&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Feb 17 19:27:55 2011
@@ -48,9 +48,8 @@
return Owned(new (Context) NullStmt(SemiLoc, LeadingEmptyMacro));
}
-StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg,
- SourceLocation StartLoc,
- SourceLocation EndLoc) {
+StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,
+ SourceLocation EndLoc) {
DeclGroupRef DG = dg.getAsVal<DeclGroupRef>();
// If we have an invalid decl, just return an error.
@@ -232,25 +231,6 @@
}
StmtResult
-Sema::ActOnLabelStmt(SourceLocation IdentLoc, IdentifierInfo *II,
- SourceLocation ColonLoc, Stmt *SubStmt,
- AttributeList *Attr) {
- // Look up the record for this label identifier.
- LabelDecl *&TheDecl = getCurFunction()->LabelMap[II];
-
- // If not forward referenced or defined already, create the backing decl.
- if (TheDecl == 0)
- TheDecl = LabelDecl::Create(Context, CurContext, IdentLoc, II);
-
- assert(TheDecl->getIdentifier() == II && "Label mismatch!");
-
- if (Attr)
- ProcessDeclAttributeList(CurScope, TheDecl, Attr);
-
- return ActOnLabelStmt(IdentLoc, TheDecl, ColonLoc, SubStmt);
-}
-
-StmtResult
Sema::ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl,
SourceLocation ColonLoc, Stmt *SubStmt) {
@@ -1023,19 +1003,6 @@
ForLoc, RParenLoc));
}
-StmtResult
-Sema::ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
- IdentifierInfo *LabelII) {
- // Look up the record for this label identifier.
- LabelDecl *&TheDecl = getCurFunction()->LabelMap[LabelII];
-
- // If we haven't seen this label yet, create a forward reference.
- if (TheDecl == 0)
- TheDecl = LabelDecl::Create(Context, CurContext, LabelLoc, LabelII);
-
- return ActOnGotoStmt(GotoLoc, LabelLoc, TheDecl);
-}
-
StmtResult Sema::ActOnGotoStmt(SourceLocation GotoLoc,
SourceLocation LabelLoc,
LabelDecl *TheDecl) {
More information about the cfe-commits
mailing list