[cfe-commits] r74528 - in /cfe/trunk/lib/Sema: Sema.h SemaExpr.cpp SemaTemplateInstantiateDecl.cpp SemaTemplateInstantiateExpr.cpp

Douglas Gregor dgregor at apple.com
Tue Jun 30 08:47:49 PDT 2009


Author: dgregor
Date: Tue Jun 30 10:47:41 2009
New Revision: 74528

URL: http://llvm.org/viewvc/llvm-project?rev=74528&view=rev
Log:
Refactor ActOnDeclarationNameExpr into a "parsing action" part and a
"semantic analysis" part. Use the "semantic analysis" part when
performing template instantiation on a DeclRefExpr, rather than an ad
hoc list of rules to construct DeclRefExprs from the instantiation.

A test case for this change will come in with a large commit, which
illustrates what I was actually trying to work on.

Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=74528&r1=74527&r2=74528&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Jun 30 10:47:41 2009
@@ -1401,7 +1401,11 @@
                                             bool HasTrailingLParen,
                                             const CXXScopeSpec *SS,
                                             bool isAddressOfOperand = false);
-
+  OwningExprResult BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
+                                            bool HasTrailingLParen,
+                                            const CXXScopeSpec *SS, 
+                                            bool isAddressOfOperand);
+    
   virtual OwningExprResult ActOnPredefinedExpr(SourceLocation Loc,
                                                tok::TokenKind Kind);
   virtual OwningExprResult ActOnNumericConstant(const Token &);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=74528&r1=74527&r2=74528&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 30 10:47:41 2009
@@ -970,7 +970,64 @@
         return ExprError(Diag(Loc, diag::err_undeclared_var_use) << Name);
     }
   }
+  
+  if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
+    // Warn about constructs like:
+    //   if (void *X = foo()) { ... } else { X }.
+    // In the else block, the pointer is always false.
+    
+    // FIXME: In a template instantiation, we don't have scope
+    // information to check this property.
+    if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
+      Scope *CheckS = S;
+      while (CheckS) {
+        if (CheckS->isWithinElse() && 
+            CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
+          if (Var->getType()->isBooleanType())
+            ExprError(Diag(Loc, diag::warn_value_always_false)
+                      << Var->getDeclName());
+          else
+            ExprError(Diag(Loc, diag::warn_value_always_zero)
+                      << Var->getDeclName());
+          break;
+        }
+        
+        // Move up one more control parent to check again.
+        CheckS = CheckS->getControlParent();
+        if (CheckS)
+          CheckS = CheckS->getParent();
+      }
+    }
+  } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) {
+    if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
+      // C99 DR 316 says that, if a function type comes from a
+      // function definition (without a prototype), that type is only
+      // used for checking compatibility. Therefore, when referencing
+      // the function, we pretend that we don't have the full function
+      // type.
+      if (DiagnoseUseOfDecl(Func, Loc))
+        return ExprError();
 
+      QualType T = Func->getType();
+      QualType NoProtoType = T;
+      if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
+        NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
+      return BuildDeclRefExpr(Func, NoProtoType, Loc, false, false, SS);
+    }
+  }
+  
+  return BuildDeclarationNameExpr(Loc, D, HasTrailingLParen, SS, isAddressOfOperand);
+}
+
+/// \brief Complete semantic analysis for a reference to the given declaration.
+Sema::OwningExprResult
+Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
+                               bool HasTrailingLParen,
+                               const CXXScopeSpec *SS, 
+                               bool isAddressOfOperand) {
+  assert(D && "Cannot refer to a NULL declaration");
+  DeclarationName Name = D->getDeclName();
+  
   // If this is an expression of the form &Class::member, don't build an
   // implicit member ref, because we want a pointer to the member in general,
   // not any specific instance's member.
@@ -1094,51 +1151,11 @@
   // this check when we're going to perform argument-dependent lookup
   // on this function name, because this might not be the function
   // that overload resolution actually selects.
+  bool ADL = getLangOptions().CPlusPlus && (!SS || !SS->isSet()) && 
+             HasTrailingLParen;
   if (!(ADL && isa<FunctionDecl>(VD)) && DiagnoseUseOfDecl(VD, Loc))
     return ExprError();
 
-  if (VarDecl *Var = dyn_cast<VarDecl>(VD)) {
-    // Warn about constructs like:
-    //   if (void *X = foo()) { ... } else { X }.
-    // In the else block, the pointer is always false.
-
-    // FIXME: In a template instantiation, we don't have scope
-    // information to check this property.
-    if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
-      Scope *CheckS = S;
-      while (CheckS) {
-        if (CheckS->isWithinElse() && 
-            CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
-          if (Var->getType()->isBooleanType())
-            ExprError(Diag(Loc, diag::warn_value_always_false)
-              << Var->getDeclName());
-          else
-            ExprError(Diag(Loc, diag::warn_value_always_zero)
-              << Var->getDeclName());
-          break;
-        }
-
-        // Move up one more control parent to check again.
-        CheckS = CheckS->getControlParent();
-        if (CheckS)
-          CheckS = CheckS->getParent();
-      }
-    }
-  } else if (FunctionDecl *Func = dyn_cast<FunctionDecl>(VD)) {
-    if (!getLangOptions().CPlusPlus && !Func->hasPrototype()) {
-      // C99 DR 316 says that, if a function type comes from a
-      // function definition (without a prototype), that type is only
-      // used for checking compatibility. Therefore, when referencing
-      // the function, we pretend that we don't have the full function
-      // type.
-      QualType T = Func->getType();
-      QualType NoProtoType = T;
-      if (const FunctionProtoType *Proto = T->getAsFunctionProtoType())
-        NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType());
-      return BuildDeclRefExpr(VD, NoProtoType, Loc, false, false, SS);
-    }
-  }
-
   // Only create DeclRefExpr's for valid Decl's.
   if (VD->isInvalidDecl())
     return ExprError();

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=74528&r1=74527&r2=74528&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Jun 30 10:47:41 2009
@@ -865,6 +865,6 @@
       if (!Function->getBody())
         InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function);
     
-    // FIXME: instantiation static member variables
+    // FIXME: instantiate static member variables
   }
 }

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=74528&r1=74527&r2=74528&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Tue Jun 30 10:47:41 2009
@@ -156,18 +156,15 @@
                                                            false, false));
   }
 
-  ValueDecl *NewD 
-    = dyn_cast_or_null<ValueDecl>(SemaRef.InstantiateCurrentDeclRef(D));
-  if (!NewD)
+  NamedDecl *InstD = SemaRef.InstantiateCurrentDeclRef(D);
+  if (!InstD)
     return SemaRef.ExprError();
 
-  // FIXME: Build QualifiedDeclRefExpr?
-  QualType T = NewD->getType();
-  return SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(NewD,
-                                                      T.getNonReferenceType(),
-                                                           E->getLocation(),
-                                                        T->isDependentType(),
-                                                        T->isDependentType()));
+  // FIXME: nested-name-specifier for QualifiedDeclRefExpr
+  return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD, 
+                                          /*FIXME:*/false,
+                                          /*FIXME:*/0, 
+                                          /*FIXME:*/false);
 }
 
 Sema::OwningExprResult





More information about the cfe-commits mailing list