[cfe-commits] r129065 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/CodeGen/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Core/ test/SemaCXX/ test/SemaTemplate/ tools/libclang/

John McCall rjmccall at apple.com
Thu Apr 7 01:22:57 PDT 2011


Author: rjmccall
Date: Thu Apr  7 03:22:57 2011
New Revision: 129065

URL: http://llvm.org/viewvc/llvm-project?rev=129065&view=rev
Log:
Basic, untested implementation for an "unknown any" type requested by LLDB.
The idea is that you can create a VarDecl with an unknown type, or a
FunctionDecl with an unknown return type, and it will still be valid to
access that object as long as you explicitly cast it at every use.  I'm
still going back and forth about how I want to test this effectively, but
I wanted to go ahead and provide a skeletal implementation for the LLDB
folks' benefit and because it also improves some diagnostic goodness for
placeholder expressions.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/OperationKinds.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/lib/AST/ItaniumMangle.cpp
    cfe/trunk/lib/AST/MicrosoftMangle.cpp
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/AST/TypeLoc.cpp
    cfe/trunk/lib/CodeGen/CGExpr.cpp
    cfe/trunk/lib/CodeGen/CGExprAgg.cpp
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CGRTTI.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/Sema/SemaCXXCast.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Serialization/ASTCommon.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/SemaCXX/overloaded-operator.cpp
    cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CIndexUSRs.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Apr  7 03:22:57 2011
@@ -420,8 +420,7 @@
   CanQualType FloatTy, DoubleTy, LongDoubleTy;
   CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
   CanQualType VoidPtrTy, NullPtrTy;
-  CanQualType OverloadTy;
-  CanQualType DependentTy;
+  CanQualType OverloadTy, DependentTy, UnknownAnyTy;
   CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy;
 
   ASTContext(const LangOptions& LOpts, SourceManager &SM, const TargetInfo &t,

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Apr  7 03:22:57 2011
@@ -2221,6 +2221,7 @@
     case CK_MemberPointerToBoolean:
     case CK_FloatingComplexToBoolean:
     case CK_IntegralComplexToBoolean:
+    case CK_ResolveUnknownAnyType:
     case CK_LValueBitCast:            // -> bool&
     case CK_UserDefinedConversion:    // operator bool()
       assert(path_empty() && "Cast kind should not have a base path!");

Modified: cfe/trunk/include/clang/AST/OperationKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/OperationKinds.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/OperationKinds.h (original)
+++ cfe/trunk/include/clang/AST/OperationKinds.h Thu Apr  7 03:22:57 2011
@@ -245,7 +245,10 @@
 
   /// \brief Converts from an integral complex to a floating complex.
   ///   _Complex unsigned -> _Complex float
-  CK_IntegralComplexToFloatingComplex
+  CK_IntegralComplexToFloatingComplex,
+
+  /// \brief Assign an unknown-any declaration a type.
+  CK_ResolveUnknownAnyType
 };
 
 #define CK_Invalid ((CastKind) -1)

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Thu Apr  7 03:22:57 2011
@@ -1488,7 +1488,14 @@
     /// theoretically deducible.
     Dependent,
 
-    Overload,  // This represents the type of an overloaded function declaration.
+    /// The type of an unresolved overload set.
+    Overload,
+
+    /// __builtin_any_type.  Useful for clients like debuggers
+    /// that don't know what type to give something.  Only a small
+    /// number of operations are valid on expressions of unknown type;
+    /// notable among them, calls and explicit casts.
+    UnknownAny,
 
     /// The primitive Objective C 'id' type.  The type pointed to by the
     /// user-visible 'id' type.  Only ever shows up in an AST as the base
@@ -1537,7 +1544,7 @@
   /// i.e. a type which cannot appear in arbitrary positions in a
   /// fully-formed expression.
   bool isPlaceholderType() const {
-    return getKind() == Overload;
+    return getKind() == Overload || getKind() == UnknownAny;
   }
 
   static bool classof(const Type *T) { return T->getTypeClass() == Builtin; }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr  7 03:22:57 2011
