~ubuntu-branches/ubuntu/wily/aspectc++/wily

« back to all changes in this revision

Viewing changes to Puma/src/infos/CTypeInfo.cc

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2009-06-15 10:17:02 UTC
  • mfrom: (1.2.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20090615101702-qsr30iptwbxylmo2
Tags: 1.0pre4~svn.20090615-1
* New upstream release.
* don't ignore errors in the postrm script
* avoid spurious creation of empty dir ./usr/sbin/
* improve short descriptions of libpuma-doc and libpuma-dev
* bump Standards-Version to 3.8.1
* bump debhelper compat level to level 7 (latest in stable)

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include "Puma/CObjectInfo.h"
33
33
#include "Puma/CTemplateInfo.h"
34
34
#include "Puma/CArgumentInfo.h"
 
35
#include "Puma/CAttributeInfo.h"
35
36
#include "Puma/DeducedArgument.h"
36
37
#include "Puma/CEnumeratorInfo.h"
37
38
#include "Puma/CTemplateParamInfo.h"
53
54
// Basic types //////////////////////////////////////////////////
54
55
 
55
56
CTypePrimitive CTYPE_BOOL ("bool", CTypeInfo::TYPE_BOOL);
 
57
CTypePrimitive CTYPE_C_BOOL ("_Bool", CTypeInfo::TYPE_C_BOOL);
56
58
CTypePrimitive CTYPE_CHAR ("char", CTypeInfo::TYPE_CHAR);
57
59
CTypePrimitive CTYPE_SIGNED_CHAR ("signed char", CTypeInfo::TYPE_SIGNED_CHAR);
58
60
CTypePrimitive CTYPE_UNSIGNED_CHAR ("unsigned char", CTypeInfo::TYPE_UNSIGNED_CHAR);
78
80
CTypeInfo *CTypeInfo::CTYPE_SIZE_T = &CTYPE_UNSIGNED_INT;  // default type
79
81
CTypeInfo *CTypeInfo::CTYPE_PTRDIFF_T = &CTYPE_INT;        // default type
80
82
 
81
 
bool CTypeInfo::equalTemplateParams (CTemplateParamInfo *p1, CTemplateParamInfo *p2) const {
82
 
  if (p1->isTemplate () != p2->isTemplate ())
83
 
    return false;
84
 
  if (p1->isTypeParam () != p2->isTypeParam ())
85
 
    return false;
86
 
  if (p1->ValueType () && p2->ValueType () && *p1->ValueType () != *p2->ValueType ())
87
 
    return false;
88
 
    
89
 
  if (p1->isTemplate ()) {
90
 
    CTemplateInfo *t1 = p1->TemplateTemplate ();
91
 
    CTemplateInfo *t2 = p1->TemplateTemplate ();
92
 
    if (! t1 || ! t2 || (t1->Parameters () != t2->Parameters ()))
93
 
      return false;
94
 
    for (unsigned i = 0; i < t1->Parameters (); i++) {
95
 
      p1 = t1->Parameter (i);
96
 
      p2 = t2->Parameter (i);
97
 
      if (*p1->TypeInfo () != *p2->TypeInfo ())
98
 
        return false;
99
 
    }
100
 
  }
101
 
  return true;
102
 
}
103
 
 
104
83
bool CTypeInfo::operator ==(const CTypeInfo &type) const {
105
84
  if (! (_Id == type._Id)) {
106
85
    return false;
109
88
  } else if (TypeTemplateParam ()) {
110
89
    CTemplateParamInfo *p1 = TypeTemplateParam ()->TemplateParamInfo ();
111
90
    CTemplateParamInfo *p2 = type.TypeTemplateParam ()->TemplateParamInfo ();
112
 
    return (p1 && p2 && equalTemplateParams (p1, p2));
 
91
    return (p1 && p2 && *p1 == *p2);
113
92
  } else if (TypeClass ()) {
114
93
    CClassInfo *c1 = TypeClass ()->ClassInfo ();
115
94
    CClassInfo *c2 = type.TypeClass ()->ClassInfo ();
195
174
  return false;
196
175
}
197
176
 
198
 
// check if a typedef is defined in a generated template argument scope
199
 
bool isInTemplateArgScope (CObjectInfo *obj) {
200
 
  bool result = (obj->Scope ()->isNamespace () &&
201
 
    ((obj->Scope ()->isAnonymous () && strstr (obj->Scope ()->Name (), "<")) ||
202
 
    strstr (obj->Scope ()->Name (), "__puma_")));
 
177
bool CTypeInfo::isTemplateInstanceArg () const {
 
178
  bool result = false;
 
179
  if (_TypedefInfo) {
 
180
    CScopeInfo* scope = _TypedefInfo->Scope ();
 
181
    if (strcmp (_TypedefInfo->Name (), "__puma_redirect") == 0)
 
182
      scope = scope->Parent ();
 
183
    if (scope->isNamespace () && scope->isAnonymous () && strstr (scope->Name (), "<"))
 
184
      result = true;
 
185
  }
203
186
  return result;
204
187
}
205
 
    
 
188
 
206
189
void CTypeInfo::TypeText (char state, ostream &out, const char *t) const {
207
 
  // check for prefix, safe, and clear the flag
 
190
  // check for prefix, save and clear the flag
208
191
  bool prefix = state & PRINT_PRE;
209
192
  state = state & ~PRINT_PRE;
210
 
  
211
 
  if (isTypedef () && !isInTemplateArgScope (TypedefInfo ()) &&
 
193
 
 
194
  if (isTypedef () && ! isTemplateInstanceArg () &&
212
195
      ((state & PRINT_TDN) ||
213
196
       (TypeEnum () && EnumInfo ()->isAnonymous ()) ||
214
197
       (TypeRecord () && Record ()->isAnonymous ()))) {
217
200
    out << TypedefInfo ()->Name ();
218
201
  } else if (TypeQualified ()) {
219
202
    // print QUALIFIED TYPES
220
 
    std::ostringstream qualifiers;    
 
203
    std::ostringstream qualifiers;
221
204
    if (TypeQualified ()->isConst ()) {
222
205
      qualifiers << "const";
223
206
      if (TypeQualified ()->isVolatile ()) 
273
256
    for (unsigned i = 0; i < argtypes->Entries (); i++) {
274
257
      if (i > 0) name_and_args << ",";
275
258
      CTypeInfo *argtype = argtypes->Entry (i);
276
 
      argtype->TypeText (state, name_and_args);
 
259
      argtype->TypeText ((state & PRINT_ELA) ? (state & ~PRINT_INE) : state,
 
260
                         name_and_args);
277
261
    }
278
262
    name_and_args << ")";
279
263
    if (this_type->isConst ())
306
290
    return;
307
291
  } else if (TypeClass ()) {
308
292
    // print CLASSES
309
 
    if (state & PRINT_ELA) {
 
293
    if ((state & PRINT_ELA) && !(state & PRINT_INE)) {
310
294
      CRecord* record = TypeClass ()->Record ();
311
295
      if (record && record->ClassInfo ()->isStruct ()) {
312
296
        out << "struct ";
318
302
    printName (state, out, TypeClass ()->Record ());
319
303
  } else if (TypeUnion ()) {
320
304
    // print UNIONS
321
 
    if (state & PRINT_ELA) {
 
305
    if ((state & PRINT_ELA) && !(state & PRINT_INE)) {
322
306
      out << "union ";
323
307
    }
324
308
    printScope (state, out, TypeUnion ()->Record ());
325
309
    printName (state, out, TypeUnion ()->Record ());
326
310
  } else if (TypeEnum ()) {
327
311
    // print ENUMS
328
 
    if (state & PRINT_ELA) {
 
312
    if ((state & PRINT_ELA) && !(state & PRINT_INE)) {
329
313
      out << "enum ";
330
314
    }
331
315
    printScope (state, out, TypeEnum ()->EnumInfo ());
360
344
      out << "::";
361
345
    } else if (! scope->isAnonymous ()) {
362
346
      if (scope->Record ()) {
363
 
        scope->TypeInfo ()->TypeText (state, out);
 
347
        // print the scope name, but don't use elaborated type specifier
 
348
        scope->TypeInfo ()->TypeText (state | PRINT_INE, out);
364
349
        out << "::";
365
350
      } else if (scope->NamespaceInfo () && ! scope->GlobalScope ()) {
366
351
        if (state & PRINT_ABS)
394
379
    if (i) 
395
380
      out << ",";
396
381
    if (arg->Type ()) {
397
 
        arg->Type ()->TypeText (state, out, 0);
 
382
        arg->Type ()->TypeText ((state & PRINT_ELA) ? (state & ~PRINT_INE) : state,
 
383
                                out, 0);
398
384
    } else if (arg->Value ()) {
399
385
      out << *arg->Value ();
400
386
    }
521
507
unsigned CTypeInfo::rank () const {
522
508
  switch (Id ()) {
523
509
    case TYPE_BOOL               : return 1;
 
510
    case TYPE_C_BOOL             : return 1;
524
511
    case TYPE_CHAR               : return 2;
525
512
    case TYPE_SIGNED_CHAR        : return 2;
526
513
    case TYPE_UNSIGNED_CHAR      : return 3;
692
679
  if (cinfo) {
693
680
    for (unsigned i = cinfo->Attributes (); i > 0; i--) {
694
681
      info = cinfo->Attribute (i-1);
695
 
      if (info->EnumeratorInfo () || info->Storage () == CStorage::CLASS_STATIC)
 
682
      if (info->EnumeratorInfo () || 
 
683
          info->Storage () == CStorage::CLASS_STATIC || 
 
684
          info->Storage () == CStorage::CLASS_THREAD)
696
685
        continue;
697
686
      type = info->TypeInfo ();
698
687
      align = type->Align ();
718
707
  return 0;
719
708
}
720
709
 
721
 
long int CTypeInfo::Align () const {
722
 
//  else if (TypeArray ())
723
 
//    return BaseType ()->Align ();
724
 
  return 0;
725
 
}
726
 
 
727
710
bool CTypeInfo::isTemplate () const { 
728
711
  return TypeRecord () && TypeRecord ()->Record () ? 
729
712
          TypeRecord ()->Record ()->isTemplate () :
758
741
  return Record () ? (CUnionInfo*)Record ()->DefObject () : (CUnionInfo*)0; 
759
742
}
760
743
 
 
744
 
761
745
bool CTypeTemplateParam::isType () const {
762
746
  return TemplateParamInfo () && TemplateParamInfo ()->isTypeParam ();
763
747
}
764
748
 
765
 
bool CTypeInfo::isDependent (bool consider_unknown_t) const {
 
749
bool CTypeInfo::isDependent (bool consider_unknown_t, bool is_named_type) const {
766
750
  if (consider_unknown_t && is_unknown_t ())
767
751
    return true;
768
752
  if (TypeTemplateParam ())
771
755
    return true;
772
756
  if (isTemplateInstance ()) {
773
757
    if ((TypeRecord () && 
774
 
         TypeRecord ()->Record ()->TemplateInstance ()->isPseudoInstance ()) ||
 
758
         ! TypeRecord ()->Record ()->TemplateInstance ()->canInstantiate ()) ||
775
759
        (TypeFunction () && 
776
 
         TypeFunction ()->FunctionInfo ()->TemplateInstance ()->isPseudoInstance ()))
777
 
      return true;
778
 
  }
779
 
  // HACK? Needed for template template parameters
780
 
  //if (isTemplate ())
781
 
  //  return true;
782
 
  if (TypeClass () && 
783
 
      TypeClass ()->ClassInfo () && 
784
 
      TypeClass ()->ClassInfo ()->hasDepBaseClass () &&
785
 
      ! TypeClass ()->ClassInfo ()->isTemplate ())
786
 
    return true;
 
760
         ! TypeFunction ()->FunctionInfo ()->TemplateInstance ()->canInstantiate ()))
 
761
      return true;
 
762
  }
 
763
  if (TypeClass () && TypeClass ()->ClassInfo ()) {
 
764
    CClassInfo* ci = TypeClass ()->ClassInfo ();
 
765
    if (! ci->isTemplate () && ci->hasDepBaseClass ())
 
766
      return true;
 
767
    if (! is_named_type && ci->isTemplate () && ci->hasDepBaseClass ())
 
768
      return true;
 
769
  }
787
770
  return BaseType () && this != BaseType () && 
788
 
         BaseType ()->isDependent (consider_unknown_t);
 
771
         BaseType ()->isDependent (consider_unknown_t, is_named_type);
789
772
}
790
773
 
791
774
bool CTypeList::isDependent () const {
795
778
  return false;
796
779
}
797
780
 
798
 
 
799
781
static void MangleTemplateArguments (CTemplateInstance *instance, 
800
782
                                     ostream &out) {
801
783
  DeducedArgument *arg;
836
818
  out << "E";
837
819
}
838
820
 
839
 
 
840
821
static void MangleScopedName (const CObjectInfo *info, ostream &out, bool first = true) {
841
822
  CScopeInfo *scope;
842
823
  if (! info || ! info->Name ())
873
854
  } 
874
855
}
875
856
 
876
 
 
877
857
// C++ V3 ABI mangling: see http://www.codesourcery.com/cxx-abi/abi.html#mangling for details 
878
858
void CTypeInfo::Mangled (ostream &out) const {
879
859
 
928
908
  } else if (TypePrimitive ()) {
929
909
    switch (_Id) {
930
910
      case TYPE_BOOL:                out << "b"; break;
 
911
      case TYPE_C_BOOL:              out << "b"; break;
931
912
      case TYPE_CHAR:                out << "c"; break;
932
913
      case TYPE_WCHAR_T:             out << "w"; break;
933
914
      case TYPE_SHORT:               out << "s"; break;
968
949
  return _Enum ? _Enum->UnderlyingType() : &CTYPE_INT; 
969
950
}
970
951
 
 
952
bool CTypeClass::instantiate (CStructure *scope) {
 
953
  // If this is the type of a pseudo class instance, 
 
954
  // create a real instance of the corresponding template. 
 
955
  // Return true if instantiation succeeded.
 
956
  CClassInfo* ci = ClassInfo ();
 
957
  if (ci) {
 
958
    CTemplateInstance* ti = ci->TemplateInstance ();
 
959
    if (ti && ! ti->isInstantiated () && ti->canInstantiate ()) {
 
960
      // instantiate
 
961
      return ti->instantiate (scope);
 
962
    }
 
963
  }
 
964
  return true;
 
965
}
 
966
 
 
967
/** Check if this is a plain old data (POD) type. */
 
968
bool CTypeInfo::isPOD () const {
 
969
  // §3.9p10
 
970
  // Arithmetic types (3.9.1), enumeration types, pointer types, and pointer
 
971
  // to member types (3.9.2), and cv-qualified versions of these types (3.9.3) are
 
972
  // collectively called scalar types. Scalar types, POD-struct types, POD-union
 
973
  // types (clause 9), arrays of such types and cv-qualified versions of these
 
974
  // types (3.9.3) are collectively called POD types.
 
975
  if (isScalar ())
 
976
    return true;
 
977
 
 
978
  // §9p4
 
979
  // A POD-struct is an aggregate class that has no non-static data members of
 
980
  // type pointer to member, non-POD-struct, non-POD-union, or array of such types,
 
981
  // or reference, and has no user-defined copy assignment operator and no user-defined
 
982
  // destructor. Similarly, a POD-union is an aggregate union that has no non-static
 
983
  // data members of type pointer to member, non-POD-struct, non-POD-union, or array
 
984
  // of such types, or reference, and has no user-defined copy assignment operator
 
985
  // and no user-defined destructor. A POD class is a class that is either a POD-struct
 
986
  // or a POD-union.
 
987
  //
 
988
  // $8.5.1p1
 
989
  // An aggregate is an array or a class (clause 9) with no user-declared constructors
 
990
  // (12.1), no private or protected non-static data members (clause 11), no base
 
991
  // classes (clause 10), and no virtual functions (10.3).
 
992
  CRecord* c = isClassOrUnion () ? VirtualType ()->TypeRecord ()->Record () : 0;
 
993
 
 
994
  // class or union without base classes
 
995
  if (c && (! c->ClassInfo () || ! c->ClassInfo ()->BaseClasses ())) {
 
996
 
 
997
    // check data members
 
998
    unsigned i, num = c->Attributes ();
 
999
    for (i = 0; i < num; i++) {
 
1000
      CAttributeInfo* member = c->Attribute (i);
 
1001
      // private or protected data member
 
1002
      if (member->Protection () == CProtection::PROT_PRIVATE ||
 
1003
          member->Protection () == CProtection::PROT_PROTECTED)
 
1004
        break;
 
1005
      // static members don't matter
 
1006
      if (! member->isStatic ()) {
 
1007
        CTypeInfo* type = member->TypeInfo ();
 
1008
        // reference type
 
1009
        if (type->isAddress ())
 
1010
          break;
 
1011
        // get underlying type of array
 
1012
        while (type->isArray ())
 
1013
          type = type->VirtualType ()->BaseType ();
 
1014
        // pointer to member
 
1015
        if (type->isMemberPointer ())
 
1016
          break;
 
1017
        // non-POD class
 
1018
        if (type->isClassOrUnion () && ! type->isPOD ())
 
1019
          break;
 
1020
      }
 
1021
    }
 
1022
    // non-POD member found
 
1023
    if (i != num)
 
1024
      return false;
 
1025
 
 
1026
    // check member functions
 
1027
    num = c->Functions ();
 
1028
    for (i = 0; i < num; i++) {
 
1029
      CFunctionInfo* member = c->Function (i);
 
1030
      // virtual function
 
1031
      if (member->isVirtual ())
 
1032
        break;
 
1033
      // user-defined
 
1034
      if (! member->isBuiltin ()) {
 
1035
        // user-defined constructor or destructor
 
1036
        if (member->isConstructor () || member->isDestructor ())
 
1037
          break;
 
1038
        // copy assignment operator
 
1039
        if (member->isCopyAssignOperator ())
 
1040
          break;
 
1041
      }
 
1042
    }
 
1043
 
 
1044
    // POD class
 
1045
    if (i == num)
 
1046
      return true;
 
1047
  }
 
1048
 
 
1049
  return false;
 
1050
}
 
1051
 
 
1052
long int CTypeInfo::Align () const {
 
1053
  // TODO: Calculation of alignment not yet implemented
 
1054
  //       except for class and union types.
 
1055
  return 1;
 
1056
}
 
1057
 
971
1058
 
972
1059
} // namespace Puma