Hi Everyone,<br><br>Way back in August, I had a rudimentary implementation of the C++0x type deduction via the 'auto' type. I never got around to adding the appropriate tests and then there was a major refactor of much of the Sema code that I think made my implementation seem out of place. I've finally gotten around to looking at this again and would like the advice of those more experienced in the type system.<br>
<br>Also, I wasn't sure if I should attach my diff as a file or embed it inline, so I've done both.<br><br>Thanks ahead of time for your help!<br><br><br><span style="font-family: courier new,monospace;">Index: include/clang/Sema/Sema.h</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--- include/clang/Sema/Sema.h (revision 121900)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+++ include/clang/Sema/Sema.h (working copy)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">@@ -986,6 +986,13 @@</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> bool TryImplicitConversion(InitializationSequence &Sequence,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ QualType ToType,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ Expr *From,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ bool SuppressUserConversions,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ bool AllowExplicit,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ bool InOverloadResolution);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ bool TryImplicitConversion(InitializationSequence &Sequence,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> const InitializedEntity &Entity,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> Expr *From,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> bool SuppressUserConversions,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Index: include/clang/Sema/Initialization.h</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--- include/clang/Sema/Initialization.h (revision 121900)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+++ include/clang/Sema/Initialization.h (working copy)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">@@ -552,6 +552,8 @@</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> /// \brief Steps taken by this initialization.</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> llvm::SmallVector<Step, 4> Steps;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ QualType DeducedType;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> public:</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> /// \brief Describes why initialization failed.</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Index: include/clang/AST/CanonicalType.h</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">--- include/clang/AST/CanonicalType.h (revision 121900)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+++ include/clang/AST/CanonicalType.h (working copy)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">@@ -277,6 +277,7 @@</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUnionType)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isComplexIntegerType)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isNullPtrType)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isUndeducedAutoType)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isDependentType)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isOverloadableType)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Index: include/clang/AST/Type.h</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">--- include/clang/AST/Type.h (revision 121900)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+++ include/clang/AST/Type.h (working copy)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">@@ -1176,6 +1176,7 @@</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bool isObjCBuiltinType() const; // 'id' or 'Class'</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> bool isTemplateTypeParmType() const; // C++ template type parameter</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bool isNullPtrType() const; // C++0x nullptr_t</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ bool isUndeducedAutoType() const; // C++0x yet to be deduced 'auto'</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> enum ScalarTypeKind {</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> STK_Pointer,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Index: lib/Sema/SemaInit.cpp</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">--- lib/Sema/SemaInit.cpp (revision 121900)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+++ lib/Sema/SemaInit.cpp (working copy)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">@@ -3094,12 +3094,6 @@</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // parenthesized list of expressions.</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> QualType DestType = Entity.getType();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">- if (DestType->isDependentType() ||</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">- Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">- SequenceKind = DependentSequence;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">- return;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">- }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">-</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> for (unsigned I = 0; I != NumArgs; ++I)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> if (Args[I]->getObjectKind() == OK_ObjCProperty)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> S.ConvertPropertyForRValue(Args[I]);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">@@ -3111,6 +3105,19 @@</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> if (!isa<InitListExpr>(Initializer))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> SourceType = Initializer->getType();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ if (S.getLangOptions().CPlusPlus0x) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ if (DestType->isUndeducedAutoType() && !SourceType.isNull()) { // TODO: Can 'auto' be initialized with a list?</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ DeducedType = SourceType;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ DestType = SourceType;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ if (DestType->isDependentType() ||</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ SequenceKind = DependentSequence;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ return;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // - If the initializer is a braced-init-list, the object is </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // list-initialized (8.5.4).</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">@@ -3183,7 +3190,7 @@</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> (Context.hasSameUnqualifiedType(SourceType, DestType) ||</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> S.IsDerivedFrom(SourceType, DestType))))</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">- Entity.getType(), *this);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ DestType, *this);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // - Otherwise (i.e., for the remaining copy-initialization cases), </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // user-defined conversion sequences that can convert from the source</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // type to the destination type or (when a conversion function is </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">@@ -3213,7 +3220,7 @@</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // conversions (Clause 4) will be used, if necessary, to convert the</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // initializer expression to the cv-unqualified version of the </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // destination type; no user-defined conversions are considered.</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">- if (S.TryImplicitConversion(*this, Entity, Initializer,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ if (S.TryImplicitConversion(*this, DestType, Initializer,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> /*SuppressUserConversions*/ true,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> /*AllowExplicitConversions*/ false,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> /*InOverloadResolution*/ false))</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">@@ -3548,6 +3555,10 @@</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> return ExprError();</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ if (ResultType && !DeducedType.isNull()) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ *ResultType = DeducedType;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ }</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> if (SequenceKind == DependentSequence) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // If the declaration is a non-dependent, incomplete array type</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // that has an initializer, then its type will be completed once</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">@@ -3609,7 +3620,7 @@</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // FIXME: Ugly hack around the fact that Entity.getType() is not</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // the same as Entity.getDecl()->getType() in cases involving type merging,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> // and we want latter when it makes sense.</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">- if (ResultType)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ if (ResultType && DeducedType.isNull())</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> *ResultType = Entity.getDecl() ? Entity.getDecl()->getType() :</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> Entity.getType();</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Index: lib/Sema/SemaOverload.cpp</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--- lib/Sema/SemaOverload.cpp (revision 121900)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+++ lib/Sema/SemaOverload.cpp (working copy)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">@@ -834,23 +834,37 @@</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bool Sema::TryImplicitConversion(InitializationSequence &Sequence,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">- const InitializedEntity &Entity,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ QualType ToType,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> Expr *Initializer,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bool SuppressUserConversions,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> bool AllowExplicitConversions,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bool InOverloadResolution) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> ImplicitConversionSequence ICS</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">- = clang::TryImplicitConversion(*this, Initializer, Entity.getType(),</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ = clang::TryImplicitConversion(*this, Initializer, ToType,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> SuppressUserConversions,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> AllowExplicitConversions, </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> InOverloadResolution);</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> if (ICS.isBad()) return true;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // Perform the actual conversion.</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">- Sequence.AddConversionSequenceStep(ICS, Entity.getType());</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ Sequence.AddConversionSequenceStep(ICS, ToType);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> return false;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+bool Sema::TryImplicitConversion(InitializationSequence &Sequence,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ const InitializedEntity &Entity,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ Expr *Initializer,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ bool SuppressUserConversions,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ bool AllowExplicitConversions,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ bool InOverloadResolution) {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ return TryImplicitConversion(Sequence, Entity.getType(),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ Initializer, SuppressUserConversions,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ AllowExplicitConversions, InOverloadResolution);</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ </span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> /// PerformImplicitConversion - Perform an implicit conversion of the</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> /// expression From to the type ToType. Returns true if there was an</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> /// error, false otherwise. The expression From is replaced with the</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Index: lib/AST/Type.cpp</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">===================================================================</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">--- lib/AST/Type.cpp (revision 121900)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+++ lib/AST/Type.cpp (working copy)</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">@@ -862,6 +862,12 @@</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> return false;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> }</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> </span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+bool Type::isUndeducedAutoType() const {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ if (const BuiltinType *BT = getAs<BuiltinType>())</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+ return BT->getKind() == BuiltinType::UndeducedAuto;</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+ return false;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">+}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">+</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> bool Type::isSpecifierType() const {</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> // Note that this intentionally does not use the canonical type.</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> switch (getTypeClass()) {</span><br style="font-family: courier new,monospace;">
<br>