@@ -3849,6 +3849,9 @@
   "%0 does not refer to the name of a parameter pack; did you mean %1?">;
 def note_parameter_pack_here : Note<"parameter pack %0 declared here">;
 
+def err_bad_use_of_unknown_any : Error<
+  "no known type for %0; must explicitly cast this expression to use it">;
+
 } // end of sema category
 
 } // end of sema component.

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Apr  7 03:22:57 2011
@@ -5024,6 +5024,10 @@
                       CastKind &Kind, ExprValueKind &VK, CXXCastPath &BasePath,
                       bool FunctionalStyle = false);
 
+  bool checkUnknownAnyCast(SourceRange TyRange, QualType castType,
+                           Expr *&castExpr, CastKind &castKind,
+                           ExprValueKind &valueKind, CXXCastPath &BasePath);
+
   // CheckVectorCast - check type constraints for vectors.
   // Since vectors are an extension, there are no C standard reference for this.
   // We allow casting between vectors and integer datatypes of the same size.

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Apr  7 03:22:57 2011
@@ -490,7 +490,9 @@
       /// \brief The ObjC 'Class' type.
       PREDEF_TYPE_OBJC_CLASS    = 27,
       /// \brief The ObjC 'SEL' type.
-      PREDEF_TYPE_OBJC_SEL    = 28
+      PREDEF_TYPE_OBJC_SEL      = 28,
+      /// \brief The 'unknown any' type.
+      PREDEF_TYPE_UNKNOWN_ANY   = 29
     };
 
     /// \brief The number of predefined type IDs that are reserved for

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Apr  7 03:22:57 2011
@@ -402,6 +402,9 @@
   // Placeholder type for functions.
   InitBuiltinType(OverloadTy,          BuiltinType::Overload);
 
+  // "any" type; useful for debugger-like clients.
+  InitBuiltinType(UnknownAnyTy,        BuiltinType::UnknownAny);
+
   // C99 6.2.5p11.
   FloatComplexTy      = getComplexType(FloatTy);
   DoubleComplexTy     = getComplexType(DoubleTy);

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Apr  7 03:22:57 2011
@@ -1360,6 +1360,7 @@
     
   case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
   case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
+  case BuiltinType::UnknownAny: return Importer.getToContext().UnknownAnyTy;
 
   case BuiltinType::ObjCId:
     // FIXME: Make sure that the "to" context supports Objective-C!

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Apr  7 03:22:57 2011
@@ -1055,6 +1055,8 @@
     return "IntegralComplexCast";
   case CK_IntegralComplexToFloatingComplex:
     return "IntegralComplexToFloatingComplex";
+  case CK_ResolveUnknownAnyType:
+    return "ResolveUnknownAnyType";
   }
 
   llvm_unreachable("Unhandled cast kind!");

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Apr  7 03:22:57 2011
@@ -1798,6 +1798,7 @@
   case CK_GetObjCProperty:
   case CK_LValueBitCast:
   case CK_UserDefinedConversion:
+  case CK_ResolveUnknownAnyType:
     return false;
 
   case CK_LValueToRValue:
@@ -2351,6 +2352,7 @@
   case CK_GetObjCProperty:
   case CK_LValueBitCast:
   case CK_UserDefinedConversion:
