[cfe-commits] r82585 - in /cfe/trunk: clang.xcodeproj/project.pbxproj lib/CodeGen/CGCXX.cpp lib/CodeGen/CGCXXExpr.cpp lib/CodeGen/CMakeLists.txt

Anders Carlsson andersca at mac.com
Tue Sep 22 15:53:18 PDT 2009


Author: andersca
Date: Tue Sep 22 17:53:17 2009
New Revision: 82585

URL: http://llvm.org/viewvc/llvm-project?rev=82585&view=rev
Log:
Move codegen of new and delete to CGCXXExpr.cpp

Added:
    cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
Modified:
    cfe/trunk/clang.xcodeproj/project.pbxproj
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CMakeLists.txt

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=82585&r1=82584&r2=82585&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Tue Sep 22 17:53:17 2009
@@ -35,6 +35,7 @@
 		1A5D5E580E5E81010023C059 /* CGCXX.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D5E570E5E81010023C059 /* CGCXX.cpp */; };
 		1A6B6CD410693FC900BB4A8F /* CodeCompleteConsumer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */; };
 		1A6B6CD510693FC900BB4A8F /* SemaCodeComplete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6CD210693FC900BB4A8F /* SemaCodeComplete.cpp */; };
+		1A6B6E9A1069833600BB4A8F /* CGCXXExpr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6B6E991069833600BB4A8F /* CGCXXExpr.cpp */; };
 		1A6FE7090FD6F85800E00CA9 /* CGCXXTemp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A6FE7080FD6F85800E00CA9 /* CGCXXTemp.cpp */; };
 		1A701B640F7C8FE400FEC4D1 /* SemaAccess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A701B630F7C8FE400FEC4D1 /* SemaAccess.cpp */; };
 		1A7342480C7B57D500122F56 /* CGObjC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A7342470C7B57D500122F56 /* CGObjC.cpp */; };
@@ -370,6 +371,7 @@
 		1A6B6CD110693FC900BB4A8F /* CodeCompleteConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeCompleteConsumer.cpp; path = lib/Sema/CodeCompleteConsumer.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1A6B6CD210693FC900BB4A8F /* SemaCodeComplete.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SemaCodeComplete.cpp; path = lib/Sema/SemaCodeComplete.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1A6B6CD310693FC900BB4A8F /* SemaTemplate.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = SemaTemplate.h; path = lib/Sema/SemaTemplate.h; sourceTree = "<group>"; tabWidth = 2; };
+		1A6B6E991069833600BB4A8F /* CGCXXExpr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGCXXExpr.cpp; path = lib/CodeGen/CGCXXExpr.cpp; sourceTree = "<group>"; };
 		1A6FE7080FD6F85800E00CA9 /* CGCXXTemp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGCXXTemp.cpp; path = lib/CodeGen/CGCXXTemp.cpp; sourceTree = "<group>"; tabWidth = 2; };
 		1A7019E90F79BC1100FEC4D1 /* DiagnosticAnalysisKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticAnalysisKinds.td; sourceTree = "<group>"; };
 		1A7019EA0F79BC1100FEC4D1 /* DiagnosticASTKinds.td */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticASTKinds.td; sourceTree = "<group>"; };
@@ -1248,6 +1250,7 @@
 				1A5D5E570E5E81010023C059 /* CGCXX.cpp */,
 				1A649E1E0F9599DA005B965E /* CGCXX.h */,
 				1A4C41BE105B4C0B0047B5E7 /* CGCXXClass.cpp */,
+				1A6B6E991069833600BB4A8F /* CGCXXExpr.cpp */,
 				1A6FE7080FD6F85800E00CA9 /* CGCXXTemp.cpp */,
 				35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */,
 				35A3E7010DD3874400757F74 /* CGDebugInfo.h */,
@@ -1889,6 +1892,7 @@
 				1A4C41BF105B4C0B0047B5E7 /* CGCXXClass.cpp in Sources */,
 				1A6B6CD410693FC900BB4A8F /* CodeCompleteConsumer.cpp in Sources */,
 				1A6B6CD510693FC900BB4A8F /* SemaCodeComplete.cpp in Sources */,
