[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