+  case CK_ResolveUnknownAnyType:
     return false;
 
   case CK_FloatingRealToComplex: {

Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
+++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Apr  7 03:22:57 2011
@@ -1327,6 +1327,7 @@
 
   case BuiltinType::Overload:
   case BuiltinType::Dependent:
+  case BuiltinType::UnknownAny:
     assert(false &&
            "Overloaded and dependent types shouldn't get to name mangling");
     break;

Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
+++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Apr  7 03:22:57 2011
@@ -717,6 +717,7 @@
 
   case BuiltinType::Overload:
   case BuiltinType::Dependent:
+  case BuiltinType::UnknownAny:
     assert(false &&
            "Overloaded and dependent types shouldn't get to name mangling");
     break;

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Thu Apr  7 03:22:57 2011
@@ -1132,6 +1132,7 @@
   case NullPtr:           return "nullptr_t";
   case Overload:          return "<overloaded function type>";
   case Dependent:         return "<dependent type>";
+  case UnknownAny:        return "<unknown type>";
   case ObjCId:            return "id";
   case ObjCClass:         return "Class";
   case ObjCSel:           return "SEL";

Modified: cfe/trunk/lib/AST/TypeLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TypeLoc.cpp (original)
+++ cfe/trunk/lib/AST/TypeLoc.cpp Thu Apr  7 03:22:57 2011
@@ -234,6 +234,7 @@
     case BuiltinType::NullPtr:
     case BuiltinType::Overload:
     case BuiltinType::Dependent:
+    case BuiltinType::UnknownAny:
     case BuiltinType::ObjCId:
     case BuiltinType::ObjCClass:
     case BuiltinType::ObjCSel:

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Apr  7 03:22:57 2011
@@ -1930,6 +1930,12 @@
                                            ConvertType(ToType));
     return MakeAddrLValue(V, E->getType());
   }
+  case CK_ResolveUnknownAnyType: {
+    const DeclRefExpr *declRef = cast<DeclRefExpr>(E->getSubExpr());
+    llvm::Constant *addr = CGM.getAddrOfUnknownAnyDecl(declRef->getDecl(),
+                                                       E->getType());
+    return MakeAddrLValue(addr, E->getType());
+  }
   }
   
   llvm_unreachable("Unhandled lvalue cast kind?");

Modified: cfe/trunk/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprAgg.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprAgg.cpp Thu Apr  7 03:22:57 2011
@@ -309,6 +309,10 @@
   case CK_LValueBitCast:
     llvm_unreachable("should not be emitting lvalue bitcast as rvalue");
     break;
+
+  case CK_ResolveUnknownAnyType:
+    EmitAggLoadOfLValue(E);
+    break;
       
   case CK_Dependent:
   case CK_BitCast:

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Thu Apr  7 03:22:57 2011
@@ -552,6 +552,7 @@
     case CK_GetObjCProperty:
     case CK_ToVoid:
     case CK_Dynamic:
+    case CK_ResolveUnknownAnyType:
       return 0;
 
     // These might need to be supported for constexpr.

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Thu Apr  7 03:22:57 2011
@@ -1126,6 +1126,9 @@
     RValue RV = CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType());
     return RV.getScalarVal();
   }
+
+  case CK_ResolveUnknownAnyType:
+    return EmitLoadOfLValue(CE);
       
   case CK_LValueToRValue:
     assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));

Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Thu Apr  7 03:22:57 2011
@@ -196,6 +196,7 @@
       
     case BuiltinType::Overload:
     case BuiltinType::Dependent:
+    case BuiltinType::UnknownAny:
       assert(false && "Should not see this type here!");
       
     case BuiltinType::ObjCId:

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Apr  7 03:22:57 2011
@@ -1072,12 +1072,60 @@
   return GetOrCreateLLVMGlobal(MangledName, PTy, D);
 }
 