+				1A6B6E9A1069833600BB4A8F /* CGCXXExpr.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=82585&r1=82584&r2=82585&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Sep 22 17:53:17 2009
@@ -453,193 +453,6 @@
                          E->arg_begin(), E->arg_end());
 }
 
-llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
-  if (E->isArray()) {
-    ErrorUnsupported(E, "new[] expression");
-    return llvm::UndefValue::get(ConvertType(E->getType()));
-  }
-
-  QualType AllocType = E->getAllocatedType();
-  FunctionDecl *NewFD = E->getOperatorNew();
-  const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>();
-
-  CallArgList NewArgs;
-
-  // The allocation size is the first argument.
-  QualType SizeTy = getContext().getSizeType();
-  llvm::Value *AllocSize =
-    llvm::ConstantInt::get(ConvertType(SizeTy),
-                           getContext().getTypeSize(AllocType) / 8);
-
-  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
-
-  // Emit the rest of the arguments.
-  // FIXME: Ideally, this should just use EmitCallArgs.
-  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
-
-  // First, use the types from the function type.
-  // We start at 1 here because the first argument (the allocation size)
-  // has already been emitted.
-  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
-    QualType ArgType = NewFTy->getArgType(i);
-
-    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
-           getTypePtr() ==
-           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
-           "type mismatch in call argument!");
-
-    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
-                                     ArgType));
-
-  }
-
-  // Either we've emitted all the call args, or we have a call to a
-  // variadic function.
-  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
-         "Extra arguments in non-variadic function!");
-
-  // If we still have any arguments, emit them using the type of the argument.
-  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
-       NewArg != NewArgEnd; ++NewArg) {
-    QualType ArgType = NewArg->getType();
-    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
-                                     ArgType));
-  }
-
-  // Emit the call to new.
-  RValue RV =
-    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
-             CGM.GetAddrOfFunction(NewFD), NewArgs, NewFD);
-
-  // If an allocation function is declared with an empty exception specification
-  // it returns null to indicate failure to allocate storage. [expr.new]p13.
-  // (We don't need to check for null when there's no new initializer and
-  // we're allocating a POD type).
-  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
-    !(AllocType->isPODType() && !E->hasInitializer());
-
-  llvm::BasicBlock *NewNull = 0;
-  llvm::BasicBlock *NewNotNull = 0;
-  llvm::BasicBlock *NewEnd = 0;
-
-  llvm::Value *NewPtr = RV.getScalarVal();
-
-  if (NullCheckResult) {
-    NewNull = createBasicBlock("new.null");
-    NewNotNull = createBasicBlock("new.notnull");
-    NewEnd = createBasicBlock("new.end");
-
-    llvm::Value *IsNull =
-      Builder.CreateICmpEQ(NewPtr,
-                           llvm::Constant::getNullValue(NewPtr->getType()),
-                           "isnull");
-
-    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
-    EmitBlock(NewNotNull);
-  }
-
-  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
-
-  if (AllocType->isPODType()) {
-    if (E->getNumConstructorArgs() > 0) {
-      assert(E->getNumConstructorArgs() == 1 &&
-             "Can only have one argument to initializer of POD type.");
-
-      const Expr *Init = E->getConstructorArg(0);
-
-      if (!hasAggregateLLVMType(AllocType))
-        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
-      else if (AllocType->isAnyComplexType())
-        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
-      else
-        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
-    }
-  } else {
-    // Call the constructor.
-    CXXConstructorDecl *Ctor = E->getConstructor();
-
-    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
-                           E->constructor_arg_begin(),
-                           E->constructor_arg_end());
-  }
-
-  if (NullCheckResult) {
-    Builder.CreateBr(NewEnd);
-    EmitBlock(NewNull);
-    Builder.CreateBr(NewEnd);
-    EmitBlock(NewEnd);
-
-    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
-    PHI->reserveOperandSpace(2);
-    PHI->addIncoming(NewPtr, NewNotNull);
-    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
-
-    NewPtr = PHI;
-  }
-
-  return NewPtr;
-}
-
-void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
-  if (E->isArrayForm()) {
-    ErrorUnsupported(E, "delete[] expression");
-    return;
-  };
-
-  QualType DeleteTy =
-    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
-
-  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
-
-  // Null check the pointer.
-  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
-  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
-
-  llvm::Value *IsNull =
-    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
-                         "isnull");
-
-  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
-  EmitBlock(DeleteNotNull);
-
-  // Call the destructor if necessary.
-  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
-    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
-      if (!RD->hasTrivialDestructor()) {
-        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
-        if (Dtor->isVirtual()) {
-          const llvm::Type *Ty =
-            CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
-                                           /*isVariadic=*/false);
-          
-          llvm::Value *Callee = BuildVirtualCall(Dtor, Ptr, Ty);
-          EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0);
-        } else 
-          EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
-      }
-    }
-  }
-
-  // Call delete.
-  FunctionDecl *DeleteFD = E->getOperatorDelete();
-  const FunctionProtoType *DeleteFTy =
-    DeleteFD->getType()->getAs<FunctionProtoType>();
-
-  CallArgList DeleteArgs;
-
-  QualType ArgTy = DeleteFTy->getArgType(0);
-  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
-  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
-
-  // Emit the call to delete.
-  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
-                                          DeleteArgs),
-           CGM.GetAddrOfFunction(DeleteFD),
-           DeleteArgs, DeleteFD);
-
-  EmitBlock(DeleteEnd);
-}
-
 void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) {
   EmitGlobal(GlobalDecl(D, Ctor_Complete));
   EmitGlobal(GlobalDecl(D, Ctor_Base));

Added: cfe/trunk/lib/CodeGen/CGCXXExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXExpr.cpp?rev=82585&view=auto

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXExpr.cpp (added)
+++ cfe/trunk/lib/CodeGen/CGCXXExpr.cpp Tue Sep 22 17:53:17 2009
@@ -0,0 +1,203 @@
+//===--- CGCXXExpr.cpp - Emit LLVM Code for C++ expressions ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code dealing with code generation of C++ expressions
+//
+//===----------------------------------------------------------------------===//
+
+#include "CodeGenFunction.h"
+using namespace clang;
+using namespace CodeGen;
+
+llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
+  if (E->isArray()) {
+    ErrorUnsupported(E, "new[] expression");
+    return llvm::UndefValue::get(ConvertType(E->getType()));
+  }
+
+  QualType AllocType = E->getAllocatedType();
+  FunctionDecl *NewFD = E->getOperatorNew();
+  const FunctionProtoType *NewFTy = NewFD->getType()->getAs<FunctionProtoType>();
+
+  CallArgList NewArgs;
+
+  // The allocation size is the first argument.
+  QualType SizeTy = getContext().getSizeType();
+  llvm::Value *AllocSize =
+    llvm::ConstantInt::get(ConvertType(SizeTy),
+                           getContext().getTypeSize(AllocType) / 8);
+
+  NewArgs.push_back(std::make_pair(RValue::get(AllocSize), SizeTy));
+
+  // Emit the rest of the arguments.
+  // FIXME: Ideally, this should just use EmitCallArgs.
+  CXXNewExpr::const_arg_iterator NewArg = E->placement_arg_begin();
+
+  // First, use the types from the function type.
+  // We start at 1 here because the first argument (the allocation size)
+  // has already been emitted.
+  for (unsigned i = 1, e = NewFTy->getNumArgs(); i != e; ++i, ++NewArg) {
+    QualType ArgType = NewFTy->getArgType(i);
+
+    assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
+           getTypePtr() ==
+           getContext().getCanonicalType(NewArg->getType()).getTypePtr() &&
+           "type mismatch in call argument!");
+
+    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
+                                     ArgType));
+
+  }
+
+  // Either we've emitted all the call args, or we have a call to a
+  // variadic function.
+  assert((NewArg == E->placement_arg_end() || NewFTy->isVariadic()) &&
+         "Extra arguments in non-variadic function!");
+
+  // If we still have any arguments, emit them using the type of the argument.
+  for (CXXNewExpr::const_arg_iterator NewArgEnd = E->placement_arg_end();
+       NewArg != NewArgEnd; ++NewArg) {
+    QualType ArgType = NewArg->getType();
+    NewArgs.push_back(std::make_pair(EmitCallArg(*NewArg, ArgType),
+                                     ArgType));
+  }
+
+  // Emit the call to new.
+  RValue RV =
+    EmitCall(CGM.getTypes().getFunctionInfo(NewFTy->getResultType(), NewArgs),
+             CGM.GetAddrOfFunction(NewFD), NewArgs, NewFD);
+
+  // If an allocation function is declared with an empty exception specification
+  // it returns null to indicate failure to allocate storage. [expr.new]p13.
+  // (We don't need to check for null when there's no new initializer and
+  // we're allocating a POD type).
+  bool NullCheckResult = NewFTy->hasEmptyExceptionSpec() &&
+    !(AllocType->isPODType() && !E->hasInitializer());
+
+  llvm::BasicBlock *NewNull = 0;
+  llvm::BasicBlock *NewNotNull = 0;
+  llvm::BasicBlock *NewEnd = 0;
+
+  llvm::Value *NewPtr = RV.getScalarVal();
+
+  if (NullCheckResult) {
+    NewNull = createBasicBlock("new.null");
+    NewNotNull = createBasicBlock("new.notnull");
+    NewEnd = createBasicBlock("new.end");
+
+    llvm::Value *IsNull =
+      Builder.CreateICmpEQ(NewPtr,
+                           llvm::Constant::getNullValue(NewPtr->getType()),
+                           "isnull");
+
+    Builder.CreateCondBr(IsNull, NewNull, NewNotNull);
+    EmitBlock(NewNotNull);
+  }
+
+  NewPtr = Builder.CreateBitCast(NewPtr, ConvertType(E->getType()));
+
+  if (AllocType->isPODType()) {
+    if (E->getNumConstructorArgs() > 0) {
+      assert(E->getNumConstructorArgs() == 1 &&
+             "Can only have one argument to initializer of POD type.");
+
+      const Expr *Init = E->getConstructorArg(0);
+
+      if (!hasAggregateLLVMType(AllocType))
+        Builder.CreateStore(EmitScalarExpr(Init), NewPtr);
+      else if (AllocType->isAnyComplexType())
+        EmitComplexExprIntoAddr(Init, NewPtr, AllocType.isVolatileQualified());
+      else
+        EmitAggExpr(Init, NewPtr, AllocType.isVolatileQualified());
+    }
+  } else {
+    // Call the constructor.
+    CXXConstructorDecl *Ctor = E->getConstructor();
+
+    EmitCXXConstructorCall(Ctor, Ctor_Complete, NewPtr,
+                           E->constructor_arg_begin(),
+                           E->constructor_arg_end());
+  }
+
+  if (NullCheckResult) {
+    Builder.CreateBr(NewEnd);
+    EmitBlock(NewNull);
+    Builder.CreateBr(NewEnd);
+    EmitBlock(NewEnd);
+
+    llvm::PHINode *PHI = Builder.CreatePHI(NewPtr->getType());
+    PHI->reserveOperandSpace(2);
+    PHI->addIncoming(NewPtr, NewNotNull);
+    PHI->addIncoming(llvm::Constant::getNullValue(NewPtr->getType()), NewNull);
+
+    NewPtr = PHI;
+  }
+
+  return NewPtr;
+}
+
+void CodeGenFunction::EmitCXXDeleteExpr(const CXXDeleteExpr *E) {
+  if (E->isArrayForm()) {
+    ErrorUnsupported(E, "delete[] expression");
+    return;
+  };
+
+  QualType DeleteTy =
+    E->getArgument()->getType()->getAs<PointerType>()->getPointeeType();
+
+  llvm::Value *Ptr = EmitScalarExpr(E->getArgument());
+
+  // Null check the pointer.
+  llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
+  llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
+
+  llvm::Value *IsNull =
+    Builder.CreateICmpEQ(Ptr, llvm::Constant::getNullValue(Ptr->getType()),
+                         "isnull");
+
+  Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
+  EmitBlock(DeleteNotNull);
+
+  // Call the destructor if necessary.
+  if (const RecordType *RT = DeleteTy->getAs<RecordType>()) {
+    if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      if (!RD->hasTrivialDestructor()) {
+        const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
+        if (Dtor->isVirtual()) {
+          const llvm::Type *Ty =
+            CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),
+                                           /*isVariadic=*/false);
+          
+          llvm::Value *Callee = BuildVirtualCall(Dtor, Ptr, Ty);
+          EmitCXXMemberCall(Dtor, Callee, Ptr, 0, 0);
+        } else 
+          EmitCXXDestructorCall(Dtor, Dtor_Complete, Ptr);
+      }
+    }
+  }
+
+  // Call delete.
+  FunctionDecl *DeleteFD = E->getOperatorDelete();
+  const FunctionProtoType *DeleteFTy =
+    DeleteFD->getType()->getAs<FunctionProtoType>();
+
+  CallArgList DeleteArgs;
+
+  QualType ArgTy = DeleteFTy->getArgType(0);
+  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
+  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
+
+  // Emit the call to delete.
+  EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
+                                          DeleteArgs),
+           CGM.GetAddrOfFunction(DeleteFD),
+           DeleteArgs, DeleteFD);
+
+  EmitBlock(DeleteEnd);
+}

Modified: cfe/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CMakeLists.txt?rev=82585&r1=82584&r2=82585&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ cfe/trunk/lib/CodeGen/CMakeLists.txt Tue Sep 22 17:53:17 2009
@@ -5,6 +5,7 @@
   CGBuiltin.cpp
   CGCXX.cpp
   CGCXXClass.cpp
+  CGCXXExpr.cpp
   CGCXXTemp.cpp
   CGCall.cpp
   CGDebugInfo.cpp





More information about the cfe-commits mailing list