Slight refactoring.
- Factored out CppLanguage::ParseTypeExpression() into one that could be used in CLanguageFamily, with some hooks to help differentiate what's allowed in C vs C++. Makes the type parsing available for C files as well, and consequently allows typecasting to work for those.
This commit is contained in:
parent
4122ce2aff
commit
87d33c4ff3
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
@ -22,3 +23,13 @@ CLanguage::Name() const
|
||||
{
|
||||
return "C";
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CLanguage::IsModifierValid(char modifier) const
|
||||
{
|
||||
if (modifier == '*')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ public:
|
||||
virtual ~CLanguage();
|
||||
|
||||
virtual const char* Name() const;
|
||||
|
||||
protected:
|
||||
virtual bool IsModifierValid(char modifier) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
/*
|
||||
* Copyright 2013, Rene Gollent, rene@gollent.com.
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "CLanguageFamily.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "TeamTypeInformation.h"
|
||||
#include "Type.h"
|
||||
#include "TypeLookupConstraints.h"
|
||||
|
||||
|
||||
|
||||
CLanguageFamily::CLanguageFamily()
|
||||
{
|
||||
@ -22,3 +30,131 @@ CLanguageFamily::GetSyntaxHighlighter() const
|
||||
// TODO:...
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CLanguageFamily::ParseTypeExpression(const BString& expression,
|
||||
TeamTypeInformation* info, Type*& _resultType) const
|
||||
{
|
||||
status_t result = B_OK;
|
||||
Type* baseType = NULL;
|
||||
|
||||
BString parsedName = expression;
|
||||
BString baseTypeName;
|
||||
BString arraySpecifier;
|
||||
parsedName.RemoveAll(" ");
|
||||
|
||||
int32 modifierIndex = -1;
|
||||
modifierIndex = parsedName.FindFirst('*');
|
||||
if (modifierIndex == -1)
|
||||
modifierIndex = parsedName.FindFirst('&');
|
||||
if (modifierIndex == -1)
|
||||
modifierIndex = parsedName.FindFirst('[');
|
||||
|
||||
if (modifierIndex >= 0)
|
||||
parsedName.MoveInto(baseTypeName, 0, modifierIndex);
|
||||
else
|
||||
baseTypeName = parsedName;
|
||||
|
||||
modifierIndex = parsedName.FindFirst('[');
|
||||
if (modifierIndex >= 0) {
|
||||
parsedName.MoveInto(arraySpecifier, modifierIndex,
|
||||
parsedName.Length() - modifierIndex);
|
||||
}
|
||||
|
||||
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
|
||||
baseType);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BReference<Type> typeRef;
|
||||
typeRef.SetTo(baseType, true);
|
||||
|
||||
if (!parsedName.IsEmpty()) {
|
||||
AddressType* derivedType = NULL;
|
||||
// walk the list of modifiers trying to add each.
|
||||
for (int32 i = 0; i < parsedName.Length(); i++) {
|
||||
if (!IsModifierValid(parsedName[i]))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
address_type_kind typeKind;
|
||||
switch (parsedName[i]) {
|
||||
case '*':
|
||||
{
|
||||
typeKind = DERIVED_TYPE_POINTER;
|
||||
break;
|
||||
}
|
||||
case '&':
|
||||
{
|
||||
typeKind = DERIVED_TYPE_REFERENCE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (derivedType == NULL) {
|
||||
result = baseType->CreateDerivedAddressType(typeKind,
|
||||
derivedType);
|
||||
} else {
|
||||
result = derivedType->CreateDerivedAddressType(typeKind,
|
||||
derivedType);
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
typeRef.SetTo(derivedType, true);
|
||||
}
|
||||
|
||||
_resultType = derivedType;
|
||||
} else
|
||||
_resultType = baseType;
|
||||
|
||||
|
||||
if (!arraySpecifier.IsEmpty()) {
|
||||
ArrayType* arrayType = NULL;
|
||||
|
||||
int32 startIndex = 1;
|
||||
do {
|
||||
int32 size = strtoul(arraySpecifier.String() + startIndex,
|
||||
NULL, 10);
|
||||
if (size < 0)
|
||||
return B_ERROR;
|
||||
|
||||
if (arrayType == NULL) {
|
||||
result = _resultType->CreateDerivedArrayType(0, size, true,
|
||||
arrayType);
|
||||
} else {
|
||||
result = arrayType->CreateDerivedArrayType(0, size, true,
|
||||
arrayType);
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
typeRef.SetTo(arrayType, true);
|
||||
|
||||
startIndex = arraySpecifier.FindFirst('[', startIndex + 1);
|
||||
|
||||
} while (startIndex >= 0);
|
||||
|
||||
// since a C/C++ array is essentially pointer math,
|
||||
// the resulting array has to be wrapped in a pointer to
|
||||
// ensure the element addresses wind up being against the
|
||||
// correct address.
|
||||
AddressType* addressType = NULL;
|
||||
result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER,
|
||||
addressType);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
_resultType = addressType;
|
||||
}
|
||||
|
||||
typeRef.Detach();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -15,6 +15,13 @@ public:
|
||||
virtual ~CLanguageFamily();
|
||||
|
||||
virtual SyntaxHighlighter* GetSyntaxHighlighter() const;
|
||||
|
||||
virtual status_t ParseTypeExpression(const BString& expression,
|
||||
TeamTypeInformation* lookup,
|
||||
Type*& _resultType) const;
|
||||
|
||||
protected:
|
||||
virtual bool IsModifierValid(char modifier) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -7,12 +7,6 @@
|
||||
|
||||
#include "CppLanguage.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "TeamTypeInformation.h"
|
||||
#include "Type.h"
|
||||
#include "TypeLookupConstraints.h"
|
||||
|
||||
|
||||
CppLanguage::CppLanguage()
|
||||
{
|
||||
@ -31,127 +25,11 @@ CppLanguage::Name() const
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
CppLanguage::ParseTypeExpression(const BString &expression,
|
||||
TeamTypeInformation* info,
|
||||
Type*& _resultType) const
|
||||
bool
|
||||
CppLanguage::IsModifierValid(char modifier) const
|
||||
{
|
||||
status_t result = B_OK;
|
||||
Type* baseType = NULL;
|
||||
if (modifier == '*' || modifier == '&')
|
||||
return true;
|
||||
|
||||
BString parsedName = expression;
|
||||
BString baseTypeName;
|
||||
BString arraySpecifier;
|
||||
parsedName.RemoveAll(" ");
|
||||
|
||||
int32 modifierIndex = -1;
|
||||
modifierIndex = parsedName.FindFirst('*');
|
||||
if (modifierIndex == -1)
|
||||
modifierIndex = parsedName.FindFirst('&');
|
||||
if (modifierIndex == -1)
|
||||
modifierIndex = parsedName.FindFirst('[');
|
||||
|
||||
if (modifierIndex >= 0)
|
||||
parsedName.MoveInto(baseTypeName, 0, modifierIndex);
|
||||
else
|
||||
baseTypeName = parsedName;
|
||||
|
||||
modifierIndex = parsedName.FindFirst('[');
|
||||
if (modifierIndex >= 0) {
|
||||
parsedName.MoveInto(arraySpecifier, modifierIndex,
|
||||
parsedName.Length() - modifierIndex);
|
||||
}
|
||||
|
||||
result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(),
|
||||
baseType);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
BReference<Type> typeRef;
|
||||
typeRef.SetTo(baseType, true);
|
||||
|
||||
if (!parsedName.IsEmpty()) {
|
||||
AddressType* derivedType = NULL;
|
||||
// walk the list of modifiers trying to add each.
|
||||
for (int32 i = 0; i < parsedName.Length(); i++) {
|
||||
address_type_kind typeKind;
|
||||
switch (parsedName[i]) {
|
||||
case '*':
|
||||
{
|
||||
typeKind = DERIVED_TYPE_POINTER;
|
||||
break;
|
||||
}
|
||||
case '&':
|
||||
{
|
||||
typeKind = DERIVED_TYPE_REFERENCE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (derivedType == NULL) {
|
||||
result = baseType->CreateDerivedAddressType(typeKind,
|
||||
derivedType);
|
||||
} else {
|
||||
result = derivedType->CreateDerivedAddressType(typeKind,
|
||||
derivedType);
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
typeRef.SetTo(derivedType, true);
|
||||
}
|
||||
|
||||
_resultType = derivedType;
|
||||
} else
|
||||
_resultType = baseType;
|
||||
|
||||
|
||||
if (!arraySpecifier.IsEmpty()) {
|
||||
ArrayType* arrayType = NULL;
|
||||
|
||||
int32 startIndex = 1;
|
||||
do {
|
||||
int32 size = strtoul(arraySpecifier.String() + startIndex,
|
||||
NULL, 10);
|
||||
if (size < 0)
|
||||
return B_ERROR;
|
||||
|
||||
if (arrayType == NULL) {
|
||||
result = _resultType->CreateDerivedArrayType(0, size, true,
|
||||
arrayType);
|
||||
} else {
|
||||
result = arrayType->CreateDerivedArrayType(0, size, true,
|
||||
arrayType);
|
||||
}
|
||||
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
typeRef.SetTo(arrayType, true);
|
||||
|
||||
startIndex = arraySpecifier.FindFirst('[', startIndex + 1);
|
||||
|
||||
} while (startIndex >= 0);
|
||||
|
||||
// since a C/C++ array is essentially pointer math,
|
||||
// the resulting array has to be wrapped in a pointer to
|
||||
// ensure the element addresses wind up being against the
|
||||
// correct address.
|
||||
AddressType* addressType = NULL;
|
||||
result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER,
|
||||
addressType);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
_resultType = addressType;
|
||||
}
|
||||
|
||||
typeRef.Detach();
|
||||
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
@ -16,9 +16,8 @@ public:
|
||||
|
||||
virtual const char* Name() const;
|
||||
|
||||
virtual status_t ParseTypeExpression(const BString &expression,
|
||||
TeamTypeInformation* lookup,
|
||||
Type*& _resultType) const;
|
||||
protected:
|
||||
virtual bool IsModifierValid(char modifier) const;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user