+/// getAddrOfUnknownAnyDecl - Return an llvm::Constant for the address
+/// of a global which was declared with unknown type.  It is possible
+/// for a VarDecl to end up getting resolved to have function type,
+/// which complicates this substantially; on the other hand, these are
+/// always external references, which does simplify the logic a lot.
+llvm::Constant *
+CodeGenModule::getAddrOfUnknownAnyDecl(const NamedDecl *decl, QualType type) {
+  GlobalDecl global;
+
+  // FunctionDecls will always end up with function types, but
+  // VarDecls can end up with them too.
+  if (isa<FunctionDecl>(decl))
+    global = GlobalDecl(cast<FunctionDecl>(decl));
+  else
+    global = GlobalDecl(cast<VarDecl>(decl));
+  llvm::StringRef mangledName = getMangledName(global);
+
+  const llvm::Type *ty = getTypes().ConvertTypeForMem(type);
+  const llvm::PointerType *pty =
+    llvm::PointerType::get(ty, getContext().getTargetAddressSpace(type));
+
+
+  // Check for an existing global value with this name.
+  llvm::GlobalValue *entry = GetGlobalValue(mangledName);
+  if (entry)
+    return llvm::ConstantExpr::getBitCast(entry, pty);
+
+  // If we're creating something with function type, go ahead and
+  // create a function.
+  if (const llvm::FunctionType *fnty = dyn_cast<llvm::FunctionType>(ty)) {
+    llvm::Function *fn = llvm::Function::Create(fnty,
+                                                llvm::Function::ExternalLinkage,
+                                                mangledName, &getModule());
+    return fn;
+
+  // Otherwise, make a global variable.
+  } else {
+    llvm::GlobalVariable *var
+      = new llvm::GlobalVariable(getModule(), ty, false,
+                                 llvm::GlobalValue::ExternalLinkage,
+                                 0, mangledName, 0,
+                                 false, pty->getAddressSpace());
+    if (isa<VarDecl>(decl) && cast<VarDecl>(decl)->isThreadSpecified())
+      var->setThreadLocal(true);
+    return var;
+  }
+}
+
 /// CreateRuntimeVariable - Create a new runtime global variable with the
 /// specified type and name.
 llvm::Constant *
 CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
                                      llvm::StringRef Name) {
-  return GetOrCreateLLVMGlobal(Name,  llvm::PointerType::getUnqual(Ty), 0,
+  return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0,
                                true);
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Apr  7 03:22:57 2011
@@ -358,6 +358,8 @@
   llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
                                      const llvm::Type *Ty = 0);
 
+  llvm::Constant *getAddrOfUnknownAnyDecl(const NamedDecl *D, QualType type);
+
   /// GetAddrOfFunction - Return the address of the given function.  If Ty is
   /// non-null, then this function will use the specified type if it has to
   /// create it.

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Thu Apr  7 03:22:57 2011
@@ -253,10 +253,11 @@
     
     case BuiltinType::Overload:
     case BuiltinType::Dependent:
-      assert(0 && "Unexpected builtin type!");
+    case BuiltinType::UnknownAny:
+      llvm_unreachable("Unexpected builtin type!");
       break;
     }
-    assert(0 && "Unknown builtin type!");
+    llvm_unreachable("Unknown builtin type!");
     break;
   }
   case Type::Complex: {

Modified: cfe/trunk/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXCast.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCXXCast.cpp Thu Apr  7 03:22:57 2011
@@ -1590,3 +1590,4 @@
 
   return tcr != TC_Success;
 }
+

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Apr  7 03:22:57 2011
@@ -4658,6 +4658,47 @@
   return ActOnCallExpr(S, ConfigDR, LLLLoc, execConfig, GGGLoc, 0);
 }
 
+/// Given a function expression of unknown-any type, rebuild it to
+/// have a type appropriate for being called with the given arguments,
+/// yielding a value of unknown-any type.
+static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn,
+                                            Expr **args, unsigned numArgs) {
+  // Build a simple function type exactly matching the arguments.
+  llvm::SmallVector<QualType, 8> argTypes;
+  argTypes.reserve(numArgs);
+  for (unsigned i = 0; i != numArgs; ++i) {
+    // Require all the sub-expression to not be placeholders.
+    ExprResult result = S.CheckPlaceholderExpr(args[i], SourceLocation());
+    if (result.isInvalid()) return ExprError();
+    args[i] = result.take();
+
+    // Do l2r conversions on all the arguments.
+    S.DefaultLvalueConversion(args[i]);
+
+    argTypes.push_back(args[i]->getType());
+  }
+
+  // Resolve the symbol to a function type that returns an unknown-any
+  // type.  In the fully resolved expression, this cast will surround
+  // the DeclRefExpr.
+  FunctionProtoType::ExtProtoInfo extInfo;
+  QualType fnType = S.Context.getFunctionType(S.Context.UnknownAnyTy,
+                                              argTypes.data(), numArgs,
+                                              extInfo);
+  fn = ImplicitCastExpr::Create(S.Context, fnType,
+                                CK_ResolveUnknownAnyType,
+                                fn, /*path*/ 0,
+                     (S.getLangOptions().CPlusPlus ? VK_LValue : VK_RValue));
+
+  // Decay that to a pointer.
+  fnType = S.Context.getPointerType(fnType);
+  fn = ImplicitCastExpr::Create(S.Context, fnType,
+                                CK_FunctionToPointerDecay,
+                                fn, /*path*/ 0, VK_RValue);
+
+  return S.Owned(fn);
+}
+
 /// BuildResolvedCallExpr - Build a call to a resolved expression,
 /// i.e. an expression not of \p OverloadTy.  The expression should
 /// unary-convert to an expression of function-pointer or
