[cfe-commits] r59527 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/conversion-function.cpp
Douglas Gregor
doug.gregor at gmail.com
Tue Nov 18 07:03:41 PST 2008
Author: dgregor
Date: Tue Nov 18 09:03:34 2008
New Revision: 59527
URL: http://llvm.org/viewvc/llvm-project?rev=59527&view=rev
Log:
As threatened previously: consolidate name lookup and the creation of
DeclRefExprs and BlockDeclRefExprs into a single function
Sema::ActOnDeclarationNameExpr, eliminating a bunch of duplicate
lookup-name-and-check-the-result code.
Note that we still have the three parser entry points for identifiers,
operator-function-ids, and conversion-function-ids, since the parser
doesn't (and shouldn't) know about DeclarationNames. This is a Good
Thing (TM), and there will be more entrypoints coming (e.g., for C++
pseudo-destructor expressions).
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/conversion-function.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=59527&r1=59526&r2=59527&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Tue Nov 18 09:03:34 2008
@@ -896,6 +896,8 @@
"unexpected type name '%0': expected identifier")
DIAG(err_undeclared_var_use, ERROR,
"use of undeclared identifier '%0'")
+DIAG(err_undeclared_use, ERROR,
+ "use of undeclared '%0'")
DIAG(warn_deprecated, WARNING,
"'%0' is deprecated")
DIAG(err_redefinition, ERROR,
@@ -1379,9 +1381,6 @@
"be used")
DIAG(warn_conv_to_void_not_used, WARNING,
"conversion function converting '%0' to '%1' will never be used")
-DIAG(err_no_conv_function, ERROR,
- "no conversion function to type '%0'")
-
DIAG(warn_not_compound_assign, WARNING,
"use of unary operator that may be intended as compound assignment (%0=)")
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=59527&r1=59526&r2=59527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 18 09:03:34 2008
@@ -625,6 +625,12 @@
TypeTy *Ty,
bool HasTrailingLParen,
const CXXScopeSpec *SS);
+ ExprResult ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
+ DeclarationName Name,
+ bool HasTrailingLParen,
+ const CXXScopeSpec *SS);
+
+
virtual ExprResult ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind);
virtual ExprResult ActOnNumericConstant(const Token &);
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=59527&r1=59526&r2=59527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 18 09:03:34 2008
@@ -347,19 +347,41 @@
IdentifierInfo &II,
bool HasTrailingLParen,
const CXXScopeSpec *SS) {
+ return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS);
+}
+
+/// ActOnDeclarationNameExpr - The parser has read some kind of name
+/// (e.g., a C++ id-expression (C++ [expr.prim]p1)). This routine
+/// performs lookup on that name and returns an expression that refers
+/// to that name. This routine isn't directly called from the parser,
+/// because the parser doesn't know about DeclarationName. Rather,
+/// this routine is called by ActOnIdentifierExpr,
+/// ActOnOperatorFunctionIdExpr, and ActOnConversionFunctionExpr,
+/// which form the DeclarationName from the corresponding syntactic
+/// forms.
+///
+/// HasTrailingLParen indicates whether this identifier is used in a
+/// function call context. LookupCtx is only used for a C++
+/// qualified-id (foo::bar) to indicate the class or namespace that
+/// the identifier must be a member of.
+Sema::ExprResult Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
+ DeclarationName Name,
+ bool HasTrailingLParen,
+ const CXXScopeSpec *SS) {
// Could be enum-constant, value decl, instance variable, etc.
Decl *D;
if (SS && !SS->isEmpty()) {
DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
if (DC == 0)
return true;
- D = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC);
+ D = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
} else
- D = LookupDecl(&II, Decl::IDNS_Ordinary, S);
+ D = LookupDecl(Name, Decl::IDNS_Ordinary, S);
// If this reference is in an Objective-C method, then ivar lookup happens as
// well.
- if (getCurMethodDecl()) {
+ IdentifierInfo *II = Name.getAsIdentifierInfo();
+ if (II && getCurMethodDecl()) {
ScopedDecl *SD = dyn_cast_or_null<ScopedDecl>(D);
// There are two cases to handle here. 1) scoped lookup could have failed,
// in which case we should look for an ivar. 2) scoped lookup could have
@@ -368,7 +390,7 @@
// name, if the lookup suceeds, we replace it our current decl.
if (SD == 0 || SD->isDefinedOutsideFunctionOrMethod()) {
ObjCInterfaceDecl *IFace = getCurMethodDecl()->getClassInterface();
- if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&II)) {
+ if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(II)) {
// FIXME: This should use a new expr for a direct reference, don't turn
// this into Self->ivar, just return a BareIVarExpr or something.
IdentifierInfo &II = Context.Idents.get("self");
@@ -378,7 +400,7 @@
}
}
// Needed to implement property "super.method" notation.
- if (SD == 0 && &II == SuperID) {
+ if (SD == 0 && II == SuperID) {
QualType T = Context.getPointerType(Context.getObjCInterfaceType(
getCurMethodDecl()->getClassInterface()));
return new ObjCSuperExpr(Loc, T);
@@ -387,17 +409,20 @@
if (D == 0) {
// Otherwise, this could be an implicitly declared function reference (legal
// in C90, extension in C99).
- if (HasTrailingLParen &&
+ if (HasTrailingLParen && II &&
!getLangOptions().CPlusPlus) // Not in C++.
- D = ImplicitlyDefineFunction(Loc, II, S);
+ D = ImplicitlyDefineFunction(Loc, *II, S);
else {
// If this name wasn't predeclared and if this is not a function call,
// diagnose the problem.
if (SS && !SS->isEmpty())
return Diag(Loc, diag::err_typecheck_no_member,
- II.getName(), SS->getRange());
+ Name.getAsString(), SS->getRange());
+ else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
+ Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
+ return Diag(Loc, diag::err_undeclared_use, Name.getAsString());
else
- return Diag(Loc, diag::err_undeclared_var_use, II.getName());
+ return Diag(Loc, diag::err_undeclared_var_use, Name.getAsString());
}
}
@@ -423,11 +448,11 @@
return Diag(Loc, diag::err_invalid_non_static_member_use, FD->getName());
}
if (isa<TypedefDecl>(D))
- return Diag(Loc, diag::err_unexpected_typedef, II.getName());
+ return Diag(Loc, diag::err_unexpected_typedef, Name.getAsString());
if (isa<ObjCInterfaceDecl>(D))
- return Diag(Loc, diag::err_unexpected_interface, II.getName());
+ return Diag(Loc, diag::err_unexpected_interface, Name.getAsString());
if (isa<NamespaceDecl>(D))
- return Diag(Loc, diag::err_unexpected_namespace, II.getName());
+ return Diag(Loc, diag::err_unexpected_namespace, Name.getAsString());
// Make the DeclRefExpr or BlockDeclRefExpr for the decl.
if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D))
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=59527&r1=59526&r2=59527&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov 18 09:03:34 2008
@@ -33,41 +33,8 @@
QualType ConvTypeCanon = Context.getCanonicalType(ConvType);
DeclarationName ConvName
= Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
-
- // We only expect to find a CXXConversionDecl.
- Decl *D;
- if (SS && !SS->isEmpty()) {
- DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
- if (DC == 0)
- return true;
- D = LookupDecl(ConvName, Decl::IDNS_Ordinary, S, DC);
- } else
- D = LookupDecl(ConvName, Decl::IDNS_Ordinary, S);
-
- if (D == 0) {
- // If there is no conversion function that converts to this type,
- // diagnose the problem.
- if (SS && !SS->isEmpty())
- return Diag(OperatorLoc, diag::err_typecheck_no_member,
- ConvType.getAsString(), SS->getRange());
- else
- return Diag(OperatorLoc, diag::err_no_conv_function,
- ConvType.getAsString());
- }
-
- assert(isa<CXXConversionDecl>(D) && "we had to find a conversion function");
- CXXConversionDecl *Conversion = cast<CXXConversionDecl>(D);
-
- // check if referencing a declaration with __attribute__((deprecated)).
- if (Conversion->getAttr<DeprecatedAttr>())
- Diag(OperatorLoc, diag::warn_deprecated, Conversion->getName());
-
- // Only create DeclRefExpr's for valid Decl's.
- if (Conversion->isInvalidDecl())
- return true;
-
- // Create a normal DeclRefExpr.
- return new DeclRefExpr(Conversion, Conversion->getType(), OperatorLoc);
+ return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen,
+ SS);
}
/// ActOnOperatorFunctionIdExpr - Parse a C++ overloaded operator
@@ -81,39 +48,7 @@
bool HasTrailingLParen,
const CXXScopeSpec *SS) {
DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(Op);
-
- Decl *D;
- if (SS && !SS->isEmpty()) {
- DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
- if (DC == 0)
- return true;
- D = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
- } else
- D = LookupDecl(Name, Decl::IDNS_Ordinary, S);
-
- if (D == 0) {
- // If there is no conversion function that converts to this type,
- // diagnose the problem.
- if (SS && !SS->isEmpty())
- return Diag(OperatorLoc, diag::err_typecheck_no_member,
- Name.getAsString(), SS->getRange());
- else
- return Diag(OperatorLoc, diag::err_undeclared_var_use,
- Name.getAsString());
- }
-
- ValueDecl *VD = cast<ValueDecl>(D);
-
- // check if referencing a declaration with __attribute__((deprecated)).
- if (VD->getAttr<DeprecatedAttr>())
- Diag(OperatorLoc, diag::warn_deprecated, Name.getAsString());
-
- // Only create DeclRefExpr's for valid Decl's.
- if (VD->isInvalidDecl())
- return true;
-
- // Create a normal DeclRefExpr.
- return new DeclRefExpr(VD, VD->getType(), OperatorLoc);
+ return ActOnDeclarationNameExpr(S, OperatorLoc, Name, HasTrailingLParen, SS);
}
/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
Modified: cfe/trunk/test/SemaCXX/conversion-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-function.cpp?rev=59527&r1=59526&r2=59527&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-function.cpp Tue Nov 18 09:03:34 2008
@@ -9,7 +9,7 @@
}
float g() {
- return operator float(); // expected-error{{no conversion function to type 'float'}}
+ return operator float(); // expected-error{{use of undeclared 'operator float'}}
}
};
More information about the cfe-commits
mailing list