aboutsummaryrefslogtreecommitdiffstats
path: root/lib/AsmParser
diff options
context:
space:
mode:
authorNowar Gu <nowar100@gmail.com>2011-07-16 20:12:42 +0800
committerNowar Gu <nowar100@gmail.com>2011-07-16 20:58:03 +0800
commita71642b2a4944eaa269d881cf71b02b8e8fe5638 (patch)
tree700ef6031477973400c762125d0302d5924cae56 /lib/AsmParser
parent7445072fa666b054015b797743e08c02557068e9 (diff)
parent91ddfc4723f5857e0124192d71e625a7926cbc70 (diff)
downloadexternal_llvm-a71642b2a4944eaa269d881cf71b02b8e8fe5638.zip
external_llvm-a71642b2a4944eaa269d881cf71b02b8e8fe5638.tar.gz
external_llvm-a71642b2a4944eaa269d881cf71b02b8e8fe5638.tar.bz2
Merge upstream to r135343 at Sat. 16th July 2011.
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLLexer.h4
-rw-r--r--lib/AsmParser/LLParser.cpp608
-rw-r--r--lib/AsmParser/LLParser.h87
3 files changed, 320 insertions, 379 deletions
diff --git a/lib/AsmParser/LLLexer.h b/lib/AsmParser/LLLexer.h
index 4fe705e..33b9135 100644
--- a/lib/AsmParser/LLLexer.h
+++ b/lib/AsmParser/LLLexer.h
@@ -38,7 +38,7 @@ namespace llvm {
lltok::Kind CurKind;
std::string StrVal;
unsigned UIntVal;
- const Type *TyVal;
+ Type *TyVal;
APFloat APFloatVal;
APSInt APSIntVal;
@@ -56,7 +56,7 @@ namespace llvm {
LocTy getLoc() const { return SMLoc::getFromPointer(TokStart); }
lltok::Kind getKind() const { return CurKind; }
const std::string &getStrVal() const { return StrVal; }
- const Type *getTyVal() const { return TyVal; }
+ Type *getTyVal() const { return TyVal; }
unsigned getUIntVal() const { return UIntVal; }
const APSInt &getAPSIntVal() const { return APSIntVal; }
const APFloat &getAPFloatVal() const { return APFloatVal; }
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index d985851..cfc31f3 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -89,15 +89,16 @@ bool LLParser::ValidateEndOfModule() {
ForwardRefBlockAddresses.erase(ForwardRefBlockAddresses.begin());
}
-
- if (!ForwardRefTypes.empty())
- return Error(ForwardRefTypes.begin()->second.second,
- "use of undefined type named '" +
- ForwardRefTypes.begin()->first + "'");
- if (!ForwardRefTypeIDs.empty())
- return Error(ForwardRefTypeIDs.begin()->second.second,
- "use of undefined type '%" +
- Twine(ForwardRefTypeIDs.begin()->first) + "'");
+ for (unsigned i = 0, e = NumberedTypes.size(); i != e; ++i)
+ if (NumberedTypes[i].second.isValid())
+ return Error(NumberedTypes[i].second,
+ "use of undefined type '%" + Twine(i) + "'");
+
+ for (StringMap<std::pair<Type*, LocTy> >::iterator I =
+ NamedTypes.begin(), E = NamedTypes.end(); I != E; ++I)
+ if (I->second.second.isValid())
+ return Error(I->second.second,
+ "use of undefined type named '" + I->getKey() + "'");
if (!ForwardRefVals.empty())
return Error(ForwardRefVals.begin()->second.second,
@@ -293,36 +294,32 @@ bool LLParser::ParseDepLibs() {
/// ::= LocalVarID '=' 'type' type
bool LLParser::ParseUnnamedType() {
LocTy TypeLoc = Lex.getLoc();
- unsigned TypeID = NumberedTypes.size();
- if (Lex.getUIntVal() != TypeID)
- return Error(Lex.getLoc(), "type expected to be numbered '%" +
- Twine(TypeID) + "'");
+ unsigned TypeID = Lex.getUIntVal();
Lex.Lex(); // eat LocalVarID;
if (ParseToken(lltok::equal, "expected '=' after name") ||
ParseToken(lltok::kw_type, "expected 'type' after '='"))
return true;
- PATypeHolder Ty(Type::getVoidTy(Context));
- if (ParseType(Ty)) return true;
-
- // See if this type was previously referenced.
- std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
- FI = ForwardRefTypeIDs.find(TypeID);
- if (FI != ForwardRefTypeIDs.end()) {
- if (FI->second.first.get() == Ty)
- return Error(TypeLoc, "self referential type is invalid");
-
- cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
- Ty = FI->second.first.get();
- ForwardRefTypeIDs.erase(FI);
+ if (TypeID >= NumberedTypes.size())
+ NumberedTypes.resize(TypeID+1);
+
+ Type *Result = 0;
+ if (ParseStructDefinition(TypeLoc, "",
+ NumberedTypes[TypeID], Result)) return true;
+
+ if (!isa<StructType>(Result)) {
+ std::pair<Type*, LocTy> &Entry = NumberedTypes[TypeID];
+ if (Entry.first)
+ return Error(TypeLoc, "non-struct types may not be recursive");
+ Entry.first = Result;
+ Entry.second = SMLoc();
}
- NumberedTypes.push_back(Ty);
-
return false;
}
+
/// toplevelentity
/// ::= LocalVar '=' 'type' type
bool LLParser::ParseNamedType() {
@@ -330,37 +327,23 @@ bool LLParser::ParseNamedType() {
LocTy NameLoc = Lex.getLoc();
Lex.Lex(); // eat LocalVar.
- PATypeHolder Ty(Type::getVoidTy(Context));
-
if (ParseToken(lltok::equal, "expected '=' after name") ||
- ParseToken(lltok::kw_type, "expected 'type' after name") ||
- ParseType(Ty))
+ ParseToken(lltok::kw_type, "expected 'type' after name"))
return true;
-
- // Set the type name, checking for conflicts as we do so.
- bool AlreadyExists = M->addTypeName(Name, Ty);
- if (!AlreadyExists) return false;
-
- // See if this type is a forward reference. We need to eagerly resolve
- // types to allow recursive type redefinitions below.
- std::map<std::string, std::pair<PATypeHolder, LocTy> >::iterator
- FI = ForwardRefTypes.find(Name);
- if (FI != ForwardRefTypes.end()) {
- if (FI->second.first.get() == Ty)
- return Error(NameLoc, "self referential type is invalid");
-
- cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
- Ty = FI->second.first.get();
- ForwardRefTypes.erase(FI);
- return false;
+
+ Type *Result = 0;
+ if (ParseStructDefinition(NameLoc, Name,
+ NamedTypes[Name], Result)) return true;
+
+ if (!isa<StructType>(Result)) {
+ std::pair<Type*, LocTy> &Entry = NamedTypes[Name];
+ if (Entry.first)
+ return Error(NameLoc, "non-struct types may not be recursive");
+ Entry.first = Result;
+ Entry.second = SMLoc();
}
-
- // Inserting a name that is already defined, get the existing name.
- assert(M->getTypeByName(Name) && "Conflict but no matching type?!");
-
- // Otherwise, this is an attempt to redefine a type, report the error.
- return Error(NameLoc, "redefinition of type named '" + Name + "' of type '" +
- getTypeString(Ty) + "'");
+
+ return false;
}
@@ -536,7 +519,7 @@ bool LLParser::ParseStandaloneMetadata() {
unsigned MetadataID = 0;
LocTy TyLoc;
- PATypeHolder Ty(Type::getVoidTy(Context));
+ Type *Ty = 0;
SmallVector<Value *, 16> Elts;
if (ParseUInt32(MetadataID) ||
ParseToken(lltok::equal, "expected '=' here") ||
@@ -668,7 +651,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
LocTy UnnamedAddrLoc;
LocTy TyLoc;
- PATypeHolder Ty(Type::getVoidTy(Context));
+ Type *Ty = 0;
if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) ||
ParseOptionalAddrSpace(AddrSpace) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
@@ -792,18 +775,11 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty,
// Otherwise, create a new forward reference for this value and remember it.
GlobalValue *FwdVal;
- if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
- // Function types can return opaque but functions can't.
- if (FT->getReturnType()->isOpaqueTy()) {
- Error(Loc, "function may not return opaque type");
- return 0;
- }
-
+ if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
- } else {
+ else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
GlobalValue::ExternalWeakLinkage, 0, Name);
- }
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -837,17 +813,11 @@ GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) {
// Otherwise, create a new forward reference for this value and remember it.
GlobalValue *FwdVal;
- if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
- // Function types can return opaque but functions can't.
- if (FT->getReturnType()->isOpaqueTy()) {
- Error(Loc, "function may not return opaque type");
- return 0;
- }
+ if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType()))
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
- } else {
+ else
FwdVal = new GlobalVariable(*M, PTy->getElementType(), false,
GlobalValue::ExternalWeakLinkage, 0, "");
- }
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
return FwdVal;
@@ -1228,165 +1198,68 @@ bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices,
// Type Parsing.
//===----------------------------------------------------------------------===//
-/// ParseType - Parse and resolve a full type.
-bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) {
- LocTy TypeLoc = Lex.getLoc();
- if (ParseTypeRec(Result)) return true;
-
- // Verify no unresolved uprefs.
- if (!UpRefs.empty())
- return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
-
- if (!AllowVoid && Result.get()->isVoidTy())
- return Error(TypeLoc, "void type only allowed for function results");
-
- return false;
-}
-
-/// HandleUpRefs - Every time we finish a new layer of types, this function is
-/// called. It loops through the UpRefs vector, which is a list of the
-/// currently active types. For each type, if the up-reference is contained in
-/// the newly completed type, we decrement the level count. When the level
-/// count reaches zero, the up-referenced type is the type that is passed in:
-/// thus we can complete the cycle.
-///
-PATypeHolder LLParser::HandleUpRefs(const Type *ty) {
- // If Ty isn't abstract, or if there are no up-references in it, then there is
- // nothing to resolve here.
- if (!ty->isAbstract() || UpRefs.empty()) return ty;
-
- PATypeHolder Ty(ty);
-#if 0
- dbgs() << "Type '" << *Ty
- << "' newly formed. Resolving upreferences.\n"
- << UpRefs.size() << " upreferences active!\n";
-#endif
-
- // If we find any resolvable upreferences (i.e., those whose NestingLevel goes
- // to zero), we resolve them all together before we resolve them to Ty. At
- // the end of the loop, if there is anything to resolve to Ty, it will be in
- // this variable.
- OpaqueType *TypeToResolve = 0;
-
- for (unsigned i = 0; i != UpRefs.size(); ++i) {
- // Determine if 'Ty' directly contains this up-references 'LastContainedTy'.
- bool ContainsType =
- std::find(Ty->subtype_begin(), Ty->subtype_end(),
- UpRefs[i].LastContainedTy) != Ty->subtype_end();
-
-#if 0
- dbgs() << " UR#" << i << " - TypeContains(" << *Ty << ", "
- << *UpRefs[i].LastContainedTy << ") = "
- << (ContainsType ? "true" : "false")
- << " level=" << UpRefs[i].NestingLevel << "\n";
-#endif
- if (!ContainsType)
- continue;
-
- // Decrement level of upreference
- unsigned Level = --UpRefs[i].NestingLevel;
- UpRefs[i].LastContainedTy = Ty;
-
- // If the Up-reference has a non-zero level, it shouldn't be resolved yet.
- if (Level != 0)
- continue;
-
-#if 0
- dbgs() << " * Resolving upreference for " << UpRefs[i].UpRefTy << "\n";
-#endif
- if (!TypeToResolve)
- TypeToResolve = UpRefs[i].UpRefTy;
- else
- UpRefs[i].UpRefTy->refineAbstractTypeTo(TypeToResolve);
- UpRefs.erase(UpRefs.begin()+i); // Remove from upreference list.
- --i; // Do not skip the next element.
- }
-
- if (TypeToResolve)
- TypeToResolve->refineAbstractTypeTo(Ty);
-
- return Ty;
-}
-
-
-/// ParseTypeRec - The recursive function used to process the internal
-/// implementation details of types.
-bool LLParser::ParseTypeRec(PATypeHolder &Result) {
+/// ParseType - Parse a type.
+bool LLParser::ParseType(Type *&Result, bool AllowVoid) {
+ SMLoc TypeLoc = Lex.getLoc();
switch (Lex.getKind()) {
default:
return TokError("expected type");
case lltok::Type:
- // TypeRec ::= 'float' | 'void' (etc)
+ // Type ::= 'float' | 'void' (etc)
Result = Lex.getTyVal();
Lex.Lex();
break;
- case lltok::kw_opaque:
- // TypeRec ::= 'opaque'
- Result = OpaqueType::get(Context);
- Lex.Lex();
- break;
case lltok::lbrace:
- // TypeRec ::= '{' ... '}'
- if (ParseStructType(Result, false))
+ // Type ::= StructType
+ if (ParseAnonStructType(Result, false))
return true;
break;
case lltok::lsquare:
- // TypeRec ::= '[' ... ']'
+ // Type ::= '[' ... ']'
Lex.Lex(); // eat the lsquare.
if (ParseArrayVectorType(Result, false))
return true;
break;
case lltok::less: // Either vector or packed struct.
- // TypeRec ::= '<' ... '>'
+ // Type ::= '<' ... '>'
Lex.Lex();
if (Lex.getKind() == lltok::lbrace) {
- if (ParseStructType(Result, true) ||
+ if (ParseAnonStructType(Result, true) ||
ParseToken(lltok::greater, "expected '>' at end of packed struct"))
return true;
} else if (ParseArrayVectorType(Result, true))
return true;
break;
- case lltok::LocalVar:
- // TypeRec ::= %foo
- if (const Type *T = M->getTypeByName(Lex.getStrVal())) {
- Result = T;
- } else {
- Result = OpaqueType::get(Context);
- ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(),
- std::make_pair(Result,
- Lex.getLoc())));
- M->addTypeName(Lex.getStrVal(), Result.get());
+ case lltok::LocalVar: {
+ // Type ::= %foo
+ std::pair<Type*, LocTy> &Entry = NamedTypes[Lex.getStrVal()];
+
+ // If the type hasn't been defined yet, create a forward definition and
+ // remember where that forward def'n was seen (in case it never is defined).
+ if (Entry.first == 0) {
+ Entry.first = StructType::createNamed(Context, Lex.getStrVal());
+ Entry.second = Lex.getLoc();
}
+ Result = Entry.first;
Lex.Lex();
break;
+ }
- case lltok::LocalVarID:
- // TypeRec ::= %4
- if (Lex.getUIntVal() < NumberedTypes.size())
- Result = NumberedTypes[Lex.getUIntVal()];
- else {
- std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
- I = ForwardRefTypeIDs.find(Lex.getUIntVal());
- if (I != ForwardRefTypeIDs.end())
- Result = I->second.first;
- else {
- Result = OpaqueType::get(Context);
- ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(),
- std::make_pair(Result,
- Lex.getLoc())));
- }
+ case lltok::LocalVarID: {
+ // Type ::= %4
+ if (Lex.getUIntVal() >= NumberedTypes.size())
+ NumberedTypes.resize(Lex.getUIntVal()+1);
+ std::pair<Type*, LocTy> &Entry = NumberedTypes[Lex.getUIntVal()];
+
+ // If the type hasn't been defined yet, create a forward definition and
+ // remember where that forward def'n was seen (in case it never is defined).
+ if (Entry.first == 0) {
+ Entry.first = StructType::createNamed(Context, "");
+ Entry.second = Lex.getLoc();
}
+ Result = Entry.first;
Lex.Lex();
break;
- case lltok::backslash: {
- // TypeRec ::= '\' 4
- Lex.Lex();
- unsigned Val;
- if (ParseUInt32(Val)) return true;
- OpaqueType *OT = OpaqueType::get(Context); //Use temporary placeholder.
- UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT));
- Result = OT;
- break;
}
}
@@ -1394,34 +1267,37 @@ bool LLParser::ParseTypeRec(PATypeHolder &Result) {
while (1) {
switch (Lex.getKind()) {
// End of type.
- default: return false;
+ default:
+ if (!AllowVoid && Result->isVoidTy())
+ return Error(TypeLoc, "void type only allowed for function results");
+ return false;
- // TypeRec ::= TypeRec '*'
+ // Type ::= Type '*'
case lltok::star:
- if (Result.get()->isLabelTy())
+ if (Result->isLabelTy())
return TokError("basic block pointers are invalid");
- if (Result.get()->isVoidTy())
- return TokError("pointers to void are invalid; use i8* instead");
- if (!PointerType::isValidElementType(Result.get()))
+ if (Result->isVoidTy())
+ return TokError("pointers to void are invalid - use i8* instead");
+ if (!PointerType::isValidElementType(Result))
return TokError("pointer to this type is invalid");
- Result = HandleUpRefs(PointerType::getUnqual(Result.get()));
+ Result = PointerType::getUnqual(Result);
Lex.Lex();
break;
- // TypeRec ::= TypeRec 'addrspace' '(' uint32 ')' '*'
+ // Type ::= Type 'addrspace' '(' uint32 ')' '*'
case lltok::kw_addrspace: {
- if (Result.get()->isLabelTy())
+ if (Result->isLabelTy())
return TokError("basic block pointers are invalid");
- if (Result.get()->isVoidTy())
+ if (Result->isVoidTy())
return TokError("pointers to void are invalid; use i8* instead");
- if (!PointerType::isValidElementType(Result.get()))
+ if (!PointerType::isValidElementType(Result))
return TokError("pointer to this type is invalid");
unsigned AddrSpace;
if (ParseOptionalAddrSpace(AddrSpace) ||
ParseToken(lltok::star, "expected '*' in address space"))
return true;
- Result = HandleUpRefs(PointerType::get(Result.get(), AddrSpace));
+ Result = PointerType::get(Result, AddrSpace);
break;
}
@@ -1452,7 +1328,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
// Parse the argument.
LocTy ArgLoc;
- PATypeHolder ArgTy(Type::getVoidTy(Context));
+ Type *ArgTy = 0;
unsigned ArgAttrs1 = Attribute::None;
unsigned ArgAttrs2 = Attribute::None;
Value *V;
@@ -1472,7 +1348,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
/// ParseArgumentList - Parse the argument list for a function type or function
-/// prototype. If 'inType' is true then we are parsing a FunctionType.
+/// prototype.
/// ::= '(' ArgTypeListI ')'
/// ArgTypeListI
/// ::= /*empty*/
@@ -1480,8 +1356,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
/// ::= ArgTypeList ',' '...'
/// ::= ArgType (',' ArgType)*
///
-bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
- bool &isVarArg, bool inType) {
+bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
+ bool &isVarArg){
isVarArg = false;
assert(Lex.getKind() == lltok::lparen);
Lex.Lex(); // eat the (.
@@ -1493,14 +1369,11 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
Lex.Lex();
} else {
LocTy TypeLoc = Lex.getLoc();
- PATypeHolder ArgTy(Type::getVoidTy(Context));
+ Type *ArgTy = 0;
unsigned Attrs;
std::string Name;
- // If we're parsing a type, use ParseTypeRec, because we allow recursive
- // types (such as a function returning a pointer to itself). If parsing a
- // function prototype, we require fully resolved types.
- if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
+ if (ParseType(ArgTy) ||
ParseOptionalAttrs(Attrs, 0)) return true;
if (ArgTy->isVoidTy())
@@ -1525,8 +1398,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
// Otherwise must be an argument type.
TypeLoc = Lex.getLoc();
- if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
- ParseOptionalAttrs(Attrs, 0)) return true;
+ if (ParseType(ArgTy) || ParseOptionalAttrs(Attrs, 0)) return true;
if (ArgTy->isVoidTy())
return Error(TypeLoc, "argument can not have void type");
@@ -1538,7 +1410,7 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
Name = "";
}
- if (!ArgTy->isFirstClassType() && !ArgTy->isOpaqueTy())
+ if (!ArgTy->isFirstClassType())
return Error(TypeLoc, "invalid type for function argument");
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
@@ -1550,15 +1422,15 @@ bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
/// ParseFunctionType
/// ::= Type ArgumentList OptionalAttrs
-bool LLParser::ParseFunctionType(PATypeHolder &Result) {
+bool LLParser::ParseFunctionType(Type *&Result) {
assert(Lex.getKind() == lltok::lparen);
if (!FunctionType::isValidReturnType(Result))
return TokError("invalid function return type");
- std::vector<ArgInfo> ArgList;
+ SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
- if (ParseArgumentList(ArgList, isVarArg, true))
+ if (ParseArgumentList(ArgList, isVarArg))
return true;
// Reject names on the arguments lists.
@@ -1570,68 +1442,122 @@ bool LLParser::ParseFunctionType(PATypeHolder &Result) {
"argument attributes invalid in function type");
}
- std::vector<const Type*> ArgListTy;
+ SmallVector<Type*, 16> ArgListTy;
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
- ArgListTy.push_back(ArgList[i].Type);
+ ArgListTy.push_back(ArgList[i].Ty);
+
+ Result = FunctionType::get(Result, ArgListTy, isVarArg);
+ return false;
+}
- Result = HandleUpRefs(FunctionType::get(Result.get(),
- ArgListTy, isVarArg));
+/// ParseAnonStructType - Parse an anonymous struct type, which is inlined into
+/// other structs.
+bool LLParser::ParseAnonStructType(Type *&Result, bool Packed) {
+ SmallVector<Type*, 8> Elts;
+ if (ParseStructBody(Elts)) return true;
+
+ Result = StructType::get(Context, Elts, Packed);
+ return false;
+}
+
+/// ParseStructDefinition - Parse a struct in a 'type' definition.
+bool LLParser::ParseStructDefinition(SMLoc TypeLoc, StringRef Name,
+ std::pair<Type*, LocTy> &Entry,
+ Type *&ResultTy) {
+ // If the type was already defined, diagnose the redefinition.
+ if (Entry.first && !Entry.second.isValid())
+ return Error(TypeLoc, "redefinition of type");
+
+ // If we have opaque, just return without filling in the definition for the
+ // struct. This counts as a definition as far as the .ll file goes.
+ if (EatIfPresent(lltok::kw_opaque)) {
+ // This type is being defined, so clear the location to indicate this.
+ Entry.second = SMLoc();
+
+ // If this type number has never been uttered, create it.
+ if (Entry.first == 0)
+ Entry.first = StructType::createNamed(Context, Name);
+ ResultTy = Entry.first;
+ return false;
+ }
+
+ // If the type starts with '<', then it is either a packed struct or a vector.
+ bool isPacked = EatIfPresent(lltok::less);
+
+ // If we don't have a struct, then we have a random type alias, which we
+ // accept for compatibility with old files. These types are not allowed to be
+ // forward referenced and not allowed to be recursive.
+ if (Lex.getKind() != lltok::lbrace) {
+ if (Entry.first)
+ return Error(TypeLoc, "forward references to non-struct type");
+
+ ResultTy = 0;
+ if (isPacked)
+ return ParseArrayVectorType(ResultTy, true);
+ return ParseType(ResultTy);
+ }
+
+ // This type is being defined, so clear the location to indicate this.
+ Entry.second = SMLoc();
+
+ // If this type number has never been uttered, create it.
+ if (Entry.first == 0)
+ Entry.first = StructType::createNamed(Context, Name);
+
+ StructType *STy = cast<StructType>(Entry.first);
+
+ SmallVector<Type*, 8> Body;
+ if (ParseStructBody(Body) ||
+ (isPacked && ParseToken(lltok::greater, "expected '>' in packed struct")))
+ return true;
+
+ STy->setBody(Body, isPacked);
+ ResultTy = STy;
return false;
}
+
/// ParseStructType: Handles packed and unpacked types. </> parsed elsewhere.
-/// TypeRec
+/// StructType
/// ::= '{' '}'
-/// ::= '{' TypeRec (',' TypeRec)* '}'
+/// ::= '{' Type (',' Type)* '}'
/// ::= '<' '{' '}' '>'
-/// ::= '<' '{' TypeRec (',' TypeRec)* '}' '>'
-bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
+/// ::= '<' '{' Type (',' Type)* '}' '>'
+bool LLParser::ParseStructBody(SmallVectorImpl<Type*> &Body) {
assert(Lex.getKind() == lltok::lbrace);
Lex.Lex(); // Consume the '{'
- if (EatIfPresent(lltok::rbrace)) {
- Result = StructType::get(Context, Packed);
+ // Handle the empty struct.
+ if (EatIfPresent(lltok::rbrace))
return false;
- }
- std::vector<PATypeHolder> ParamsList;
LocTy EltTyLoc = Lex.getLoc();
- if (ParseTypeRec(Result)) return true;
- ParamsList.push_back(Result);
+ Type *Ty = 0;
+ if (ParseType(Ty)) return true;
+ Body.push_back(Ty);
- if (Result->isVoidTy())
- return Error(EltTyLoc, "struct element can not have void type");
- if (!StructType::isValidElementType(Result))
+ if (!StructType::isValidElementType(Ty))
return Error(EltTyLoc, "invalid element type for struct");
while (EatIfPresent(lltok::comma)) {
EltTyLoc = Lex.getLoc();
- if (ParseTypeRec(Result)) return true;
+ if (ParseType(Ty)) return true;
- if (Result->isVoidTy())
- return Error(EltTyLoc, "struct element can not have void type");
- if (!StructType::isValidElementType(Result))
+ if (!StructType::isValidElementType(Ty))
return Error(EltTyLoc, "invalid element type for struct");
- ParamsList.push_back(Result);
+ Body.push_back(Ty);
}
- if (ParseToken(lltok::rbrace, "expected '}' at end of struct"))
- return true;
-
- std::vector<const Type*> ParamsListTy;
- for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
- ParamsListTy.push_back(ParamsList[i].get());
- Result = HandleUpRefs(StructType::get(Context, ParamsListTy, Packed));
- return false;
+ return ParseToken(lltok::rbrace, "expected '}' at end of struct");
}
/// ParseArrayVectorType - Parse an array or vector type, assuming the first
/// token has already been consumed.
-/// TypeRec
+/// Type
/// ::= '[' APSINTVAL 'x' Types ']'
/// ::= '<' APSINTVAL 'x' Types '>'
-bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
+bool LLParser::ParseArrayVectorType(Type *&Result, bool isVector) {
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
Lex.getAPSIntVal().getBitWidth() > 64)
return TokError("expected number in address space");
@@ -1644,11 +1570,8 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
return true;
LocTy TypeLoc = Lex.getLoc();
- PATypeHolder EltTy(Type::getVoidTy(Context));
- if (ParseTypeRec(EltTy)) return true;
-
- if (EltTy->isVoidTy())
- return Error(TypeLoc, "array and vector element type cannot be void");
+ Type *EltTy = 0;
+ if (ParseType(EltTy)) return true;
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
"expected end of sequential type"))
@@ -1665,7 +1588,7 @@ bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
} else {
if (!ArrayType::isValidElementType(EltTy))
return Error(TypeLoc, "invalid array element type");
- Result = HandleUpRefs(ArrayType::get(EltTy, Size));
+ Result = ArrayType::get(EltTy, Size);
}
return false;
}
@@ -1770,7 +1693,7 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
}
// Don't make placeholders with invalid type.
- if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) {
+ if (!Ty->isFirstClassType() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
return 0;
}
@@ -1811,7 +1734,7 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty,
return 0;
}
- if (!Ty->isFirstClassType() && !Ty->isOpaqueTy() && !Ty->isLabelTy()) {
+ if (!Ty->isFirstClassType() && !Ty->isLabelTy()) {
P.Error(Loc, "invalid use of a non-first-class type");
return 0;
}
@@ -1987,9 +1910,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
ParseToken(lltok::rbrace, "expected end of struct constant"))
return true;
- // FIXME: Get this type from context instead of reconstructing it!
- ID.ConstantVal = ConstantStruct::getAnon(Context, Elts);
- ID.Kind = ValID::t_Constant;
+ ID.ConstantStructElts = new Constant*[Elts.size()];
+ ID.UIntVal = Elts.size();
+ memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
+ ID.Kind = ValID::t_ConstantStruct;
return false;
}
case lltok::less: {
@@ -2007,9 +1931,10 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (isPackedStruct) {
- // FIXME: Get this type from context instead of reconstructing it!
- ID.ConstantVal = ConstantStruct::getAnon(Context, Elts, true);
- ID.Kind = ValID::t_Constant;
+ ID.ConstantStructElts = new Constant*[Elts.size()];
+ memcpy(ID.ConstantStructElts, Elts.data(), Elts.size()*sizeof(Elts[0]));
+ ID.UIntVal = Elts.size();
+ ID.Kind = ValID::t_PackedConstantStruct;
return false;
}
@@ -2131,7 +2056,7 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
case lltok::kw_inttoptr:
case lltok::kw_ptrtoint: {
unsigned Opc = Lex.getUIntVal();
- PATypeHolder DestTy(Type::getVoidTy(Context));
+ Type *DestTy = 0;
Constant *SrcVal;
Lex.Lex();
if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
@@ -2161,11 +2086,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
if (!Val->getType()->isAggregateType())
return Error(ID.Loc, "extractvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
- Indices.end()))
+ if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
return Error(ID.Loc, "invalid indices for extractvalue");
- ID.ConstantVal =
- ConstantExpr::getExtractValue(Val, Indices.data(), Indices.size());
+ ID.ConstantVal = ConstantExpr::getExtractValue(Val, Indices);
ID.Kind = ValID::t_Constant;
return false;
}
@@ -2182,11 +2105,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) {
return true;
if (!Val0->getType()->isAggregateType())
return Error(ID.Loc, "insertvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
- Indices.end()))
+ if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
return Error(ID.Loc, "invalid indices for insertvalue");
- ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1,
- Indices.data(), Indices.size());
+ ID.ConstantVal = ConstantExpr::getInsertValue(Val0, Val1, Indices);
ID.Kind = ValID::t_Constant;
return false;
}
@@ -2414,9 +2335,9 @@ bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&C) {
}
bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
- PATypeHolder Type(Type::getVoidTy(Context));
- return ParseType(Type) ||
- ParseGlobalValue(Type, V);
+ Type *Ty = 0;
+ return ParseType(Ty) ||
+ ParseGlobalValue(Ty, V);
}
/// ParseGlobalValueVector
@@ -2562,8 +2483,7 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
return false;
case ValID::t_Undef:
// FIXME: LabelTy should not be a first-class type.
- if ((!Ty->isFirstClassType() || Ty->isLabelTy()) &&
- !Ty->isOpaqueTy())
+ if (!Ty->isFirstClassType() || Ty->isLabelTy())
return Error(ID.Loc, "invalid type for undef constant");
V = UndefValue::get(Ty);
return false;
@@ -2584,20 +2504,40 @@ bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
V = ID.ConstantVal;
return false;
+ case ValID::t_ConstantStruct:
+ case ValID::t_PackedConstantStruct:
+ if (const StructType *ST = dyn_cast<StructType>(Ty)) {
+ if (ST->getNumElements() != ID.UIntVal)
+ return Error(ID.Loc,
+ "initializer with struct type has wrong # elements");
+ if (ST->isPacked() != (ID.Kind == ValID::t_PackedConstantStruct))
+ return Error(ID.Loc, "packed'ness of initializer and type don't match");
+
+ // Verify that the elements are compatible with the structtype.
+ for (unsigned i = 0, e = ID.UIntVal; i != e; ++i)
+ if (ID.ConstantStructElts[i]->getType() != ST->getElementType(i))
+ return Error(ID.Loc, "element " + Twine(i) +
+ " of struct initializer doesn't match struct element type");
+
+ V = ConstantStruct::get(ST, ArrayRef<Constant*>(ID.ConstantStructElts,
+ ID.UIntVal));
+ } else
+ return Error(ID.Loc, "constant expression type mismatch");
+ return false;
}
}
-bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
+bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState *PFS) {
V = 0;
ValID ID;
- return ParseValID(ID, &PFS) ||
- ConvertValIDToValue(Ty, ID, V, &PFS);
+ return ParseValID(ID, PFS) ||
+ ConvertValIDToValue(Ty, ID, V, PFS);
}
-bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
- PATypeHolder T(Type::getVoidTy(Context));
- return ParseType(T) ||
- ParseValue(T, V, PFS);
+bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) {
+ Type *Ty = 0;
+ return ParseType(Ty) ||
+ ParseValue(Ty, V, PFS);
}
bool LLParser::ParseTypeAndBasicBlock(BasicBlock *&BB, LocTy &Loc,
@@ -2623,7 +2563,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
unsigned Visibility, RetAttrs;
CallingConv::ID CC;
- PATypeHolder RetType(Type::getVoidTy(Context));
+ Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
@@ -2660,8 +2600,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
return Error(LinkageLoc, "invalid function linkage type");
}
- if (!FunctionType::isValidReturnType(RetType) ||
- RetType->isOpaqueTy())
+ if (!FunctionType::isValidReturnType(RetType))
return Error(RetTypeLoc, "invalid function return type");
LocTy NameLoc = Lex.getLoc();
@@ -2684,7 +2623,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
if (Lex.getKind() != lltok::lparen)
return TokError("expected '(' in function argument list");
- std::vector<ArgInfo> ArgList;
+ SmallVector<ArgInfo, 8> ArgList;
bool isVarArg;
unsigned FuncAttrs;
std::string Section;
@@ -2693,7 +2632,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
bool UnnamedAddr;
LocTy UnnamedAddrLoc;
- if (ParseArgumentList(ArgList, isVarArg, false) ||
+ if (ParseArgumentList(ArgList, isVarArg) ||
ParseOptionalToken(lltok::kw_unnamed_addr, UnnamedAddr,
&UnnamedAddrLoc) ||
ParseOptionalAttrs(FuncAttrs, 2) ||
@@ -2712,14 +2651,14 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
// Okay, if we got here, the function is syntactically valid. Convert types
// and do semantic checks.
- std::vector<const Type*> ParamTypeList;
+ std::vector<Type*> ParamTypeList;
SmallVector<AttributeWithIndex, 8> Attrs;
if (RetAttrs != Attribute::None)
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
- ParamTypeList.push_back(ArgList[i].Type);
+ ParamTypeList.push_back(ArgList[i].Ty);
if (ArgList[i].Attrs != Attribute::None)
Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
}
@@ -3052,11 +2991,18 @@ bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
/// ::= 'ret' void (',' !dbg, !1)*
/// ::= 'ret' TypeAndValue (',' !dbg, !1)*
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
- PerFunctionState &PFS) {
- PATypeHolder Ty(Type::getVoidTy(Context));
+ PerFunctionState &PFS) {
+ SMLoc TypeLoc = Lex.getLoc();
+ Type *Ty = 0;
if (ParseType(Ty, true /*void allowed*/)) return true;
+ Type *ResType = PFS.getFunction().getReturnType();
+
if (Ty->isVoidTy()) {
+ if (!ResType->isVoidTy())
+ return Error(TypeLoc, "value doesn't match function result type '" +
+ getTypeString(ResType) + "'");
+
Inst = ReturnInst::Create(Context);
return false;
}
@@ -3064,6 +3010,10 @@ bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
Value *RV;
if (ParseValue(Ty, RV, PFS)) return true;
+ if (ResType != RV->getType())
+ return Error(TypeLoc, "value doesn't match function result type '" +
+ getTypeString(ResType) + "'");
+
Inst = ReturnInst::Create(Context, RV);
return false;
}
@@ -3191,7 +3141,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
LocTy CallLoc = Lex.getLoc();
unsigned RetAttrs, FnAttrs;
CallingConv::ID CC;
- PATypeHolder RetType(Type::getVoidTy(Context));
+ Type *RetType = 0;
LocTy RetTypeLoc;
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
@@ -3217,7 +3167,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
if (!(PFTy = dyn_cast<PointerType>(RetType)) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
- std::vector<const Type*> ParamTypes;
+ std::vector<Type*> ParamTypes;
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
ParamTypes.push_back(ArgList[i].V->getType());
@@ -3268,8 +3218,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
- InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB,
- Args.begin(), Args.end());
+ InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args);
II->setCallingConv(CC);
II->setAttributes(PAL);
Inst = II;
@@ -3369,8 +3318,9 @@ bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS,
/// ::= CastOpc TypeAndValue 'to' Type
bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS,
unsigned Opc) {
- LocTy Loc; Value *Op;
- PATypeHolder DestTy(Type::getVoidTy(Context));
+ LocTy Loc;
+ Value *Op;
+ Type *DestTy = 0;
if (ParseTypeAndValue(Op, Loc, PFS) ||
ParseToken(lltok::kw_to, "expected 'to' after cast value") ||
ParseType(DestTy))
@@ -3409,7 +3359,7 @@ bool LLParser::ParseSelect(Instruction *&Inst, PerFunctionState &PFS) {
/// ::= 'va_arg' TypeAndValue ',' Type
bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) {
Value *Op;
- PATypeHolder EltTy(Type::getVoidTy(Context));
+ Type *EltTy = 0;
LocTy TypeLoc;
if (ParseTypeAndValue(Op, PFS) ||
ParseToken(lltok::comma, "expected ',' after vaarg operand") ||
@@ -3481,11 +3431,10 @@ bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
/// ParsePHI
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Value ']')*
int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
- PATypeHolder Ty(Type::getVoidTy(Context));
+ Type *Ty = 0; LocTy TypeLoc;
Value *Op0, *Op1;
- LocTy TypeLoc = Lex.getLoc();
- if (ParseType(Ty) ||
+ if (ParseType(Ty, TypeLoc) ||
ParseToken(lltok::lsquare, "expected '[' in phi value list") ||
ParseValue(Ty, Op0, PFS) ||
ParseToken(lltok::comma, "expected ',' after insertelement value") ||
@@ -3531,7 +3480,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
bool isTail) {
unsigned RetAttrs, FnAttrs;
CallingConv::ID CC;
- PATypeHolder RetType(Type::getVoidTy(Context));
+ Type *RetType = 0;
LocTy RetTypeLoc;
ValID CalleeID;
SmallVector<ParamInfo, 16> ArgList;
@@ -3554,7 +3503,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
if (!(PFTy = dyn_cast<PointerType>(RetType)) ||
!(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
// Pull out the types of all of the arguments...
- std::vector<const Type*> ParamTypes;
+ std::vector<Type*> ParamTypes;
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
ParamTypes.push_back(ArgList[i].V->getType());
@@ -3605,7 +3554,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
// Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
- CallInst *CI = CallInst::Create(Callee, Args.begin(), Args.end());
+ CallInst *CI = CallInst::Create(Callee, Args);
CI->setTailCall(isTail);
CI->setCallingConv(CC);
CI->setAttributes(PAL);
@@ -3620,10 +3569,10 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
/// ParseAlloc
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalInfo)?
int LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS) {
- PATypeHolder Ty(Type::getVoidTy(Context));
Value *Size = 0;
LocTy SizeLoc;
unsigned Alignment = 0;
+ Type *Ty = 0;
if (ParseType(Ty)) return true;
bool AteExtraComma = false;
@@ -3736,10 +3685,9 @@ int LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
if (!Val->getType()->isAggregateType())
return Error(Loc, "extractvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
- Indices.end()))
+ if (!ExtractValueInst::getIndexedType(Val->getType(), Indices))
return Error(Loc, "invalid indices for extractvalue");
- Inst = ExtractValueInst::Create(Val, Indices.begin(), Indices.end());
+ Inst = ExtractValueInst::Create(Val, Indices);
return AteExtraComma ? InstExtraComma : InstNormal;
}
@@ -3758,10 +3706,9 @@ int LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
if (!Val0->getType()->isAggregateType())
return Error(Loc0, "insertvalue operand must be aggregate type");
- if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
- Indices.end()))
+ if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices))
return Error(Loc0, "invalid indices for insertvalue");
- Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
+ Inst = InsertValueInst::Create(Val0, Val1, Indices);
return AteExtraComma ? InstExtraComma : InstNormal;
}
@@ -3787,12 +3734,7 @@ bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts,
}
Value *V = 0;
- PATypeHolder Ty(Type::getVoidTy(Context));
- ValID ID;
- if (ParseType(Ty) || ParseValID(ID, PFS) ||
- ConvertValIDToValue(Ty, ID, V, PFS))
- return true;
-
+ if (ParseTypeAndValue(V, PFS)) return true;
Elts.push_back(V);
} while (EatIfPresent(lltok::comma));
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index c486799..9630657 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -18,6 +18,7 @@
#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/ValueHandle.h"
#include <map>
@@ -32,6 +33,7 @@ namespace llvm {
class GlobalValue;
class MDString;
class MDNode;
+ class StructType;
/// ValID - Represents a reference of a definition of some sort with no type.
/// There are several cases where we have to parse the value but where the
@@ -47,7 +49,9 @@ namespace llvm {
t_Constant, // Value in ConstantVal.
t_InlineAsm, // Value in StrVal/StrVal2/UIntVal.
t_MDNode, // Value in MDNodeVal.
- t_MDString // Value in MDStringVal.
+ t_MDString, // Value in MDStringVal.
+ t_ConstantStruct, // Value in ConstantStructElts.
+ t_PackedConstantStruct // Value in ConstantStructElts.
} Kind;
LLLexer::LocTy Loc;
@@ -58,12 +62,19 @@ namespace llvm {
Constant *ConstantVal;
MDNode *MDNodeVal;
MDString *MDStringVal;
- ValID() : APFloatVal(0.0) {}
+ Constant **ConstantStructElts;
+
+ ValID() : Kind(t_LocalID), APFloatVal(0.0) {}
+ ~ValID() {
+ if (Kind == t_ConstantStruct || Kind == t_PackedConstantStruct)
+ delete [] ConstantStructElts;
+ }
bool operator<(const ValID &RHS) const {
if (Kind == t_LocalID || Kind == t_GlobalID)
return UIntVal < RHS.UIntVal;
- assert((Kind == t_LocalName || Kind == t_GlobalName) &&
+ assert((Kind == t_LocalName || Kind == t_GlobalName ||
+ Kind == t_ConstantStruct || Kind == t_PackedConstantStruct) &&
"Ordering not defined for this ValID kind yet");
return StrVal < RHS.StrVal;
}
@@ -93,33 +104,13 @@ namespace llvm {
};
DenseMap<Instruction*, std::vector<MDRef> > ForwardRefInstMetadata;
- // Type resolution handling data structures.
- std::map<std::string, std::pair<PATypeHolder, LocTy> > ForwardRefTypes;
- std::map<unsigned, std::pair<PATypeHolder, LocTy> > ForwardRefTypeIDs;
- std::vector<PATypeHolder> NumberedTypes;
+ // Type resolution handling data structures. The location is set when we
+ // have processed a use of the type but not a definition yet.
+ StringMap<std::pair<Type*, LocTy> > NamedTypes;
+ std::vector<std::pair<Type*, LocTy> > NumberedTypes;
+
std::vector<TrackingVH<MDNode> > NumberedMetadata;
std::map<unsigned, std::pair<TrackingVH<MDNode>, LocTy> > ForwardRefMDNodes;
- struct UpRefRecord {
- /// Loc - This is the location of the upref.
- LocTy Loc;
-
- /// NestingLevel - The number of nesting levels that need to be popped
- /// before this type is resolved.
- unsigned NestingLevel;
-
- /// LastContainedTy - This is the type at the current binding level for
- /// the type. Every time we reduce the nesting level, this gets updated.
- const Type *LastContainedTy;
-
- /// UpRefTy - This is the actual opaque type that the upreference is
- /// represented with.
- OpaqueType *UpRefTy;
-
- UpRefRecord(LocTy L, unsigned NL, OpaqueType *URTy)
- : Loc(L), NestingLevel(NL), LastContainedTy((Type*)URTy),
- UpRefTy(URTy) {}
- };
- std::vector<UpRefRecord> UpRefs;
// Global Value reference information.
std::map<std::string, std::pair<GlobalValue*, LocTy> > ForwardRefVals;
@@ -137,7 +128,7 @@ namespace llvm {
M(m) {}
bool Run();
- LLVMContext& getContext() { return Context; }
+ LLVMContext &getContext() { return Context; }
private:
@@ -222,16 +213,19 @@ namespace llvm {
bool ParseMDNodeID(MDNode *&Result, unsigned &SlotNo);
// Type Parsing.
- bool ParseType(PATypeHolder &Result, bool AllowVoid = false);
- bool ParseType(PATypeHolder &Result, LocTy &Loc, bool AllowVoid = false) {
+ bool ParseType(Type *&Result, bool AllowVoid = false);
+ bool ParseType(Type *&Result, LocTy &Loc, bool AllowVoid = false) {
Loc = Lex.getLoc();
return ParseType(Result, AllowVoid);
}
- bool ParseTypeRec(PATypeHolder &H);
- bool ParseStructType(PATypeHolder &H, bool Packed);
- bool ParseArrayVectorType(PATypeHolder &H, bool isVector);
- bool ParseFunctionType(PATypeHolder &Result);
- PATypeHolder HandleUpRefs(const Type *Ty);
+ bool ParseAnonStructType(Type *&Result, bool Packed);
+ bool ParseStructBody(SmallVectorImpl<Type*> &Body);
+ bool ParseStructDefinition(SMLoc TypeLoc, StringRef Name,
+ std::pair<Type*, LocTy> &Entry,
+ Type *&ResultTy);
+
+ bool ParseArrayVectorType(Type *&Result, bool isVector);
+ bool ParseFunctionType(Type *&Result);
// Function Semantic Analysis.
class PerFunctionState {
@@ -278,14 +272,20 @@ namespace llvm {
bool ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
PerFunctionState *PFS);
- bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS);
+ bool ParseValue(const Type *Ty, Value *&V, PerFunctionState *PFS);
+ bool ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
+ return ParseValue(Ty, V, &PFS);
+ }
bool ParseValue(const Type *Ty, Value *&V, LocTy &Loc,
PerFunctionState &PFS) {
Loc = Lex.getLoc();
- return ParseValue(Ty, V, PFS);
+ return ParseValue(Ty, V, &PFS);
}
- bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS);
+ bool ParseTypeAndValue(Value *&V, PerFunctionState *PFS);
+ bool ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
+ return ParseTypeAndValue(V, &PFS);
+ }
bool ParseTypeAndValue(Value *&V, LocTy &Loc, PerFunctionState &PFS) {
Loc = Lex.getLoc();
return ParseTypeAndValue(V, PFS);
@@ -321,14 +321,13 @@ namespace llvm {
// Function Parsing.
struct ArgInfo {
LocTy Loc;
- PATypeHolder Type;
+ Type *Ty;
unsigned Attrs;
std::string Name;
- ArgInfo(LocTy L, PATypeHolder Ty, unsigned Attr, const std::string &N)
- : Loc(L), Type(Ty), Attrs(Attr), Name(N) {}
+ ArgInfo(LocTy L, Type *ty, unsigned Attr, const std::string &N)
+ : Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
};
- bool ParseArgumentList(std::vector<ArgInfo> &ArgList,
- bool &isVarArg, bool inType);
+ bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg);
bool ParseFunctionHeader(Function *&Fn, bool isDefine);
bool ParseFunctionBody(Function &Fn);
bool ParseBasicBlock(PerFunctionState &PFS);