@@ -4699,6 +4740,7 @@
   if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID))
     return CheckBuiltinFunctionCall(BuiltinID, TheCall);
 
+ retry:
   const FunctionType *FuncT;
   if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) {
     // C99 6.5.2.2p1 - "The expression that denotes the called function shall
@@ -4711,6 +4753,15 @@
                Fn->getType()->getAs<BlockPointerType>()) {
     FuncT = BPT->getPointeeType()->castAs<FunctionType>();
   } else {
+    // Handle calls to expressions of unknown-any type.
+    if (Fn->getType() == Context.UnknownAnyTy) {
+      ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn, Args, NumArgs);
+      if (rewrite.isInvalid()) return ExprError();
+      Fn = rewrite.take();
+      NDecl = FDecl = 0;
+      goto retry;
+    }
+
     return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
       << Fn->getType() << Fn->getSourceRange());
   }
@@ -5038,6 +5089,9 @@
 bool Sema::CheckCastTypes(SourceRange TyR, QualType castType,
                           Expr *&castExpr, CastKind& Kind, ExprValueKind &VK,
                           CXXCastPath &BasePath, bool FunctionalStyle) {
+  if (castExpr->getType() == Context.UnknownAnyTy)
+    return checkUnknownAnyCast(TyR, castType, castExpr, Kind, VK, BasePath);
+
   if (getLangOptions().CPlusPlus)
     return CXXCheckCStyleCast(SourceRange(TyR.getBegin(),
                                           castExpr->getLocEnd()), 
@@ -5398,19 +5452,13 @@
                                         SourceLocation QuestionLoc) {
 
   // If either LHS or RHS are overloaded functions, try to resolve them.
-  if (LHS->getType() == Context.OverloadTy || 
-      RHS->getType() == Context.OverloadTy) {
-    ExprResult LHSResult = CheckPlaceholderExpr(LHS, QuestionLoc);
-    if (LHSResult.isInvalid())
-      return QualType();
-
-    ExprResult RHSResult = CheckPlaceholderExpr(RHS, QuestionLoc);
-    if (RHSResult.isInvalid())
-      return QualType();
-
-    LHS = LHSResult.take();
-    RHS = RHSResult.take();
-  }
+  ExprResult lhsResult = CheckPlaceholderExpr(LHS, QuestionLoc);
+  if (!lhsResult.isUsable()) return QualType();
+  LHS = lhsResult.take();
+
+  ExprResult rhsResult = CheckPlaceholderExpr(RHS, QuestionLoc);
+  if (!rhsResult.isUsable()) return QualType();
+  RHS = rhsResult.take();
 
   // C++ is sufficiently different to merit its own checker.
   if (getLangOptions().CPlusPlus)
@@ -8161,16 +8209,13 @@
   // f<int> == 0;  // resolve f<int> blindly
   // void (*p)(int); p = f<int>;  // resolve f<int> using target
   if (Opc != BO_Assign) { 
-    if (lhs->getType() == Context.OverloadTy) {
-      ExprResult resolvedLHS = 
-        ResolveAndFixSingleFunctionTemplateSpecialization(lhs);
-      if (resolvedLHS.isUsable()) lhs = resolvedLHS.release(); 
-    }
-    if (rhs->getType() == Context.OverloadTy) {
-      ExprResult resolvedRHS = 
-        ResolveAndFixSingleFunctionTemplateSpecialization(rhs);
-      if (resolvedRHS.isUsable()) rhs = resolvedRHS.release(); 
-    }
+    ExprResult resolvedLHS = CheckPlaceholderExpr(lhs, OpLoc);
+    if (!resolvedLHS.isUsable()) return ExprError();
+    lhs = resolvedLHS.take();
+
+    ExprResult resolvedRHS = CheckPlaceholderExpr(rhs, OpLoc);
+    if (!resolvedRHS.isUsable()) return ExprError();
+    rhs = resolvedRHS.take();
   }
 
   switch (Opc) {
@@ -8529,15 +8574,14 @@
   case UO_AddrOf:
     resultType = CheckAddressOfOperand(*this, Input, OpLoc);
     break;
-  case UO_Deref:
-    if (Input->getType() == Context.OverloadTy ) {
-      ExprResult er = ResolveAndFixSingleFunctionTemplateSpecialization(Input);
-      if (er.isUsable())
-        Input = er.release();
-    }
+  case UO_Deref: {
+    ExprResult resolved = CheckPlaceholderExpr(Input, OpLoc);
+    if (!resolved.isUsable()) return ExprError();
+    Input = resolved.take();
     DefaultFunctionArrayLvalueConversion(Input);
     resultType = CheckIndirectionOperand(*this, Input, VK, OpLoc);
     break;
+  }
   case UO_Plus:
   case UO_Minus:
     UsualUnaryConversions(Input);
@@ -9904,16 +9948,122 @@
   return Owned(Sub);
 }
 
+namespace {
+  struct RebuildUnknownAnyExpr
+    : StmtVisitor<RebuildUnknownAnyExpr, Expr*> {
+
+    Sema &S;
+
+    /// The current destination type.
+    QualType DestType;
+
+    RebuildUnknownAnyExpr(Sema &S, QualType castType)
+      : S(S), DestType(castType) {}
+
+    Expr *VisitStmt(Stmt *S) {
+      llvm_unreachable("unexpected expression kind!");
+      return 0;
+    }
+
+    Expr *VisitCallExpr(CallExpr *call) {
+      call->setCallee(Visit(call->getCallee()));
+      return call;
+    }
+
+    Expr *VisitParenExpr(ParenExpr *paren) {
+      paren->setSubExpr(Visit(paren->getSubExpr()));
+      return paren;
+    }
+
+    Expr *VisitUnaryExtension(UnaryOperator *op) {
+      op->setSubExpr(Visit(op->getSubExpr()));
+      return op;
+    }
+
+    Expr *VisitImplicitCastExpr(ImplicitCastExpr *ice) {
+      // If this isn't an inner resolution, just recurse down.
+      if (ice->getCastKind() != CK_ResolveUnknownAnyType) {
+        assert(ice->getCastKind() == CK_FunctionToPointerDecay);
+        ice->setSubExpr(Visit(ice->getSubExpr()));
+        return ice;
+      }
+
+      QualType type = ice->getType();
+      assert(type.getUnqualifiedType() == type);
+
+      // The only time it should be possible for this to appear
+      // internally to an unknown-any expression is when handling a call.
+      const FunctionProtoType *proto = type->castAs<FunctionProtoType>();
+      DestType = S.Context.getFunctionType(DestType,
+                                           proto->arg_type_begin(),
+                                           proto->getNumArgs(),
+                                           proto->getExtProtoInfo());
+
+      // Strip the resolve cast when recursively rebuilding.
+      return Visit(ice->getSubExpr());
+    }
+
+    Expr *VisitDeclRefExpr(DeclRefExpr *ref) {
+      ExprValueKind valueKind = VK_LValue;
+      if (!S.getLangOptions().CPlusPlus && DestType->isFunctionType())
+        valueKind = VK_RValue;
+
+      return ImplicitCastExpr::Create(S.Context, DestType,
+                                      CK_ResolveUnknownAnyType,
+                                      ref, 0, valueKind);
+    }
+  };
+}
+
+/// Check a cast of an unknown-any type.  We intentionally only
+/// trigger this for C-style casts.
+bool Sema::checkUnknownAnyCast(SourceRange typeRange, QualType castType,
+                               Expr *&castExpr, CastKind &castKind,
+                               ExprValueKind &VK, CXXCastPath &path) {
+  VK = Expr::getValueKindForType(castType);
+
+  // Rewrite the casted expression from scratch.
+  castExpr = RebuildUnknownAnyExpr(*this, castType).Visit(castExpr);
+
+  return CheckCastTypes(typeRange, castType, castExpr, castKind, VK, path);
+}
+
+static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *e) {
+  Expr *orig = e;
+  while (true) {
+    e = e->IgnoreParenImpCasts();
+    if (CallExpr *call = dyn_cast<CallExpr>(e))
+      e = call->getCallee();
+    else
+      break;
+  }
+
+  assert(isa<DeclRefExpr>(e) && "unexpected form of unknown-any expression");
+  DeclRefExpr *ref = cast<DeclRefExpr>(e);
+  S.Diag(ref->getLocation(), diag::err_bad_use_of_unknown_any)
+    << ref->getDecl() << orig->getSourceRange();
+
+  // Never recoverable.
+  return ExprError();
+}
+
 /// Check for operands with placeholder types and complain if found.
 /// Returns true if there was an error and no recovery was possible.
 ExprResult Sema::CheckPlaceholderExpr(Expr *E, SourceLocation Loc) {
-  const BuiltinType *BT = E->getType()->getAs<BuiltinType>();
-  if (!BT || !BT->isPlaceholderType()) return Owned(E);
+  // Placeholder types are always *exactly* the appropriate builtin type.
+  QualType type = E->getType();
 
-  // If this is overload, check for a single overload.
-  assert(BT->getKind() == BuiltinType::Overload);
-  return ResolveAndFixSingleFunctionTemplateSpecialization(E, false, true,
+  // Overloaded expressions.
+  if (type == Context.OverloadTy)
+    return ResolveAndFixSingleFunctionTemplateSpecialization(E, false, true,
                                                            E->getSourceRange(),
-                                                           QualType(),
-                                                    diag::err_ovl_unresolvable);
+                                                             QualType(),
+                                                   diag::err_ovl_unresolvable);
+
+  // Expressions of unknown type.
+  if (type == Context.UnknownAnyTy)
+    return diagnoseUnknownAnyExpr(*this, E);
+
+  assert(!type->isPlaceholderType());
+  return Owned(E);
 }

Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.cpp Thu Apr  7 03:22:57 2011
@@ -51,6 +51,7 @@
   case BuiltinType::Char32:     ID = PREDEF_TYPE_CHAR32_ID;     break;
   case BuiltinType::Overload:   ID = PREDEF_TYPE_OVERLOAD_ID;   break;
   case BuiltinType::Dependent:  ID = PREDEF_TYPE_DEPENDENT_ID;  break;
+  case BuiltinType::UnknownAny: ID = PREDEF_TYPE_UNKNOWN_ANY;   break;
   case BuiltinType::ObjCId:     ID = PREDEF_TYPE_OBJC_ID;       break;
   case BuiltinType::ObjCClass:  ID = PREDEF_TYPE_OBJC_CLASS;    break;
   case BuiltinType::ObjCSel:    ID = PREDEF_TYPE_OBJC_SEL;      break;

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Apr  7 03:22:57 2011
@@ -3622,6 +3622,7 @@
     case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy;       break;
     case PREDEF_TYPE_OVERLOAD_ID:   T = Context->OverloadTy;         break;
     case PREDEF_TYPE_DEPENDENT_ID:  T = Context->DependentTy;        break;
+    case PREDEF_TYPE_UNKNOWN_ANY:   T = Context->UnknownAnyTy;       break;
     case PREDEF_TYPE_NULLPTR_ID:    T = Context->NullPtrTy;          break;
     case PREDEF_TYPE_CHAR16_ID:     T = Context->Char16Ty;           break;
     case PREDEF_TYPE_CHAR32_ID:     T = Context->Char32Ty;           break;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Apr  7 03:22:57 2011
@@ -2170,7 +2170,8 @@
         continue;
       }
       // Various C++ casts that are not handled yet.
-      case CK_Dynamic:  
+      case CK_ResolveUnknownAnyType:
+      case CK_Dynamic:
       case CK_ToUnion:
       case CK_BaseToDerived:
       case CK_NullToMemberPointer:

Modified: cfe/trunk/test/SemaCXX/overloaded-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-operator.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overloaded-operator.cpp (original)
+++ cfe/trunk/test/SemaCXX/overloaded-operator.cpp Thu Apr  7 03:22:57 2011
@@ -387,8 +387,8 @@
 
 namespace rdar9136502 {
   struct X {
-    int i();
-    int i(int);
+    int i(); // expected-note {{candidate function}}
+    int i(int); // expected-note {{candidate function}}
   };
 
   struct Y {
@@ -396,7 +396,6 @@
   };
 
   void f(X x, Y y) {
-    // FIXME: This diagnostic is non-awesome.
-    y << x.i; // expected-error{{invalid operands to binary expression ('rdar9136502::Y' and '<overloaded function type>')}}
+    y << x.i; // expected-error{{cannot resolve overloaded function 'i' from context}}
   }
 }

Modified: cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp (original)
+++ cfe/trunk/test/SemaTemplate/resolve-single-template-id.cpp Thu Apr  7 03:22:57 2011
@@ -5,11 +5,11 @@
 }
 
 void one() { }
-void two() { } // expected-note 2{{candidate}}
-void two(int) { } // expected-note 2{{candidate}}
+void two() { } // expected-note 3{{candidate}}
+void two(int) { } // expected-note 3{{candidate}}
 
-template<class T> void twoT() { } // expected-note 3{{candidate}}
-template<class T> void twoT(int) { } // expected-note 3{{candidate}}
+template<class T> void twoT() { } // expected-note 5{{candidate}}
+template<class T> void twoT(int) { } // expected-note 5{{candidate}}
 
 template<class T> void oneT() { }
 template<class T, class U> void oneT(U) { }
@@ -51,7 +51,7 @@
   void (*p1)(int); p1 = oneT<int>;
   
   int i = (int) (false ? (void (*)(int))twoT<int> : oneT<int>); //expected-error {{incompatible operand}}
-  (twoT<int>) == oneT<int>; //expected-error {{invalid operands to binary expression}}
+  (twoT<int>) == oneT<int>; //expected-error {{cannot resolve overloaded function 'twoT' from context}}
   bool b = oneT<int>;
   void (*p)() = oneT<int>;
   test<oneT<int> > ti;
@@ -65,8 +65,8 @@
   oneT<int> < oneT<int>;  //expected-warning {{self-comparison always evaluates to false}} \
                           //expected-warning {{expression result unused}}
 
-  two < two; //expected-error {{invalid operands to binary expression}}
-  twoT<int> < twoT<int>; //expected-error {{invalid operands to binary expression}}
+  two < two; //expected-error {{cannot resolve overloaded function 'two' from context}}
+  twoT<int> < twoT<int>; //expected-error {{cannot resolve overloaded function 'twoT' from context}}
   oneT<int> == 0;   // expected-warning {{expression result unused}}
 
 }

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Thu Apr  7 03:22:57 2011
@@ -1393,6 +1393,7 @@
   case BuiltinType::NullPtr:
   case BuiltinType::Overload:
   case BuiltinType::Dependent:
+  case BuiltinType::UnknownAny:
     break;
 
   case BuiltinType::ObjCId:

Modified: cfe/trunk/tools/libclang/CIndexUSRs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexUSRs.cpp?rev=129065&r1=129064&r2=129065&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexUSRs.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexUSRs.cpp Thu Apr  7 03:22:57 2011
@@ -571,6 +571,7 @@
           c = 'n'; break;
         case BuiltinType::Overload:
         case BuiltinType::Dependent:
+        case BuiltinType::UnknownAny:
           IgnoreResults = true;
           return;
         case BuiltinType::ObjCId:





More information about the cfe-commits mailing list