2009-01-02 07:01:27 +00:00
|
|
|
//===-- LLParser.cpp - Parser Class ---------------------------------------===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file defines the parser class for .ll files.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "LLParser.h"
|
|
|
|
#include "llvm/AutoUpgrade.h"
|
|
|
|
#include "llvm/CallingConv.h"
|
|
|
|
#include "llvm/Constants.h"
|
|
|
|
#include "llvm/DerivedTypes.h"
|
|
|
|
#include "llvm/InlineAsm.h"
|
|
|
|
#include "llvm/Instructions.h"
|
2009-07-01 23:57:11 +00:00
|
|
|
#include "llvm/LLVMContext.h"
|
2009-05-10 20:57:05 +00:00
|
|
|
#include "llvm/MDNode.h"
|
2009-01-02 07:01:27 +00:00
|
|
|
#include "llvm/Module.h"
|
|
|
|
#include "llvm/ValueSymbolTable.h"
|
|
|
|
#include "llvm/ADT/SmallPtrSet.h"
|
|
|
|
#include "llvm/ADT/StringExtras.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
namespace llvm {
|
2009-01-02 08:05:26 +00:00
|
|
|
/// 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
|
|
|
|
/// type can depend on later context. This may either be a numeric reference
|
|
|
|
/// or a symbolic (%var) reference. This is just a discriminated union.
|
2009-01-02 07:01:27 +00:00
|
|
|
struct ValID {
|
|
|
|
enum {
|
|
|
|
t_LocalID, t_GlobalID, // ID in UIntVal.
|
|
|
|
t_LocalName, t_GlobalName, // Name in StrVal.
|
|
|
|
t_APSInt, t_APFloat, // Value in APSIntVal/APFloatVal.
|
|
|
|
t_Null, t_Undef, t_Zero, // No value.
|
2009-01-05 07:52:51 +00:00
|
|
|
t_EmptyArray, // No value: []
|
2009-01-02 07:01:27 +00:00
|
|
|
t_Constant, // Value in ConstantVal.
|
|
|
|
t_InlineAsm // Value in StrVal/StrVal2/UIntVal.
|
|
|
|
} Kind;
|
|
|
|
|
|
|
|
LLParser::LocTy Loc;
|
|
|
|
unsigned UIntVal;
|
|
|
|
std::string StrVal, StrVal2;
|
|
|
|
APSInt APSIntVal;
|
|
|
|
APFloat APFloatVal;
|
|
|
|
Constant *ConstantVal;
|
|
|
|
ValID() : APFloatVal(0.0) {}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
/// Run: module ::= toplevelentity*
|
2009-01-04 20:44:11 +00:00
|
|
|
bool LLParser::Run() {
|
2009-01-02 08:05:26 +00:00
|
|
|
// Prime the lexer.
|
|
|
|
Lex.Lex();
|
|
|
|
|
2009-01-04 20:44:11 +00:00
|
|
|
return ParseTopLevelEntities() ||
|
|
|
|
ValidateEndOfModule();
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// ValidateEndOfModule - Do final validity and sanity checks at the end of the
|
|
|
|
/// module.
|
|
|
|
bool LLParser::ValidateEndOfModule() {
|
|
|
|
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 '%" +
|
|
|
|
utostr(ForwardRefTypeIDs.begin()->first) + "'");
|
|
|
|
|
|
|
|
if (!ForwardRefVals.empty())
|
|
|
|
return Error(ForwardRefVals.begin()->second.second,
|
|
|
|
"use of undefined value '@" + ForwardRefVals.begin()->first +
|
|
|
|
"'");
|
|
|
|
|
|
|
|
if (!ForwardRefValIDs.empty())
|
|
|
|
return Error(ForwardRefValIDs.begin()->second.second,
|
|
|
|
"use of undefined value '@" +
|
|
|
|
utostr(ForwardRefValIDs.begin()->first) + "'");
|
|
|
|
|
|
|
|
// Look for intrinsic functions and CallInst that need to be upgraded
|
|
|
|
for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )
|
|
|
|
UpgradeCallsToIntrinsic(FI++); // must be post-increment, as we remove
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Top-Level Entities
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
bool LLParser::ParseTopLevelEntities() {
|
|
|
|
while (1) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default: return TokError("expected top-level entity");
|
|
|
|
case lltok::Eof: return false;
|
|
|
|
//case lltok::kw_define:
|
|
|
|
case lltok::kw_declare: if (ParseDeclare()) return true; break;
|
|
|
|
case lltok::kw_define: if (ParseDefine()) return true; break;
|
|
|
|
case lltok::kw_module: if (ParseModuleAsm()) return true; break;
|
|
|
|
case lltok::kw_target: if (ParseTargetDefinition()) return true; break;
|
|
|
|
case lltok::kw_deplibs: if (ParseDepLibs()) return true; break;
|
|
|
|
case lltok::kw_type: if (ParseUnnamedType()) return true; break;
|
|
|
|
case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0
|
|
|
|
case lltok::LocalVar: if (ParseNamedType()) return true; break;
|
|
|
|
case lltok::GlobalVar: if (ParseNamedGlobal()) return true; break;
|
2009-07-01 19:21:12 +00:00
|
|
|
case lltok::Metadata: if (ParseStandaloneMetadata()) return true; break;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
// The Global variable production with no name can have many different
|
|
|
|
// optional leading prefixes, the production is:
|
|
|
|
// GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
|
|
|
|
// OptionalAddrSpace ('constant'|'global') ...
|
2009-01-15 20:18:42 +00:00
|
|
|
case lltok::kw_private: // OptionalLinkage
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_internal: // OptionalLinkage
|
|
|
|
case lltok::kw_weak: // OptionalLinkage
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
case lltok::kw_weak_odr: // OptionalLinkage
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_linkonce: // OptionalLinkage
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
case lltok::kw_linkonce_odr: // OptionalLinkage
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_appending: // OptionalLinkage
|
|
|
|
case lltok::kw_dllexport: // OptionalLinkage
|
|
|
|
case lltok::kw_common: // OptionalLinkage
|
|
|
|
case lltok::kw_dllimport: // OptionalLinkage
|
|
|
|
case lltok::kw_extern_weak: // OptionalLinkage
|
|
|
|
case lltok::kw_external: { // OptionalLinkage
|
|
|
|
unsigned Linkage, Visibility;
|
|
|
|
if (ParseOptionalLinkage(Linkage) ||
|
|
|
|
ParseOptionalVisibility(Visibility) ||
|
2009-07-02 23:08:13 +00:00
|
|
|
ParseGlobal("", SMLoc(), Linkage, true, Visibility))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case lltok::kw_default: // OptionalVisibility
|
|
|
|
case lltok::kw_hidden: // OptionalVisibility
|
|
|
|
case lltok::kw_protected: { // OptionalVisibility
|
|
|
|
unsigned Visibility;
|
|
|
|
if (ParseOptionalVisibility(Visibility) ||
|
2009-07-02 23:08:13 +00:00
|
|
|
ParseGlobal("", SMLoc(), 0, false, Visibility))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case lltok::kw_thread_local: // OptionalThreadLocal
|
|
|
|
case lltok::kw_addrspace: // OptionalAddrSpace
|
|
|
|
case lltok::kw_constant: // GlobalType
|
|
|
|
case lltok::kw_global: // GlobalType
|
2009-07-02 23:08:13 +00:00
|
|
|
if (ParseGlobal("", SMLoc(), 0, false, 0)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= 'module' 'asm' STRINGCONSTANT
|
|
|
|
bool LLParser::ParseModuleAsm() {
|
|
|
|
assert(Lex.getKind() == lltok::kw_module);
|
|
|
|
Lex.Lex();
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
std::string AsmStr;
|
|
|
|
if (ParseToken(lltok::kw_asm, "expected 'module asm'") ||
|
|
|
|
ParseStringConstant(AsmStr)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
const std::string &AsmSoFar = M->getModuleInlineAsm();
|
|
|
|
if (AsmSoFar.empty())
|
2009-01-02 08:05:26 +00:00
|
|
|
M->setModuleInlineAsm(AsmStr);
|
2009-01-02 07:01:27 +00:00
|
|
|
else
|
2009-01-02 08:05:26 +00:00
|
|
|
M->setModuleInlineAsm(AsmSoFar+"\n"+AsmStr);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= 'target' 'triple' '=' STRINGCONSTANT
|
|
|
|
/// ::= 'target' 'datalayout' '=' STRINGCONSTANT
|
|
|
|
bool LLParser::ParseTargetDefinition() {
|
|
|
|
assert(Lex.getKind() == lltok::kw_target);
|
2009-01-02 08:05:26 +00:00
|
|
|
std::string Str;
|
2009-01-02 07:01:27 +00:00
|
|
|
switch (Lex.Lex()) {
|
|
|
|
default: return TokError("unknown target property");
|
|
|
|
case lltok::kw_triple:
|
|
|
|
Lex.Lex();
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseToken(lltok::equal, "expected '=' after target triple") ||
|
|
|
|
ParseStringConstant(Str))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
2009-01-02 08:05:26 +00:00
|
|
|
M->setTargetTriple(Str);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
case lltok::kw_datalayout:
|
|
|
|
Lex.Lex();
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseToken(lltok::equal, "expected '=' after target datalayout") ||
|
|
|
|
ParseStringConstant(Str))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
2009-01-02 08:05:26 +00:00
|
|
|
M->setDataLayout(Str);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= 'deplibs' '=' '[' ']'
|
|
|
|
/// ::= 'deplibs' '=' '[' STRINGCONSTANT (',' STRINGCONSTANT)* ']'
|
|
|
|
bool LLParser::ParseDepLibs() {
|
|
|
|
assert(Lex.getKind() == lltok::kw_deplibs);
|
2009-01-02 08:05:26 +00:00
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::equal, "expected '=' after deplibs") ||
|
|
|
|
ParseToken(lltok::lsquare, "expected '=' after deplibs"))
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (EatIfPresent(lltok::rsquare))
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
std::string Str;
|
|
|
|
if (ParseStringConstant(Str)) return true;
|
|
|
|
M->addLibrary(Str);
|
2009-01-02 07:01:27 +00:00
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
|
|
|
if (ParseStringConstant(Str)) return true;
|
|
|
|
M->addLibrary(Str);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
return ParseToken(lltok::rsquare, "expected ']' at end of list");
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= 'type' type
|
|
|
|
bool LLParser::ParseUnnamedType() {
|
|
|
|
assert(Lex.getKind() == lltok::kw_type);
|
|
|
|
LocTy TypeLoc = Lex.getLoc();
|
|
|
|
Lex.Lex(); // eat kw_type
|
|
|
|
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
|
|
|
if (ParseType(Ty)) return true;
|
|
|
|
|
|
|
|
unsigned TypeID = NumberedTypes.size();
|
|
|
|
|
|
|
|
// See if this type was previously referenced.
|
|
|
|
std::map<unsigned, std::pair<PATypeHolder, LocTy> >::iterator
|
|
|
|
FI = ForwardRefTypeIDs.find(TypeID);
|
|
|
|
if (FI != ForwardRefTypeIDs.end()) {
|
2009-01-05 18:19:46 +00:00
|
|
|
if (FI->second.first.get() == Ty)
|
|
|
|
return Error(TypeLoc, "self referential type is invalid");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
|
|
|
|
Ty = FI->second.first.get();
|
|
|
|
ForwardRefTypeIDs.erase(FI);
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberedTypes.push_back(Ty);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= LocalVar '=' 'type' type
|
|
|
|
bool LLParser::ParseNamedType() {
|
|
|
|
std::string Name = Lex.getStrVal();
|
|
|
|
LocTy NameLoc = Lex.getLoc();
|
2009-01-02 08:05:26 +00:00
|
|
|
Lex.Lex(); // eat LocalVar.
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
2009-01-02 08:05:26 +00:00
|
|
|
|
|
|
|
if (ParseToken(lltok::equal, "expected '=' after name") ||
|
|
|
|
ParseToken(lltok::kw_type, "expected 'type' after name") ||
|
|
|
|
ParseType(Ty))
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
// 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()) {
|
2009-01-05 18:19:46 +00:00
|
|
|
if (FI->second.first.get() == Ty)
|
|
|
|
return Error(NameLoc, "self referential type is invalid");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
cast<DerivedType>(FI->second.first.get())->refineAbstractTypeTo(Ty);
|
|
|
|
Ty = FI->second.first.get();
|
|
|
|
ForwardRefTypes.erase(FI);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Inserting a name that is already defined, get the existing name.
|
|
|
|
const Type *Existing = M->getTypeByName(Name);
|
|
|
|
assert(Existing && "Conflict but no matching type?!");
|
|
|
|
|
|
|
|
// Otherwise, this is an attempt to redefine a type. That's okay if
|
|
|
|
// the redefinition is identical to the original.
|
|
|
|
// FIXME: REMOVE REDEFINITIONS IN LLVM 3.0
|
|
|
|
if (Existing == Ty) return false;
|
|
|
|
|
|
|
|
// Any other kind of (non-equivalent) redefinition is an error.
|
|
|
|
return Error(NameLoc, "redefinition of type named '" + Name + "' of type '" +
|
|
|
|
Ty->getDescription() + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= 'declare' FunctionHeader
|
|
|
|
bool LLParser::ParseDeclare() {
|
|
|
|
assert(Lex.getKind() == lltok::kw_declare);
|
|
|
|
Lex.Lex();
|
|
|
|
|
|
|
|
Function *F;
|
|
|
|
return ParseFunctionHeader(F, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// toplevelentity
|
|
|
|
/// ::= 'define' FunctionHeader '{' ...
|
|
|
|
bool LLParser::ParseDefine() {
|
|
|
|
assert(Lex.getKind() == lltok::kw_define);
|
|
|
|
Lex.Lex();
|
|
|
|
|
|
|
|
Function *F;
|
2009-01-02 08:05:26 +00:00
|
|
|
return ParseFunctionHeader(F, true) ||
|
|
|
|
ParseFunctionBody(*F);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
/// ParseGlobalType
|
|
|
|
/// ::= 'constant'
|
|
|
|
/// ::= 'global'
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseGlobalType(bool &IsConstant) {
|
|
|
|
if (Lex.getKind() == lltok::kw_constant)
|
|
|
|
IsConstant = true;
|
|
|
|
else if (Lex.getKind() == lltok::kw_global)
|
|
|
|
IsConstant = false;
|
2009-02-10 16:24:55 +00:00
|
|
|
else {
|
|
|
|
IsConstant = false;
|
2009-01-02 07:01:27 +00:00
|
|
|
return TokError("expected 'global' or 'constant'");
|
2009-02-10 16:24:55 +00:00
|
|
|
}
|
2009-01-02 07:01:27 +00:00
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseNamedGlobal:
|
|
|
|
/// GlobalVar '=' OptionalVisibility ALIAS ...
|
|
|
|
/// GlobalVar '=' OptionalLinkage OptionalVisibility ... -> global variable
|
|
|
|
bool LLParser::ParseNamedGlobal() {
|
|
|
|
assert(Lex.getKind() == lltok::GlobalVar);
|
|
|
|
LocTy NameLoc = Lex.getLoc();
|
|
|
|
std::string Name = Lex.getStrVal();
|
|
|
|
Lex.Lex();
|
|
|
|
|
|
|
|
bool HasLinkage;
|
|
|
|
unsigned Linkage, Visibility;
|
|
|
|
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
|
|
|
|
ParseOptionalLinkage(Linkage, HasLinkage) ||
|
|
|
|
ParseOptionalVisibility(Visibility))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
|
|
|
|
return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
|
|
|
|
return ParseAlias(Name, NameLoc, Visibility);
|
|
|
|
}
|
|
|
|
|
2009-07-01 19:21:12 +00:00
|
|
|
/// ParseStandaloneMetadata:
|
|
|
|
/// !42 = !{...}
|
|
|
|
bool LLParser::ParseStandaloneMetadata() {
|
|
|
|
assert(Lex.getKind() == lltok::Metadata);
|
|
|
|
Lex.Lex();
|
|
|
|
unsigned MetadataID = 0;
|
|
|
|
if (ParseUInt32(MetadataID))
|
|
|
|
return true;
|
|
|
|
if (MetadataCache.find(MetadataID) != MetadataCache.end())
|
|
|
|
return TokError("Metadata id is already used");
|
|
|
|
if (ParseToken(lltok::equal, "expected '=' here"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
LocTy TyLoc;
|
|
|
|
bool IsConstant;
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
|
|
|
if (ParseGlobalType(IsConstant) ||
|
|
|
|
ParseType(Ty, TyLoc))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
Constant *Init = 0;
|
|
|
|
if (ParseGlobalValue(Ty, Init))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
MetadataCache[MetadataID] = Init;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
/// ParseAlias:
|
|
|
|
/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
|
|
|
|
/// Aliasee
|
2009-04-25 21:26:00 +00:00
|
|
|
/// ::= TypeAndValue
|
|
|
|
/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
|
|
|
|
/// ::= 'getelementptr' '(' ... ')'
|
2009-01-02 07:01:27 +00:00
|
|
|
///
|
|
|
|
/// Everything through visibility has already been parsed.
|
|
|
|
///
|
|
|
|
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
|
|
|
|
unsigned Visibility) {
|
|
|
|
assert(Lex.getKind() == lltok::kw_alias);
|
|
|
|
Lex.Lex();
|
|
|
|
unsigned Linkage;
|
|
|
|
LocTy LinkageLoc = Lex.getLoc();
|
|
|
|
if (ParseOptionalLinkage(Linkage))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (Linkage != GlobalValue::ExternalLinkage &&
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
Linkage != GlobalValue::WeakAnyLinkage &&
|
|
|
|
Linkage != GlobalValue::WeakODRLinkage &&
|
2009-01-15 20:18:42 +00:00
|
|
|
Linkage != GlobalValue::InternalLinkage &&
|
|
|
|
Linkage != GlobalValue::PrivateLinkage)
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(LinkageLoc, "invalid linkage type for alias");
|
|
|
|
|
|
|
|
Constant *Aliasee;
|
|
|
|
LocTy AliaseeLoc = Lex.getLoc();
|
2009-04-25 21:26:00 +00:00
|
|
|
if (Lex.getKind() != lltok::kw_bitcast &&
|
|
|
|
Lex.getKind() != lltok::kw_getelementptr) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseGlobalTypeAndValue(Aliasee)) return true;
|
|
|
|
} else {
|
|
|
|
// The bitcast dest type is not present, it is implied by the dest type.
|
|
|
|
ValID ID;
|
|
|
|
if (ParseValID(ID)) return true;
|
|
|
|
if (ID.Kind != ValID::t_Constant)
|
|
|
|
return Error(AliaseeLoc, "invalid aliasee");
|
|
|
|
Aliasee = ID.ConstantVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!isa<PointerType>(Aliasee->getType()))
|
|
|
|
return Error(AliaseeLoc, "alias must have pointer type");
|
|
|
|
|
|
|
|
// Okay, create the alias but do not insert it into the module yet.
|
|
|
|
GlobalAlias* GA = new GlobalAlias(Aliasee->getType(),
|
|
|
|
(GlobalValue::LinkageTypes)Linkage, Name,
|
|
|
|
Aliasee);
|
|
|
|
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
|
|
|
|
|
|
|
// See if this value already exists in the symbol table. If so, it is either
|
|
|
|
// a redefinition or a definition of a forward reference.
|
|
|
|
if (GlobalValue *Val =
|
|
|
|
cast_or_null<GlobalValue>(M->getValueSymbolTable().lookup(Name))) {
|
|
|
|
// See if this was a redefinition. If so, there is no entry in
|
|
|
|
// ForwardRefVals.
|
|
|
|
std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator
|
|
|
|
I = ForwardRefVals.find(Name);
|
|
|
|
if (I == ForwardRefVals.end())
|
|
|
|
return Error(NameLoc, "redefinition of global named '@" + Name + "'");
|
|
|
|
|
|
|
|
// Otherwise, this was a definition of forward ref. Verify that types
|
|
|
|
// agree.
|
|
|
|
if (Val->getType() != GA->getType())
|
|
|
|
return Error(NameLoc,
|
|
|
|
"forward reference and definition of alias have different types");
|
|
|
|
|
|
|
|
// If they agree, just RAUW the old value with the alias and remove the
|
|
|
|
// forward ref info.
|
|
|
|
Val->replaceAllUsesWith(GA);
|
|
|
|
Val->eraseFromParent();
|
|
|
|
ForwardRefVals.erase(I);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert into the module, we know its name won't collide now.
|
|
|
|
M->getAliasList().push_back(GA);
|
|
|
|
assert(GA->getNameStr() == Name && "Should not be a name conflict!");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseGlobal
|
|
|
|
/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal
|
|
|
|
/// OptionalAddrSpace GlobalType Type Const
|
|
|
|
/// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
|
|
|
|
/// OptionalAddrSpace GlobalType Type Const
|
|
|
|
///
|
|
|
|
/// Everything through visibility has been parsed already.
|
|
|
|
///
|
|
|
|
bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
|
|
|
|
unsigned Linkage, bool HasLinkage,
|
|
|
|
unsigned Visibility) {
|
|
|
|
unsigned AddrSpace;
|
|
|
|
bool ThreadLocal, IsConstant;
|
|
|
|
LocTy TyLoc;
|
|
|
|
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
|
|
|
if (ParseOptionalToken(lltok::kw_thread_local, ThreadLocal) ||
|
|
|
|
ParseOptionalAddrSpace(AddrSpace) ||
|
|
|
|
ParseGlobalType(IsConstant) ||
|
|
|
|
ParseType(Ty, TyLoc))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// If the linkage is specified and is external, then no initializer is
|
|
|
|
// present.
|
|
|
|
Constant *Init = 0;
|
|
|
|
if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage &&
|
2009-03-11 08:08:06 +00:00
|
|
|
Linkage != GlobalValue::ExternalWeakLinkage &&
|
2009-01-02 07:01:27 +00:00
|
|
|
Linkage != GlobalValue::ExternalLinkage)) {
|
|
|
|
if (ParseGlobalValue(Ty, Init))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (isa<FunctionType>(Ty) || Ty == Type::LabelTy)
|
2009-02-08 20:00:15 +00:00
|
|
|
return Error(TyLoc, "invalid type for global variable");
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
GlobalVariable *GV = 0;
|
|
|
|
|
|
|
|
// See if the global was forward referenced, if so, use the global.
|
2009-02-02 07:24:28 +00:00
|
|
|
if (!Name.empty()) {
|
|
|
|
if ((GV = M->getGlobalVariable(Name, true)) &&
|
|
|
|
!ForwardRefVals.erase(Name))
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(NameLoc, "redefinition of global '@" + Name + "'");
|
|
|
|
} else {
|
|
|
|
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
|
|
|
|
I = ForwardRefValIDs.find(NumberedVals.size());
|
|
|
|
if (I != ForwardRefValIDs.end()) {
|
|
|
|
GV = cast<GlobalVariable>(I->second.first);
|
|
|
|
ForwardRefValIDs.erase(I);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GV == 0) {
|
2009-07-08 01:26:06 +00:00
|
|
|
GV = new GlobalVariable(Context, Ty, false,
|
|
|
|
GlobalValue::ExternalLinkage, 0, Name,
|
2009-01-02 07:01:27 +00:00
|
|
|
M, false, AddrSpace);
|
|
|
|
} else {
|
|
|
|
if (GV->getType()->getElementType() != Ty)
|
|
|
|
return Error(TyLoc,
|
|
|
|
"forward reference and definition of global have different types");
|
|
|
|
|
|
|
|
// Move the forward-reference to the correct spot in the module.
|
|
|
|
M->getGlobalList().splice(M->global_end(), M->getGlobalList(), GV);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Name.empty())
|
|
|
|
NumberedVals.push_back(GV);
|
|
|
|
|
|
|
|
// Set the parsed properties on the global.
|
|
|
|
if (Init)
|
|
|
|
GV->setInitializer(Init);
|
|
|
|
GV->setConstant(IsConstant);
|
|
|
|
GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
|
|
|
|
GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
|
|
|
GV->setThreadLocal(ThreadLocal);
|
|
|
|
|
|
|
|
// Parse attributes on the global.
|
|
|
|
while (Lex.getKind() == lltok::comma) {
|
|
|
|
Lex.Lex();
|
|
|
|
|
|
|
|
if (Lex.getKind() == lltok::kw_section) {
|
|
|
|
Lex.Lex();
|
|
|
|
GV->setSection(Lex.getStrVal());
|
|
|
|
if (ParseToken(lltok::StringConstant, "expected global section string"))
|
|
|
|
return true;
|
|
|
|
} else if (Lex.getKind() == lltok::kw_align) {
|
|
|
|
unsigned Alignment;
|
|
|
|
if (ParseOptionalAlignment(Alignment)) return true;
|
|
|
|
GV->setAlignment(Alignment);
|
|
|
|
} else {
|
|
|
|
TokError("unknown global variable property!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// GlobalValue Reference/Resolution Routines.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// GetGlobalVal - Get a value with the specified name or ID, creating a
|
|
|
|
/// forward reference record if needed. This can return null if the value
|
|
|
|
/// exists but does not have the right type.
|
|
|
|
GlobalValue *LLParser::GetGlobalVal(const std::string &Name, const Type *Ty,
|
|
|
|
LocTy Loc) {
|
|
|
|
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
|
|
|
if (PTy == 0) {
|
|
|
|
Error(Loc, "global variable reference must have pointer type");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look this name up in the normal function symbol table.
|
|
|
|
GlobalValue *Val =
|
|
|
|
cast_or_null<GlobalValue>(M->getValueSymbolTable().lookup(Name));
|
|
|
|
|
|
|
|
// If this is a forward reference for the value, see if we already created a
|
|
|
|
// forward ref record.
|
|
|
|
if (Val == 0) {
|
|
|
|
std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator
|
|
|
|
I = ForwardRefVals.find(Name);
|
|
|
|
if (I != ForwardRefVals.end())
|
|
|
|
Val = I->second.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have the value in the symbol table or fwd-ref table, return it.
|
|
|
|
if (Val) {
|
|
|
|
if (Val->getType() == Ty) return Val;
|
|
|
|
Error(Loc, "'@" + Name + "' defined with type '" +
|
|
|
|
Val->getType()->getDescription() + "'");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, create a new forward reference for this value and remember it.
|
|
|
|
GlobalValue *FwdVal;
|
2009-01-08 19:05:36 +00:00
|
|
|
if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
|
|
|
|
// Function types can return opaque but functions can't.
|
|
|
|
if (isa<OpaqueType>(FT->getReturnType())) {
|
|
|
|
Error(Loc, "function may not return opaque type");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-11 08:08:06 +00:00
|
|
|
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M);
|
2009-01-08 19:05:36 +00:00
|
|
|
} else {
|
2009-07-08 01:26:06 +00:00
|
|
|
FwdVal = new GlobalVariable(Context, PTy->getElementType(), false,
|
2009-03-11 08:08:06 +00:00
|
|
|
GlobalValue::ExternalWeakLinkage, 0, Name, M);
|
2009-01-08 19:05:36 +00:00
|
|
|
}
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
|
|
|
|
return FwdVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalValue *LLParser::GetGlobalVal(unsigned ID, const Type *Ty, LocTy Loc) {
|
|
|
|
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
|
|
|
if (PTy == 0) {
|
|
|
|
Error(Loc, "global variable reference must have pointer type");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
GlobalValue *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0;
|
|
|
|
|
|
|
|
// If this is a forward reference for the value, see if we already created a
|
|
|
|
// forward ref record.
|
|
|
|
if (Val == 0) {
|
|
|
|
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator
|
|
|
|
I = ForwardRefValIDs.find(ID);
|
|
|
|
if (I != ForwardRefValIDs.end())
|
|
|
|
Val = I->second.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have the value in the symbol table or fwd-ref table, return it.
|
|
|
|
if (Val) {
|
|
|
|
if (Val->getType() == Ty) return Val;
|
|
|
|
Error(Loc, "'@" + utostr(ID) + "' defined with type '" +
|
|
|
|
Val->getType()->getDescription() + "'");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, create a new forward reference for this value and remember it.
|
|
|
|
GlobalValue *FwdVal;
|
2009-01-05 18:27:50 +00:00
|
|
|
if (const FunctionType *FT = dyn_cast<FunctionType>(PTy->getElementType())) {
|
|
|
|
// Function types can return opaque but functions can't.
|
|
|
|
if (isa<OpaqueType>(FT->getReturnType())) {
|
2009-01-05 18:56:52 +00:00
|
|
|
Error(Loc, "function may not return opaque type");
|
2009-01-05 18:27:50 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2009-03-11 08:08:06 +00:00
|
|
|
FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, "", M);
|
2009-01-05 18:27:50 +00:00
|
|
|
} else {
|
2009-07-08 01:26:06 +00:00
|
|
|
FwdVal = new GlobalVariable(Context, PTy->getElementType(), false,
|
2009-03-11 08:08:06 +00:00
|
|
|
GlobalValue::ExternalWeakLinkage, 0, "", M);
|
2009-01-05 18:27:50 +00:00
|
|
|
}
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
|
|
|
|
return FwdVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Helper Routines.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseToken - If the current token has the specified kind, eat it and return
|
|
|
|
/// success. Otherwise, emit the specified error and return failure.
|
|
|
|
bool LLParser::ParseToken(lltok::Kind T, const char *ErrMsg) {
|
|
|
|
if (Lex.getKind() != T)
|
|
|
|
return TokError(ErrMsg);
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
/// ParseStringConstant
|
|
|
|
/// ::= StringConstant
|
|
|
|
bool LLParser::ParseStringConstant(std::string &Result) {
|
|
|
|
if (Lex.getKind() != lltok::StringConstant)
|
|
|
|
return TokError("expected string constant");
|
|
|
|
Result = Lex.getStrVal();
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseUInt32
|
|
|
|
/// ::= uint32
|
|
|
|
bool LLParser::ParseUInt32(unsigned &Val) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
|
|
|
|
return TokError("expected integer");
|
|
|
|
uint64_t Val64 = Lex.getAPSIntVal().getLimitedValue(0xFFFFFFFFULL+1);
|
|
|
|
if (Val64 != unsigned(Val64))
|
|
|
|
return TokError("expected 32-bit integer (too large)");
|
|
|
|
Val = Val64;
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ParseOptionalAddrSpace
|
|
|
|
/// := /*empty*/
|
|
|
|
/// := 'addrspace' '(' uint32 ')'
|
|
|
|
bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
|
|
|
|
AddrSpace = 0;
|
2009-01-02 08:05:26 +00:00
|
|
|
if (!EatIfPresent(lltok::kw_addrspace))
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
return ParseToken(lltok::lparen, "expected '(' in address space") ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseUInt32(AddrSpace) ||
|
2009-01-02 07:01:27 +00:00
|
|
|
ParseToken(lltok::rparen, "expected ')' in address space");
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
|
|
|
|
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
|
|
|
|
/// 2: function attr.
|
2009-03-25 06:36:36 +00:00
|
|
|
/// 3: function arg after value: FIXME: REMOVE IN LLVM 3.0
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
|
|
|
|
Attrs = Attribute::None;
|
|
|
|
LocTy AttrLoc = Lex.getLoc();
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
case lltok::kw_sext:
|
|
|
|
case lltok::kw_zext:
|
2009-03-25 06:36:36 +00:00
|
|
|
// Treat these as signext/zeroext if they occur in the argument list after
|
|
|
|
// the value, as in "call i8 @foo(i8 10 sext)". If they occur before the
|
|
|
|
// value, as in "call i8 @foo(i8 sext (" then it is part of a constant
|
|
|
|
// expr.
|
2009-01-02 07:01:27 +00:00
|
|
|
// FIXME: REMOVE THIS IN LLVM 3.0
|
2009-03-25 06:36:36 +00:00
|
|
|
if (AttrKind == 3) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (Lex.getKind() == lltok::kw_sext)
|
|
|
|
Attrs |= Attribute::SExt;
|
|
|
|
else
|
|
|
|
Attrs |= Attribute::ZExt;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// FALL THROUGH.
|
|
|
|
default: // End of attributes.
|
|
|
|
if (AttrKind != 2 && (Attrs & Attribute::FunctionOnly))
|
|
|
|
return Error(AttrLoc, "invalid use of function-only attribute");
|
|
|
|
|
2009-03-25 06:36:36 +00:00
|
|
|
if (AttrKind != 0 && AttrKind != 3 && (Attrs & Attribute::ParameterOnly))
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(AttrLoc, "invalid use of parameter-only attribute");
|
|
|
|
|
|
|
|
return false;
|
2009-06-05 21:57:13 +00:00
|
|
|
case lltok::kw_zeroext: Attrs |= Attribute::ZExt; break;
|
|
|
|
case lltok::kw_signext: Attrs |= Attribute::SExt; break;
|
|
|
|
case lltok::kw_inreg: Attrs |= Attribute::InReg; break;
|
|
|
|
case lltok::kw_sret: Attrs |= Attribute::StructRet; break;
|
|
|
|
case lltok::kw_noalias: Attrs |= Attribute::NoAlias; break;
|
|
|
|
case lltok::kw_nocapture: Attrs |= Attribute::NoCapture; break;
|
|
|
|
case lltok::kw_byval: Attrs |= Attribute::ByVal; break;
|
|
|
|
case lltok::kw_nest: Attrs |= Attribute::Nest; break;
|
|
|
|
|
|
|
|
case lltok::kw_noreturn: Attrs |= Attribute::NoReturn; break;
|
|
|
|
case lltok::kw_nounwind: Attrs |= Attribute::NoUnwind; break;
|
|
|
|
case lltok::kw_noinline: Attrs |= Attribute::NoInline; break;
|
|
|
|
case lltok::kw_readnone: Attrs |= Attribute::ReadNone; break;
|
|
|
|
case lltok::kw_readonly: Attrs |= Attribute::ReadOnly; break;
|
|
|
|
case lltok::kw_alwaysinline: Attrs |= Attribute::AlwaysInline; break;
|
|
|
|
case lltok::kw_optsize: Attrs |= Attribute::OptimizeForSize; break;
|
|
|
|
case lltok::kw_ssp: Attrs |= Attribute::StackProtect; break;
|
|
|
|
case lltok::kw_sspreq: Attrs |= Attribute::StackProtectReq; break;
|
|
|
|
case lltok::kw_noredzone: Attrs |= Attribute::NoRedZone; break;
|
|
|
|
case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
case lltok::kw_align: {
|
|
|
|
unsigned Alignment;
|
|
|
|
if (ParseOptionalAlignment(Alignment))
|
|
|
|
return true;
|
|
|
|
Attrs |= Attribute::constructAlignmentFromInt(Alignment);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Lex.Lex();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseOptionalLinkage
|
|
|
|
/// ::= /*empty*/
|
2009-01-15 20:18:42 +00:00
|
|
|
/// ::= 'private'
|
2009-01-02 07:01:27 +00:00
|
|
|
/// ::= 'internal'
|
|
|
|
/// ::= 'weak'
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
/// ::= 'weak_odr'
|
2009-01-02 07:01:27 +00:00
|
|
|
/// ::= 'linkonce'
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
/// ::= 'linkonce_odr'
|
2009-01-02 07:01:27 +00:00
|
|
|
/// ::= 'appending'
|
|
|
|
/// ::= 'dllexport'
|
|
|
|
/// ::= 'common'
|
|
|
|
/// ::= 'dllimport'
|
|
|
|
/// ::= 'extern_weak'
|
|
|
|
/// ::= 'external'
|
|
|
|
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
|
|
|
|
HasLinkage = false;
|
|
|
|
switch (Lex.getKind()) {
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
default: Res = GlobalValue::ExternalLinkage; return false;
|
|
|
|
case lltok::kw_private: Res = GlobalValue::PrivateLinkage; break;
|
|
|
|
case lltok::kw_internal: Res = GlobalValue::InternalLinkage; break;
|
|
|
|
case lltok::kw_weak: Res = GlobalValue::WeakAnyLinkage; break;
|
|
|
|
case lltok::kw_weak_odr: Res = GlobalValue::WeakODRLinkage; break;
|
|
|
|
case lltok::kw_linkonce: Res = GlobalValue::LinkOnceAnyLinkage; break;
|
|
|
|
case lltok::kw_linkonce_odr: Res = GlobalValue::LinkOnceODRLinkage; break;
|
2009-04-13 05:44:34 +00:00
|
|
|
case lltok::kw_available_externally:
|
|
|
|
Res = GlobalValue::AvailableExternallyLinkage;
|
|
|
|
break;
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
|
|
|
|
case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
|
2009-03-11 20:14:15 +00:00
|
|
|
case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break;
|
2009-03-11 08:08:06 +00:00
|
|
|
case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
Lex.Lex();
|
|
|
|
HasLinkage = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseOptionalVisibility
|
|
|
|
/// ::= /*empty*/
|
|
|
|
/// ::= 'default'
|
|
|
|
/// ::= 'hidden'
|
|
|
|
/// ::= 'protected'
|
|
|
|
///
|
|
|
|
bool LLParser::ParseOptionalVisibility(unsigned &Res) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default: Res = GlobalValue::DefaultVisibility; return false;
|
|
|
|
case lltok::kw_default: Res = GlobalValue::DefaultVisibility; break;
|
|
|
|
case lltok::kw_hidden: Res = GlobalValue::HiddenVisibility; break;
|
|
|
|
case lltok::kw_protected: Res = GlobalValue::ProtectedVisibility; break;
|
|
|
|
}
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseOptionalCallingConv
|
|
|
|
/// ::= /*empty*/
|
|
|
|
/// ::= 'ccc'
|
|
|
|
/// ::= 'fastcc'
|
|
|
|
/// ::= 'coldcc'
|
|
|
|
/// ::= 'x86_stdcallcc'
|
|
|
|
/// ::= 'x86_fastcallcc'
|
2009-06-16 18:50:49 +00:00
|
|
|
/// ::= 'arm_apcscc'
|
|
|
|
/// ::= 'arm_aapcscc'
|
|
|
|
/// ::= 'arm_aapcs_vfpcc'
|
2009-01-02 07:01:27 +00:00
|
|
|
/// ::= 'cc' UINT
|
2009-06-16 18:50:49 +00:00
|
|
|
///
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseOptionalCallingConv(unsigned &CC) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default: CC = CallingConv::C; return false;
|
|
|
|
case lltok::kw_ccc: CC = CallingConv::C; break;
|
|
|
|
case lltok::kw_fastcc: CC = CallingConv::Fast; break;
|
|
|
|
case lltok::kw_coldcc: CC = CallingConv::Cold; break;
|
|
|
|
case lltok::kw_x86_stdcallcc: CC = CallingConv::X86_StdCall; break;
|
|
|
|
case lltok::kw_x86_fastcallcc: CC = CallingConv::X86_FastCall; break;
|
2009-06-16 18:50:49 +00:00
|
|
|
case lltok::kw_arm_apcscc: CC = CallingConv::ARM_APCS; break;
|
|
|
|
case lltok::kw_arm_aapcscc: CC = CallingConv::ARM_AAPCS; break;
|
|
|
|
case lltok::kw_arm_aapcs_vfpcc:CC = CallingConv::ARM_AAPCS_VFP; break;
|
2009-01-02 08:05:26 +00:00
|
|
|
case lltok::kw_cc: Lex.Lex(); return ParseUInt32(CC);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseOptionalAlignment
|
|
|
|
/// ::= /* empty */
|
|
|
|
/// ::= 'align' 4
|
|
|
|
bool LLParser::ParseOptionalAlignment(unsigned &Alignment) {
|
|
|
|
Alignment = 0;
|
2009-01-02 08:05:26 +00:00
|
|
|
if (!EatIfPresent(lltok::kw_align))
|
|
|
|
return false;
|
2009-01-05 07:46:05 +00:00
|
|
|
LocTy AlignLoc = Lex.getLoc();
|
|
|
|
if (ParseUInt32(Alignment)) return true;
|
|
|
|
if (!isPowerOf2_32(Alignment))
|
|
|
|
return Error(AlignLoc, "alignment is not a power of two");
|
|
|
|
return false;
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseOptionalCommaAlignment
|
|
|
|
/// ::= /* empty */
|
|
|
|
/// ::= ',' 'align' 4
|
|
|
|
bool LLParser::ParseOptionalCommaAlignment(unsigned &Alignment) {
|
|
|
|
Alignment = 0;
|
2009-01-02 08:05:26 +00:00
|
|
|
if (!EatIfPresent(lltok::comma))
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
return ParseToken(lltok::kw_align, "expected 'align'") ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseUInt32(Alignment);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseIndexList
|
|
|
|
/// ::= (',' uint32)+
|
|
|
|
bool LLParser::ParseIndexList(SmallVectorImpl<unsigned> &Indices) {
|
|
|
|
if (Lex.getKind() != lltok::comma)
|
|
|
|
return TokError("expected ',' as start of index list");
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
2009-01-02 07:01:27 +00:00
|
|
|
unsigned Idx;
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseUInt32(Idx)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
Indices.push_back(Idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Type Parsing.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseType - Parse and resolve a full type.
|
2009-03-09 04:49:14 +00:00
|
|
|
bool LLParser::ParseType(PATypeHolder &Result, bool AllowVoid) {
|
|
|
|
LocTy TypeLoc = Lex.getLoc();
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseTypeRec(Result)) return true;
|
|
|
|
|
|
|
|
// Verify no unresolved uprefs.
|
|
|
|
if (!UpRefs.empty())
|
|
|
|
return Error(UpRefs.back().Loc, "invalid unresolved type up reference");
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (!AllowVoid && Result.get() == Type::VoidTy)
|
|
|
|
return Error(TypeLoc, "void type only allowed for function results");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
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
|
|
|
|
errs() << "Type '" << Ty->getDescription()
|
|
|
|
<< "' 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
|
|
|
|
errs() << " UR#" << i << " - TypeContains(" << Ty->getDescription() << ", "
|
|
|
|
<< UpRefs[i].LastContainedTy->getDescription() << ") = "
|
|
|
|
<< (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
|
|
|
|
errs() << " * 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) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default:
|
|
|
|
return TokError("expected type");
|
|
|
|
case lltok::Type:
|
|
|
|
// TypeRec ::= 'float' | 'void' (etc)
|
|
|
|
Result = Lex.getTyVal();
|
|
|
|
Lex.Lex();
|
|
|
|
break;
|
|
|
|
case lltok::kw_opaque:
|
|
|
|
// TypeRec ::= 'opaque'
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = Context.getOpaqueType();
|
2009-01-02 07:01:27 +00:00
|
|
|
Lex.Lex();
|
|
|
|
break;
|
|
|
|
case lltok::lbrace:
|
|
|
|
// TypeRec ::= '{' ... '}'
|
|
|
|
if (ParseStructType(Result, false))
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case lltok::lsquare:
|
|
|
|
// TypeRec ::= '[' ... ']'
|
|
|
|
Lex.Lex(); // eat the lsquare.
|
|
|
|
if (ParseArrayVectorType(Result, false))
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case lltok::less: // Either vector or packed struct.
|
|
|
|
// TypeRec ::= '<' ... '>'
|
2009-01-02 08:05:26 +00:00
|
|
|
Lex.Lex();
|
|
|
|
if (Lex.getKind() == lltok::lbrace) {
|
|
|
|
if (ParseStructType(Result, true) ||
|
|
|
|
ParseToken(lltok::greater, "expected '>' at end of packed struct"))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
|
|
|
} else if (ParseArrayVectorType(Result, true))
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
case lltok::LocalVar:
|
|
|
|
case lltok::StringConstant: // FIXME: REMOVE IN LLVM 3.0
|
|
|
|
// TypeRec ::= %foo
|
|
|
|
if (const Type *T = M->getTypeByName(Lex.getStrVal())) {
|
|
|
|
Result = T;
|
|
|
|
} else {
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = Context.getOpaqueType();
|
2009-01-02 07:01:27 +00:00
|
|
|
ForwardRefTypes.insert(std::make_pair(Lex.getStrVal(),
|
|
|
|
std::make_pair(Result,
|
|
|
|
Lex.getLoc())));
|
|
|
|
M->addTypeName(Lex.getStrVal(), Result.get());
|
|
|
|
}
|
|
|
|
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 {
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = Context.getOpaqueType();
|
2009-01-02 07:01:27 +00:00
|
|
|
ForwardRefTypeIDs.insert(std::make_pair(Lex.getUIntVal(),
|
|
|
|
std::make_pair(Result,
|
|
|
|
Lex.getLoc())));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Lex.Lex();
|
|
|
|
break;
|
|
|
|
case lltok::backslash: {
|
|
|
|
// TypeRec ::= '\' 4
|
|
|
|
Lex.Lex();
|
2009-01-02 08:05:26 +00:00
|
|
|
unsigned Val;
|
|
|
|
if (ParseUInt32(Val)) return true;
|
2009-07-01 23:57:11 +00:00
|
|
|
OpaqueType *OT = Context.getOpaqueType(); //Use temporary placeholder.
|
2009-01-02 07:01:27 +00:00
|
|
|
UpRefs.push_back(UpRefRecord(Lex.getLoc(), Val, OT));
|
|
|
|
Result = OT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Parse the type suffixes.
|
|
|
|
while (1) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
// End of type.
|
|
|
|
default: return false;
|
|
|
|
|
|
|
|
// TypeRec ::= TypeRec '*'
|
|
|
|
case lltok::star:
|
|
|
|
if (Result.get() == Type::LabelTy)
|
|
|
|
return TokError("basic block pointers are invalid");
|
2009-02-08 19:56:22 +00:00
|
|
|
if (Result.get() == Type::VoidTy)
|
2009-02-09 17:41:21 +00:00
|
|
|
return TokError("pointers to void are invalid; use i8* instead");
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!PointerType::isValidElementType(Result.get()))
|
|
|
|
return TokError("pointer to this type is invalid");
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = HandleUpRefs(Context.getPointerTypeUnqual(Result.get()));
|
2009-01-02 07:01:27 +00:00
|
|
|
Lex.Lex();
|
|
|
|
break;
|
|
|
|
|
|
|
|
// TypeRec ::= TypeRec 'addrspace' '(' uint32 ')' '*'
|
|
|
|
case lltok::kw_addrspace: {
|
|
|
|
if (Result.get() == Type::LabelTy)
|
|
|
|
return TokError("basic block pointers are invalid");
|
2009-02-08 19:56:22 +00:00
|
|
|
if (Result.get() == Type::VoidTy)
|
2009-02-09 17:41:21 +00:00
|
|
|
return TokError("pointers to void are invalid; use i8* instead");
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!PointerType::isValidElementType(Result.get()))
|
|
|
|
return TokError("pointer to this type is invalid");
|
2009-01-02 07:01:27 +00:00
|
|
|
unsigned AddrSpace;
|
|
|
|
if (ParseOptionalAddrSpace(AddrSpace) ||
|
|
|
|
ParseToken(lltok::star, "expected '*' in address space"))
|
|
|
|
return true;
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = HandleUpRefs(Context.getPointerType(Result.get(), AddrSpace));
|
2009-01-02 07:01:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Types '(' ArgTypeListI ')' OptFuncAttrs
|
|
|
|
case lltok::lparen:
|
|
|
|
if (ParseFunctionType(Result))
|
|
|
|
return true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseParameterList
|
|
|
|
/// ::= '(' ')'
|
|
|
|
/// ::= '(' Arg (',' Arg)* ')'
|
|
|
|
/// Arg
|
|
|
|
/// ::= Type OptionalAttributes Value OptionalAttributes
|
|
|
|
bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
|
|
|
PerFunctionState &PFS) {
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' in call"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
while (Lex.getKind() != lltok::rparen) {
|
|
|
|
// If this isn't the first argument, we need a comma.
|
|
|
|
if (!ArgList.empty() &&
|
|
|
|
ParseToken(lltok::comma, "expected ',' in argument list"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Parse the argument.
|
|
|
|
LocTy ArgLoc;
|
|
|
|
PATypeHolder ArgTy(Type::VoidTy);
|
|
|
|
unsigned ArgAttrs1, ArgAttrs2;
|
|
|
|
Value *V;
|
|
|
|
if (ParseType(ArgTy, ArgLoc) ||
|
|
|
|
ParseOptionalAttrs(ArgAttrs1, 0) ||
|
|
|
|
ParseValue(ArgTy, V, PFS) ||
|
|
|
|
// FIXME: Should not allow attributes after the argument, remove this in
|
|
|
|
// LLVM 3.0.
|
2009-03-25 06:36:36 +00:00
|
|
|
ParseOptionalAttrs(ArgAttrs2, 3))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
|
|
|
ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs1|ArgAttrs2));
|
|
|
|
}
|
|
|
|
|
|
|
|
Lex.Lex(); // Lex the ')'.
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-01-05 18:34:07 +00:00
|
|
|
/// ParseArgumentList - Parse the argument list for a function type or function
|
|
|
|
/// prototype. If 'inType' is true then we are parsing a FunctionType.
|
2009-01-02 07:01:27 +00:00
|
|
|
/// ::= '(' ArgTypeListI ')'
|
|
|
|
/// ArgTypeListI
|
|
|
|
/// ::= /*empty*/
|
|
|
|
/// ::= '...'
|
|
|
|
/// ::= ArgTypeList ',' '...'
|
|
|
|
/// ::= ArgType (',' ArgType)*
|
2009-01-05 18:34:07 +00:00
|
|
|
///
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseArgumentList(std::vector<ArgInfo> &ArgList,
|
2009-01-05 18:34:07 +00:00
|
|
|
bool &isVarArg, bool inType) {
|
2009-01-02 07:01:27 +00:00
|
|
|
isVarArg = false;
|
|
|
|
assert(Lex.getKind() == lltok::lparen);
|
|
|
|
Lex.Lex(); // eat the (.
|
|
|
|
|
|
|
|
if (Lex.getKind() == lltok::rparen) {
|
|
|
|
// empty
|
|
|
|
} else if (Lex.getKind() == lltok::dotdotdot) {
|
|
|
|
isVarArg = true;
|
|
|
|
Lex.Lex();
|
|
|
|
} else {
|
|
|
|
LocTy TypeLoc = Lex.getLoc();
|
|
|
|
PATypeHolder ArgTy(Type::VoidTy);
|
|
|
|
unsigned Attrs;
|
|
|
|
std::string Name;
|
2009-01-02 08:05:26 +00:00
|
|
|
|
2009-01-05 18:34:07 +00:00
|
|
|
// 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)) ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseOptionalAttrs(Attrs, 0)) return true;
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (ArgTy == Type::VoidTy)
|
|
|
|
return Error(TypeLoc, "argument can not have void type");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
if (Lex.getKind() == lltok::LocalVar ||
|
|
|
|
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
|
|
|
Name = Lex.getStrVal();
|
|
|
|
Lex.Lex();
|
|
|
|
}
|
2009-01-02 08:05:26 +00:00
|
|
|
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!FunctionType::isValidArgumentType(ArgTy))
|
2009-01-02 08:05:26 +00:00
|
|
|
return Error(TypeLoc, "invalid type for function argument");
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
2009-01-02 07:01:27 +00:00
|
|
|
// Handle ... at end of arg list.
|
2009-01-02 08:05:26 +00:00
|
|
|
if (EatIfPresent(lltok::dotdotdot)) {
|
2009-01-02 07:01:27 +00:00
|
|
|
isVarArg = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise must be an argument type.
|
|
|
|
TypeLoc = Lex.getLoc();
|
2009-03-09 04:49:14 +00:00
|
|
|
if ((inType ? ParseTypeRec(ArgTy) : ParseType(ArgTy)) ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseOptionalAttrs(Attrs, 0)) return true;
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (ArgTy == Type::VoidTy)
|
|
|
|
return Error(TypeLoc, "argument can not have void type");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
if (Lex.getKind() == lltok::LocalVar ||
|
|
|
|
Lex.getKind() == lltok::StringConstant) { // FIXME: REMOVE IN LLVM 3.0
|
|
|
|
Name = Lex.getStrVal();
|
|
|
|
Lex.Lex();
|
|
|
|
} else {
|
|
|
|
Name = "";
|
|
|
|
}
|
2009-01-02 08:05:26 +00:00
|
|
|
|
|
|
|
if (!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy))
|
|
|
|
return Error(TypeLoc, "invalid type for function argument");
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
return ParseToken(lltok::rparen, "expected ')' at end of argument list");
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseFunctionType
|
|
|
|
/// ::= Type ArgumentList OptionalAttrs
|
|
|
|
bool LLParser::ParseFunctionType(PATypeHolder &Result) {
|
|
|
|
assert(Lex.getKind() == lltok::lparen);
|
|
|
|
|
2009-01-05 08:04:33 +00:00
|
|
|
if (!FunctionType::isValidReturnType(Result))
|
|
|
|
return TokError("invalid function return type");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
std::vector<ArgInfo> ArgList;
|
|
|
|
bool isVarArg;
|
|
|
|
unsigned Attrs;
|
2009-01-05 18:34:07 +00:00
|
|
|
if (ParseArgumentList(ArgList, isVarArg, true) ||
|
2009-01-02 07:01:27 +00:00
|
|
|
// FIXME: Allow, but ignore attributes on function types!
|
|
|
|
// FIXME: Remove in LLVM 3.0
|
|
|
|
ParseOptionalAttrs(Attrs, 2))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Reject names on the arguments lists.
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
|
|
|
if (!ArgList[i].Name.empty())
|
|
|
|
return Error(ArgList[i].Loc, "argument name invalid in function type");
|
|
|
|
if (!ArgList[i].Attrs != 0) {
|
|
|
|
// Allow but ignore attributes on function types; this permits
|
|
|
|
// auto-upgrade.
|
|
|
|
// FIXME: REJECT ATTRIBUTES ON FUNCTION TYPES in LLVM 3.0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<const Type*> ArgListTy;
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
|
|
|
|
ArgListTy.push_back(ArgList[i].Type);
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = HandleUpRefs(Context.getFunctionType(Result.get(),
|
|
|
|
ArgListTy, isVarArg));
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseStructType: Handles packed and unpacked types. </> parsed elsewhere.
|
|
|
|
/// TypeRec
|
|
|
|
/// ::= '{' '}'
|
|
|
|
/// ::= '{' TypeRec (',' TypeRec)* '}'
|
|
|
|
/// ::= '<' '{' '}' '>'
|
|
|
|
/// ::= '<' '{' TypeRec (',' TypeRec)* '}' '>'
|
|
|
|
bool LLParser::ParseStructType(PATypeHolder &Result, bool Packed) {
|
|
|
|
assert(Lex.getKind() == lltok::lbrace);
|
|
|
|
Lex.Lex(); // Consume the '{'
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (EatIfPresent(lltok::rbrace)) {
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = Context.getStructType(Packed);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<PATypeHolder> ParamsList;
|
2009-03-09 04:49:14 +00:00
|
|
|
LocTy EltTyLoc = Lex.getLoc();
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseTypeRec(Result)) return true;
|
|
|
|
ParamsList.push_back(Result);
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (Result == Type::VoidTy)
|
|
|
|
return Error(EltTyLoc, "struct element can not have void type");
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!StructType::isValidElementType(Result))
|
|
|
|
return Error(EltTyLoc, "invalid element type for struct");
|
2009-03-09 04:49:14 +00:00
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
2009-03-09 04:49:14 +00:00
|
|
|
EltTyLoc = Lex.getLoc();
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseTypeRec(Result)) return true;
|
2009-03-09 04:49:14 +00:00
|
|
|
|
|
|
|
if (Result == Type::VoidTy)
|
|
|
|
return Error(EltTyLoc, "struct element can not have void type");
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!StructType::isValidElementType(Result))
|
|
|
|
return Error(EltTyLoc, "invalid element type for struct");
|
2009-03-09 04:49:14 +00:00
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
ParamsList.push_back(Result);
|
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseToken(lltok::rbrace, "expected '}' at end of struct"))
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
std::vector<const Type*> ParamsListTy;
|
|
|
|
for (unsigned i = 0, e = ParamsList.size(); i != e; ++i)
|
|
|
|
ParamsListTy.push_back(ParamsList[i].get());
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = HandleUpRefs(Context.getStructType(ParamsListTy, Packed));
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseArrayVectorType - Parse an array or vector type, assuming the first
|
|
|
|
/// token has already been consumed.
|
|
|
|
/// TypeRec
|
|
|
|
/// ::= '[' APSINTVAL 'x' Types ']'
|
|
|
|
/// ::= '<' APSINTVAL 'x' Types '>'
|
|
|
|
bool LLParser::ParseArrayVectorType(PATypeHolder &Result, bool isVector) {
|
|
|
|
if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned() ||
|
|
|
|
Lex.getAPSIntVal().getBitWidth() > 64)
|
|
|
|
return TokError("expected number in address space");
|
|
|
|
|
|
|
|
LocTy SizeLoc = Lex.getLoc();
|
|
|
|
uint64_t Size = Lex.getAPSIntVal().getZExtValue();
|
2009-01-02 08:05:26 +00:00
|
|
|
Lex.Lex();
|
|
|
|
|
|
|
|
if (ParseToken(lltok::kw_x, "expected 'x' after element count"))
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
LocTy TypeLoc = Lex.getLoc();
|
|
|
|
PATypeHolder EltTy(Type::VoidTy);
|
|
|
|
if (ParseTypeRec(EltTy)) return true;
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (EltTy == Type::VoidTy)
|
|
|
|
return Error(TypeLoc, "array and vector element type cannot be void");
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseToken(isVector ? lltok::greater : lltok::rsquare,
|
|
|
|
"expected end of sequential type"))
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
if (isVector) {
|
2009-02-28 18:12:41 +00:00
|
|
|
if (Size == 0)
|
|
|
|
return Error(SizeLoc, "zero element vector is illegal");
|
2009-01-02 07:01:27 +00:00
|
|
|
if ((unsigned)Size != Size)
|
|
|
|
return Error(SizeLoc, "size too large for vector");
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!VectorType::isValidElementType(EltTy))
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(TypeLoc, "vector element type must be fp or integer");
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = Context.getVectorType(EltTy, unsigned(Size));
|
2009-01-02 07:01:27 +00:00
|
|
|
} else {
|
2009-06-07 07:26:46 +00:00
|
|
|
if (!ArrayType::isValidElementType(EltTy))
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(TypeLoc, "invalid array element type");
|
2009-07-01 23:57:11 +00:00
|
|
|
Result = HandleUpRefs(Context.getArrayType(EltTy, Size));
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Function Semantic Analysis.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
LLParser::PerFunctionState::PerFunctionState(LLParser &p, Function &f)
|
|
|
|
: P(p), F(f) {
|
|
|
|
|
|
|
|
// Insert unnamed arguments into the NumberedVals list.
|
|
|
|
for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
|
|
|
|
AI != E; ++AI)
|
|
|
|
if (!AI->hasName())
|
|
|
|
NumberedVals.push_back(AI);
|
|
|
|
}
|
|
|
|
|
|
|
|
LLParser::PerFunctionState::~PerFunctionState() {
|
|
|
|
// If there were any forward referenced non-basicblock values, delete them.
|
|
|
|
for (std::map<std::string, std::pair<Value*, LocTy> >::iterator
|
|
|
|
I = ForwardRefVals.begin(), E = ForwardRefVals.end(); I != E; ++I)
|
|
|
|
if (!isa<BasicBlock>(I->second.first)) {
|
2009-07-02 17:04:01 +00:00
|
|
|
I->second.first->replaceAllUsesWith(
|
|
|
|
P.getContext().getUndef(I->second.first->getType()));
|
2009-01-02 07:01:27 +00:00
|
|
|
delete I->second.first;
|
|
|
|
I->second.first = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (std::map<unsigned, std::pair<Value*, LocTy> >::iterator
|
|
|
|
I = ForwardRefValIDs.begin(), E = ForwardRefValIDs.end(); I != E; ++I)
|
|
|
|
if (!isa<BasicBlock>(I->second.first)) {
|
2009-07-02 17:04:01 +00:00
|
|
|
I->second.first->replaceAllUsesWith(
|
|
|
|
P.getContext().getUndef(I->second.first->getType()));
|
2009-01-02 07:01:27 +00:00
|
|
|
delete I->second.first;
|
|
|
|
I->second.first = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LLParser::PerFunctionState::VerifyFunctionComplete() {
|
|
|
|
if (!ForwardRefVals.empty())
|
|
|
|
return P.Error(ForwardRefVals.begin()->second.second,
|
|
|
|
"use of undefined value '%" + ForwardRefVals.begin()->first +
|
|
|
|
"'");
|
|
|
|
if (!ForwardRefValIDs.empty())
|
|
|
|
return P.Error(ForwardRefValIDs.begin()->second.second,
|
|
|
|
"use of undefined value '%" +
|
|
|
|
utostr(ForwardRefValIDs.begin()->first) + "'");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// GetVal - Get a value with the specified name or ID, creating a
|
|
|
|
/// forward reference record if needed. This can return null if the value
|
|
|
|
/// exists but does not have the right type.
|
|
|
|
Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
|
|
|
|
const Type *Ty, LocTy Loc) {
|
|
|
|
// Look this name up in the normal function symbol table.
|
|
|
|
Value *Val = F.getValueSymbolTable().lookup(Name);
|
|
|
|
|
|
|
|
// If this is a forward reference for the value, see if we already created a
|
|
|
|
// forward ref record.
|
|
|
|
if (Val == 0) {
|
|
|
|
std::map<std::string, std::pair<Value*, LocTy> >::iterator
|
|
|
|
I = ForwardRefVals.find(Name);
|
|
|
|
if (I != ForwardRefVals.end())
|
|
|
|
Val = I->second.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have the value in the symbol table or fwd-ref table, return it.
|
|
|
|
if (Val) {
|
|
|
|
if (Val->getType() == Ty) return Val;
|
|
|
|
if (Ty == Type::LabelTy)
|
|
|
|
P.Error(Loc, "'%" + Name + "' is not a basic block");
|
|
|
|
else
|
|
|
|
P.Error(Loc, "'%" + Name + "' defined with type '" +
|
|
|
|
Val->getType()->getDescription() + "'");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Don't make placeholders with invalid type.
|
|
|
|
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) && Ty != Type::LabelTy) {
|
|
|
|
P.Error(Loc, "invalid use of a non-first-class type");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, create a new forward reference for this value and remember it.
|
|
|
|
Value *FwdVal;
|
|
|
|
if (Ty == Type::LabelTy)
|
|
|
|
FwdVal = BasicBlock::Create(Name, &F);
|
|
|
|
else
|
|
|
|
FwdVal = new Argument(Ty, Name);
|
|
|
|
|
|
|
|
ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
|
|
|
|
return FwdVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *LLParser::PerFunctionState::GetVal(unsigned ID, const Type *Ty,
|
|
|
|
LocTy Loc) {
|
|
|
|
// Look this name up in the normal function symbol table.
|
|
|
|
Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : 0;
|
|
|
|
|
|
|
|
// If this is a forward reference for the value, see if we already created a
|
|
|
|
// forward ref record.
|
|
|
|
if (Val == 0) {
|
|
|
|
std::map<unsigned, std::pair<Value*, LocTy> >::iterator
|
|
|
|
I = ForwardRefValIDs.find(ID);
|
|
|
|
if (I != ForwardRefValIDs.end())
|
|
|
|
Val = I->second.first;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have the value in the symbol table or fwd-ref table, return it.
|
|
|
|
if (Val) {
|
|
|
|
if (Val->getType() == Ty) return Val;
|
|
|
|
if (Ty == Type::LabelTy)
|
|
|
|
P.Error(Loc, "'%" + utostr(ID) + "' is not a basic block");
|
|
|
|
else
|
|
|
|
P.Error(Loc, "'%" + utostr(ID) + "' defined with type '" +
|
|
|
|
Val->getType()->getDescription() + "'");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Ty->isFirstClassType() && !isa<OpaqueType>(Ty) && Ty != Type::LabelTy) {
|
|
|
|
P.Error(Loc, "invalid use of a non-first-class type");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, create a new forward reference for this value and remember it.
|
|
|
|
Value *FwdVal;
|
|
|
|
if (Ty == Type::LabelTy)
|
|
|
|
FwdVal = BasicBlock::Create("", &F);
|
|
|
|
else
|
|
|
|
FwdVal = new Argument(Ty);
|
|
|
|
|
|
|
|
ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
|
|
|
|
return FwdVal;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// SetInstName - After an instruction is parsed and inserted into its
|
|
|
|
/// basic block, this installs its name.
|
|
|
|
bool LLParser::PerFunctionState::SetInstName(int NameID,
|
|
|
|
const std::string &NameStr,
|
|
|
|
LocTy NameLoc, Instruction *Inst) {
|
|
|
|
// If this instruction has void type, it cannot have a name or ID specified.
|
|
|
|
if (Inst->getType() == Type::VoidTy) {
|
|
|
|
if (NameID != -1 || !NameStr.empty())
|
|
|
|
return P.Error(NameLoc, "instructions returning void cannot have a name");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this was a numbered instruction, verify that the instruction is the
|
|
|
|
// expected value and resolve any forward references.
|
|
|
|
if (NameStr.empty()) {
|
|
|
|
// If neither a name nor an ID was specified, just use the next ID.
|
|
|
|
if (NameID == -1)
|
|
|
|
NameID = NumberedVals.size();
|
|
|
|
|
|
|
|
if (unsigned(NameID) != NumberedVals.size())
|
|
|
|
return P.Error(NameLoc, "instruction expected to be numbered '%" +
|
|
|
|
utostr(NumberedVals.size()) + "'");
|
|
|
|
|
|
|
|
std::map<unsigned, std::pair<Value*, LocTy> >::iterator FI =
|
|
|
|
ForwardRefValIDs.find(NameID);
|
|
|
|
if (FI != ForwardRefValIDs.end()) {
|
|
|
|
if (FI->second.first->getType() != Inst->getType())
|
|
|
|
return P.Error(NameLoc, "instruction forward referenced with type '" +
|
|
|
|
FI->second.first->getType()->getDescription() + "'");
|
|
|
|
FI->second.first->replaceAllUsesWith(Inst);
|
|
|
|
ForwardRefValIDs.erase(FI);
|
|
|
|
}
|
|
|
|
|
|
|
|
NumberedVals.push_back(Inst);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Otherwise, the instruction had a name. Resolve forward refs and set it.
|
|
|
|
std::map<std::string, std::pair<Value*, LocTy> >::iterator
|
|
|
|
FI = ForwardRefVals.find(NameStr);
|
|
|
|
if (FI != ForwardRefVals.end()) {
|
|
|
|
if (FI->second.first->getType() != Inst->getType())
|
|
|
|
return P.Error(NameLoc, "instruction forward referenced with type '" +
|
|
|
|
FI->second.first->getType()->getDescription() + "'");
|
|
|
|
FI->second.first->replaceAllUsesWith(Inst);
|
|
|
|
ForwardRefVals.erase(FI);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the name on the instruction.
|
|
|
|
Inst->setName(NameStr);
|
|
|
|
|
|
|
|
if (Inst->getNameStr() != NameStr)
|
|
|
|
return P.Error(NameLoc, "multiple definition of local value named '" +
|
|
|
|
NameStr + "'");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// GetBB - Get a basic block with the specified name or ID, creating a
|
|
|
|
/// forward reference record if needed.
|
|
|
|
BasicBlock *LLParser::PerFunctionState::GetBB(const std::string &Name,
|
|
|
|
LocTy Loc) {
|
|
|
|
return cast_or_null<BasicBlock>(GetVal(Name, Type::LabelTy, Loc));
|
|
|
|
}
|
|
|
|
|
|
|
|
BasicBlock *LLParser::PerFunctionState::GetBB(unsigned ID, LocTy Loc) {
|
|
|
|
return cast_or_null<BasicBlock>(GetVal(ID, Type::LabelTy, Loc));
|
|
|
|
}
|
|
|
|
|
|
|
|
/// DefineBB - Define the specified basic block, which is either named or
|
|
|
|
/// unnamed. If there is an error, this returns null otherwise it returns
|
|
|
|
/// the block being defined.
|
|
|
|
BasicBlock *LLParser::PerFunctionState::DefineBB(const std::string &Name,
|
|
|
|
LocTy Loc) {
|
|
|
|
BasicBlock *BB;
|
|
|
|
if (Name.empty())
|
|
|
|
BB = GetBB(NumberedVals.size(), Loc);
|
|
|
|
else
|
|
|
|
BB = GetBB(Name, Loc);
|
|
|
|
if (BB == 0) return 0; // Already diagnosed error.
|
|
|
|
|
|
|
|
// Move the block to the end of the function. Forward ref'd blocks are
|
|
|
|
// inserted wherever they happen to be referenced.
|
|
|
|
F.getBasicBlockList().splice(F.end(), F.getBasicBlockList(), BB);
|
|
|
|
|
|
|
|
// Remove the block from forward ref sets.
|
|
|
|
if (Name.empty()) {
|
|
|
|
ForwardRefValIDs.erase(NumberedVals.size());
|
|
|
|
NumberedVals.push_back(BB);
|
|
|
|
} else {
|
|
|
|
// BB forward references are already in the function symbol table.
|
|
|
|
ForwardRefVals.erase(Name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return BB;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Constants.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseValID - Parse an abstract value that doesn't necessarily have a
|
|
|
|
/// type implied. For example, if we parse "4" we don't know what integer type
|
|
|
|
/// it has. The value will later be combined with its type and checked for
|
|
|
|
/// sanity.
|
|
|
|
bool LLParser::ParseValID(ValID &ID) {
|
|
|
|
ID.Loc = Lex.getLoc();
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default: return TokError("expected value token");
|
|
|
|
case lltok::GlobalID: // @42
|
|
|
|
ID.UIntVal = Lex.getUIntVal();
|
|
|
|
ID.Kind = ValID::t_GlobalID;
|
|
|
|
break;
|
|
|
|
case lltok::GlobalVar: // @foo
|
|
|
|
ID.StrVal = Lex.getStrVal();
|
|
|
|
ID.Kind = ValID::t_GlobalName;
|
|
|
|
break;
|
|
|
|
case lltok::LocalVarID: // %42
|
|
|
|
ID.UIntVal = Lex.getUIntVal();
|
|
|
|
ID.Kind = ValID::t_LocalID;
|
|
|
|
break;
|
|
|
|
case lltok::LocalVar: // %foo
|
|
|
|
case lltok::StringConstant: // "foo" - FIXME: REMOVE IN LLVM 3.0
|
|
|
|
ID.StrVal = Lex.getStrVal();
|
|
|
|
ID.Kind = ValID::t_LocalName;
|
|
|
|
break;
|
2009-04-04 07:22:01 +00:00
|
|
|
case lltok::Metadata: { // !{...} MDNode, !"foo" MDString
|
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
Lex.Lex();
|
|
|
|
if (Lex.getKind() == lltok::lbrace) {
|
2009-05-10 20:57:05 +00:00
|
|
|
SmallVector<Value*, 16> Elts;
|
2009-04-04 07:22:01 +00:00
|
|
|
if (ParseMDNodeVector(Elts) ||
|
|
|
|
ParseToken(lltok::rbrace, "expected end of metadata node"))
|
|
|
|
return true;
|
2009-05-10 20:57:05 +00:00
|
|
|
|
2009-07-02 17:20:28 +00:00
|
|
|
ID.ConstantVal = Context.getMDNode(Elts.data(), Elts.size());
|
2009-04-04 07:22:01 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-07-01 19:21:12 +00:00
|
|
|
// Standalone metadata reference
|
|
|
|
// !{ ..., !42, ... }
|
|
|
|
unsigned MID = 0;
|
|
|
|
if (!ParseUInt32(MID)) {
|
|
|
|
std::map<unsigned, Constant *>::iterator I = MetadataCache.find(MID);
|
|
|
|
if (I == MetadataCache.end())
|
|
|
|
return TokError("Unknown metadata reference");
|
|
|
|
ID.ConstantVal = I->second;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-04-04 07:22:01 +00:00
|
|
|
// MDString:
|
|
|
|
// ::= '!' STRINGCONSTANT
|
|
|
|
std::string Str;
|
|
|
|
if (ParseStringConstant(Str)) return true;
|
|
|
|
|
2009-07-02 17:28:30 +00:00
|
|
|
ID.ConstantVal = Context.getMDString(Str.data(), Str.data() + Str.size());
|
2009-04-04 07:22:01 +00:00
|
|
|
return false;
|
|
|
|
}
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::APSInt:
|
|
|
|
ID.APSIntVal = Lex.getAPSIntVal();
|
|
|
|
ID.Kind = ValID::t_APSInt;
|
|
|
|
break;
|
|
|
|
case lltok::APFloat:
|
|
|
|
ID.APFloatVal = Lex.getAPFloatVal();
|
|
|
|
ID.Kind = ValID::t_APFloat;
|
|
|
|
break;
|
|
|
|
case lltok::kw_true:
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantIntTrue();
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
break;
|
|
|
|
case lltok::kw_false:
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantIntFalse();
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
break;
|
|
|
|
case lltok::kw_null: ID.Kind = ValID::t_Null; break;
|
|
|
|
case lltok::kw_undef: ID.Kind = ValID::t_Undef; break;
|
|
|
|
case lltok::kw_zeroinitializer: ID.Kind = ValID::t_Zero; break;
|
|
|
|
|
|
|
|
case lltok::lbrace: {
|
|
|
|
// ValID ::= '{' ConstVector '}'
|
|
|
|
Lex.Lex();
|
|
|
|
SmallVector<Constant*, 16> Elts;
|
|
|
|
if (ParseGlobalValueVector(Elts) ||
|
|
|
|
ParseToken(lltok::rbrace, "expected end of struct constant"))
|
|
|
|
return true;
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantStruct(Elts.data(), Elts.size(), false);
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case lltok::less: {
|
|
|
|
// ValID ::= '<' ConstVector '>' --> Vector.
|
|
|
|
// ValID ::= '<' '{' ConstVector '}' '>' --> Packed Struct.
|
|
|
|
Lex.Lex();
|
2009-01-02 08:05:26 +00:00
|
|
|
bool isPackedStruct = EatIfPresent(lltok::lbrace);
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
SmallVector<Constant*, 16> Elts;
|
|
|
|
LocTy FirstEltLoc = Lex.getLoc();
|
|
|
|
if (ParseGlobalValueVector(Elts) ||
|
|
|
|
(isPackedStruct &&
|
|
|
|
ParseToken(lltok::rbrace, "expected end of packed struct")) ||
|
|
|
|
ParseToken(lltok::greater, "expected end of constant"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (isPackedStruct) {
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal =
|
|
|
|
Context.getConstantStruct(Elts.data(), Elts.size(), true);
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Elts.empty())
|
|
|
|
return Error(ID.Loc, "constant vector must not be empty");
|
|
|
|
|
|
|
|
if (!Elts[0]->getType()->isInteger() &&
|
|
|
|
!Elts[0]->getType()->isFloatingPoint())
|
|
|
|
return Error(FirstEltLoc,
|
|
|
|
"vector elements must have integer or floating point type");
|
|
|
|
|
|
|
|
// Verify that all the vector elements have the same type.
|
|
|
|
for (unsigned i = 1, e = Elts.size(); i != e; ++i)
|
|
|
|
if (Elts[i]->getType() != Elts[0]->getType())
|
|
|
|
return Error(FirstEltLoc,
|
|
|
|
"vector element #" + utostr(i) +
|
|
|
|
" is not of type '" + Elts[0]->getType()->getDescription());
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantVector(Elts.data(), Elts.size());
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case lltok::lsquare: { // Array Constant
|
|
|
|
Lex.Lex();
|
|
|
|
SmallVector<Constant*, 16> Elts;
|
|
|
|
LocTy FirstEltLoc = Lex.getLoc();
|
|
|
|
if (ParseGlobalValueVector(Elts) ||
|
|
|
|
ParseToken(lltok::rsquare, "expected end of array constant"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// Handle empty element.
|
|
|
|
if (Elts.empty()) {
|
|
|
|
// Use undef instead of an array because it's inconvenient to determine
|
|
|
|
// the element type at this point, there being no elements to examine.
|
2009-01-05 07:52:51 +00:00
|
|
|
ID.Kind = ValID::t_EmptyArray;
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Elts[0]->getType()->isFirstClassType())
|
|
|
|
return Error(FirstEltLoc, "invalid array element type: " +
|
|
|
|
Elts[0]->getType()->getDescription());
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
ArrayType *ATy = Context.getArrayType(Elts[0]->getType(), Elts.size());
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
// Verify all elements are correct type!
|
2009-01-02 08:49:06 +00:00
|
|
|
for (unsigned i = 0, e = Elts.size(); i != e; ++i) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (Elts[i]->getType() != Elts[0]->getType())
|
|
|
|
return Error(FirstEltLoc,
|
|
|
|
"array element #" + utostr(i) +
|
|
|
|
" is not of type '" +Elts[0]->getType()->getDescription());
|
|
|
|
}
|
2009-04-04 07:22:01 +00:00
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantArray(ATy, Elts.data(), Elts.size());
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case lltok::kw_c: // c "foo"
|
|
|
|
Lex.Lex();
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantArray(Lex.getStrVal(), false);
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseToken(lltok::StringConstant, "expected string")) return true;
|
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case lltok::kw_asm: {
|
|
|
|
// ValID ::= 'asm' SideEffect? STRINGCONSTANT ',' STRINGCONSTANT
|
|
|
|
bool HasSideEffect;
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseOptionalToken(lltok::kw_sideeffect, HasSideEffect) ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseStringConstant(ID.StrVal) ||
|
|
|
|
ParseToken(lltok::comma, "expected comma in inline asm expression") ||
|
2009-01-02 07:01:27 +00:00
|
|
|
ParseToken(lltok::StringConstant, "expected constraint string"))
|
|
|
|
return true;
|
|
|
|
ID.StrVal2 = Lex.getStrVal();
|
|
|
|
ID.UIntVal = HasSideEffect;
|
|
|
|
ID.Kind = ValID::t_InlineAsm;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case lltok::kw_trunc:
|
|
|
|
case lltok::kw_zext:
|
|
|
|
case lltok::kw_sext:
|
|
|
|
case lltok::kw_fptrunc:
|
|
|
|
case lltok::kw_fpext:
|
|
|
|
case lltok::kw_bitcast:
|
|
|
|
case lltok::kw_uitofp:
|
|
|
|
case lltok::kw_sitofp:
|
|
|
|
case lltok::kw_fptoui:
|
|
|
|
case lltok::kw_fptosi:
|
|
|
|
case lltok::kw_inttoptr:
|
|
|
|
case lltok::kw_ptrtoint: {
|
|
|
|
unsigned Opc = Lex.getUIntVal();
|
|
|
|
PATypeHolder DestTy(Type::VoidTy);
|
|
|
|
Constant *SrcVal;
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' after constantexpr cast") ||
|
|
|
|
ParseGlobalTypeAndValue(SrcVal) ||
|
2009-06-15 21:52:11 +00:00
|
|
|
ParseToken(lltok::kw_to, "expected 'to' in constantexpr cast") ||
|
2009-01-02 07:01:27 +00:00
|
|
|
ParseType(DestTy) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' at end of constantexpr cast"))
|
|
|
|
return true;
|
|
|
|
if (!CastInst::castIsValid((Instruction::CastOps)Opc, SrcVal, DestTy))
|
|
|
|
return Error(ID.Loc, "invalid cast opcode for cast from '" +
|
|
|
|
SrcVal->getType()->getDescription() + "' to '" +
|
|
|
|
DestTy->getDescription() + "'");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprCast((Instruction::CastOps)Opc,
|
|
|
|
SrcVal, DestTy);
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case lltok::kw_extractvalue: {
|
|
|
|
Lex.Lex();
|
|
|
|
Constant *Val;
|
|
|
|
SmallVector<unsigned, 4> Indices;
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' in extractvalue constantexpr")||
|
|
|
|
ParseGlobalTypeAndValue(Val) ||
|
|
|
|
ParseIndexList(Indices) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' in extractvalue constantexpr"))
|
|
|
|
return true;
|
|
|
|
if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
|
|
|
|
return Error(ID.Loc, "extractvalue operand must be array or struct");
|
|
|
|
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
|
|
|
|
Indices.end()))
|
|
|
|
return Error(ID.Loc, "invalid indices for extractvalue");
|
2009-05-21 09:52:38 +00:00
|
|
|
ID.ConstantVal =
|
2009-07-01 23:57:11 +00:00
|
|
|
Context.getConstantExprExtractValue(Val, Indices.data(), Indices.size());
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case lltok::kw_insertvalue: {
|
|
|
|
Lex.Lex();
|
|
|
|
Constant *Val0, *Val1;
|
|
|
|
SmallVector<unsigned, 4> Indices;
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' in insertvalue constantexpr")||
|
|
|
|
ParseGlobalTypeAndValue(Val0) ||
|
|
|
|
ParseToken(lltok::comma, "expected comma in insertvalue constantexpr")||
|
|
|
|
ParseGlobalTypeAndValue(Val1) ||
|
|
|
|
ParseIndexList(Indices) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' in insertvalue constantexpr"))
|
|
|
|
return true;
|
|
|
|
if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
|
|
|
|
return Error(ID.Loc, "extractvalue operand must be array or struct");
|
|
|
|
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
|
|
|
|
Indices.end()))
|
|
|
|
return Error(ID.Loc, "invalid indices for insertvalue");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprInsertValue(Val0, Val1,
|
|
|
|
Indices.data(), Indices.size());
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
case lltok::kw_icmp:
|
|
|
|
case lltok::kw_fcmp:
|
|
|
|
case lltok::kw_vicmp:
|
|
|
|
case lltok::kw_vfcmp: {
|
|
|
|
unsigned PredVal, Opc = Lex.getUIntVal();
|
|
|
|
Constant *Val0, *Val1;
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseCmpPredicate(PredVal, Opc) ||
|
|
|
|
ParseToken(lltok::lparen, "expected '(' in compare constantexpr") ||
|
|
|
|
ParseGlobalTypeAndValue(Val0) ||
|
|
|
|
ParseToken(lltok::comma, "expected comma in compare constantexpr") ||
|
|
|
|
ParseGlobalTypeAndValue(Val1) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' in compare constantexpr"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (Val0->getType() != Val1->getType())
|
|
|
|
return Error(ID.Loc, "compare operands must have the same type");
|
|
|
|
|
|
|
|
CmpInst::Predicate Pred = (CmpInst::Predicate)PredVal;
|
|
|
|
|
|
|
|
if (Opc == Instruction::FCmp) {
|
|
|
|
if (!Val0->getType()->isFPOrFPVector())
|
|
|
|
return Error(ID.Loc, "fcmp requires floating point operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprFCmp(Pred, Val0, Val1);
|
2009-01-02 07:01:27 +00:00
|
|
|
} else if (Opc == Instruction::ICmp) {
|
|
|
|
if (!Val0->getType()->isIntOrIntVector() &&
|
|
|
|
!isa<PointerType>(Val0->getType()))
|
|
|
|
return Error(ID.Loc, "icmp requires pointer or integer operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprICmp(Pred, Val0, Val1);
|
2009-01-02 07:01:27 +00:00
|
|
|
} else if (Opc == Instruction::VFCmp) {
|
|
|
|
// FIXME: REMOVE VFCMP Support
|
2009-01-05 08:26:05 +00:00
|
|
|
if (!Val0->getType()->isFPOrFPVector() ||
|
|
|
|
!isa<VectorType>(Val0->getType()))
|
|
|
|
return Error(ID.Loc, "vfcmp requires vector floating point operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprVFCmp(Pred, Val0, Val1);
|
2009-01-02 07:01:27 +00:00
|
|
|
} else if (Opc == Instruction::VICmp) {
|
2009-01-05 08:26:05 +00:00
|
|
|
// FIXME: REMOVE VICMP Support
|
|
|
|
if (!Val0->getType()->isIntOrIntVector() ||
|
|
|
|
!isa<VectorType>(Val0->getType()))
|
|
|
|
return Error(ID.Loc, "vicmp requires vector floating point operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprVICmp(Pred, Val0, Val1);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Binary Operators.
|
|
|
|
case lltok::kw_add:
|
2009-06-04 22:49:04 +00:00
|
|
|
case lltok::kw_fadd:
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_sub:
|
2009-06-04 22:49:04 +00:00
|
|
|
case lltok::kw_fsub:
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_mul:
|
2009-06-04 22:49:04 +00:00
|
|
|
case lltok::kw_fmul:
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_udiv:
|
|
|
|
case lltok::kw_sdiv:
|
|
|
|
case lltok::kw_fdiv:
|
|
|
|
case lltok::kw_urem:
|
|
|
|
case lltok::kw_srem:
|
|
|
|
case lltok::kw_frem: {
|
|
|
|
unsigned Opc = Lex.getUIntVal();
|
|
|
|
Constant *Val0, *Val1;
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' in binary constantexpr") ||
|
|
|
|
ParseGlobalTypeAndValue(Val0) ||
|
|
|
|
ParseToken(lltok::comma, "expected comma in binary constantexpr") ||
|
|
|
|
ParseGlobalTypeAndValue(Val1) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' in binary constantexpr"))
|
|
|
|
return true;
|
|
|
|
if (Val0->getType() != Val1->getType())
|
|
|
|
return Error(ID.Loc, "operands of constexpr must have same type");
|
|
|
|
if (!Val0->getType()->isIntOrIntVector() &&
|
|
|
|
!Val0->getType()->isFPOrFPVector())
|
|
|
|
return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExpr(Opc, Val0, Val1);
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Logical Operations
|
|
|
|
case lltok::kw_shl:
|
|
|
|
case lltok::kw_lshr:
|
|
|
|
case lltok::kw_ashr:
|
|
|
|
case lltok::kw_and:
|
|
|
|
case lltok::kw_or:
|
|
|
|
case lltok::kw_xor: {
|
|
|
|
unsigned Opc = Lex.getUIntVal();
|
|
|
|
Constant *Val0, *Val1;
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' in logical constantexpr") ||
|
|
|
|
ParseGlobalTypeAndValue(Val0) ||
|
|
|
|
ParseToken(lltok::comma, "expected comma in logical constantexpr") ||
|
|
|
|
ParseGlobalTypeAndValue(Val1) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' in logical constantexpr"))
|
|
|
|
return true;
|
|
|
|
if (Val0->getType() != Val1->getType())
|
|
|
|
return Error(ID.Loc, "operands of constexpr must have same type");
|
|
|
|
if (!Val0->getType()->isIntOrIntVector())
|
|
|
|
return Error(ID.Loc,
|
|
|
|
"constexpr requires integer or integer vector operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExpr(Opc, Val0, Val1);
|
2009-01-02 07:01:27 +00:00
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
case lltok::kw_getelementptr:
|
|
|
|
case lltok::kw_shufflevector:
|
|
|
|
case lltok::kw_insertelement:
|
|
|
|
case lltok::kw_extractelement:
|
|
|
|
case lltok::kw_select: {
|
|
|
|
unsigned Opc = Lex.getUIntVal();
|
|
|
|
SmallVector<Constant*, 16> Elts;
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::lparen, "expected '(' in constantexpr") ||
|
|
|
|
ParseGlobalValueVector(Elts) ||
|
|
|
|
ParseToken(lltok::rparen, "expected ')' in constantexpr"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (Opc == Instruction::GetElementPtr) {
|
|
|
|
if (Elts.size() == 0 || !isa<PointerType>(Elts[0]->getType()))
|
|
|
|
return Error(ID.Loc, "getelementptr requires pointer operand");
|
|
|
|
|
|
|
|
if (!GetElementPtrInst::getIndexedType(Elts[0]->getType(),
|
|
|
|
(Value**)&Elts[1], Elts.size()-1))
|
|
|
|
return Error(ID.Loc, "invalid indices for getelementptr");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprGetElementPtr(Elts[0],
|
2009-01-02 07:01:27 +00:00
|
|
|
&Elts[1], Elts.size()-1);
|
|
|
|
} else if (Opc == Instruction::Select) {
|
|
|
|
if (Elts.size() != 3)
|
|
|
|
return Error(ID.Loc, "expected three operands to select");
|
|
|
|
if (const char *Reason = SelectInst::areInvalidOperands(Elts[0], Elts[1],
|
|
|
|
Elts[2]))
|
|
|
|
return Error(ID.Loc, Reason);
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprSelect(Elts[0], Elts[1], Elts[2]);
|
2009-01-02 07:01:27 +00:00
|
|
|
} else if (Opc == Instruction::ShuffleVector) {
|
|
|
|
if (Elts.size() != 3)
|
|
|
|
return Error(ID.Loc, "expected three operands to shufflevector");
|
|
|
|
if (!ShuffleVectorInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
|
|
|
|
return Error(ID.Loc, "invalid operands to shufflevector");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal =
|
|
|
|
Context.getConstantExprShuffleVector(Elts[0], Elts[1],Elts[2]);
|
2009-01-02 07:01:27 +00:00
|
|
|
} else if (Opc == Instruction::ExtractElement) {
|
|
|
|
if (Elts.size() != 2)
|
|
|
|
return Error(ID.Loc, "expected two operands to extractelement");
|
|
|
|
if (!ExtractElementInst::isValidOperands(Elts[0], Elts[1]))
|
|
|
|
return Error(ID.Loc, "invalid extractelement operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal = Context.getConstantExprExtractElement(Elts[0], Elts[1]);
|
2009-01-02 07:01:27 +00:00
|
|
|
} else {
|
|
|
|
assert(Opc == Instruction::InsertElement && "Unknown opcode");
|
|
|
|
if (Elts.size() != 3)
|
|
|
|
return Error(ID.Loc, "expected three operands to insertelement");
|
|
|
|
if (!InsertElementInst::isValidOperands(Elts[0], Elts[1], Elts[2]))
|
|
|
|
return Error(ID.Loc, "invalid insertelement operands");
|
2009-07-01 23:57:11 +00:00
|
|
|
ID.ConstantVal =
|
|
|
|
Context.getConstantExprInsertElement(Elts[0], Elts[1],Elts[2]);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ID.Kind = ValID::t_Constant;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseGlobalValue - Parse a global value with the specified type.
|
|
|
|
bool LLParser::ParseGlobalValue(const Type *Ty, Constant *&V) {
|
|
|
|
V = 0;
|
|
|
|
ValID ID;
|
2009-01-02 08:05:26 +00:00
|
|
|
return ParseValID(ID) ||
|
|
|
|
ConvertGlobalValIDToValue(Ty, ID, V);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// ConvertGlobalValIDToValue - Apply a type to a ValID to get a fully resolved
|
|
|
|
/// constant.
|
|
|
|
bool LLParser::ConvertGlobalValIDToValue(const Type *Ty, ValID &ID,
|
|
|
|
Constant *&V) {
|
|
|
|
if (isa<FunctionType>(Ty))
|
|
|
|
return Error(ID.Loc, "functions are not values, refer to them as pointers");
|
|
|
|
|
|
|
|
switch (ID.Kind) {
|
|
|
|
default: assert(0 && "Unknown ValID!");
|
|
|
|
case ValID::t_LocalID:
|
|
|
|
case ValID::t_LocalName:
|
|
|
|
return Error(ID.Loc, "invalid use of function-local name");
|
|
|
|
case ValID::t_InlineAsm:
|
|
|
|
return Error(ID.Loc, "inline asm can only be an operand of call/invoke");
|
|
|
|
case ValID::t_GlobalName:
|
|
|
|
V = GetGlobalVal(ID.StrVal, Ty, ID.Loc);
|
|
|
|
return V == 0;
|
|
|
|
case ValID::t_GlobalID:
|
|
|
|
V = GetGlobalVal(ID.UIntVal, Ty, ID.Loc);
|
|
|
|
return V == 0;
|
|
|
|
case ValID::t_APSInt:
|
|
|
|
if (!isa<IntegerType>(Ty))
|
|
|
|
return Error(ID.Loc, "integer constant must have integer type");
|
|
|
|
ID.APSIntVal.extOrTrunc(Ty->getPrimitiveSizeInBits());
|
2009-07-01 23:57:11 +00:00
|
|
|
V = Context.getConstantInt(ID.APSIntVal);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
case ValID::t_APFloat:
|
|
|
|
if (!Ty->isFloatingPoint() ||
|
|
|
|
!ConstantFP::isValueValidForType(Ty, ID.APFloatVal))
|
|
|
|
return Error(ID.Loc, "floating point constant invalid for type");
|
|
|
|
|
|
|
|
// The lexer has no type info, so builds all float and double FP constants
|
|
|
|
// as double. Fix this here. Long double does not need this.
|
|
|
|
if (&ID.APFloatVal.getSemantics() == &APFloat::IEEEdouble &&
|
|
|
|
Ty == Type::FloatTy) {
|
|
|
|
bool Ignored;
|
|
|
|
ID.APFloatVal.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven,
|
|
|
|
&Ignored);
|
|
|
|
}
|
2009-07-01 23:57:11 +00:00
|
|
|
V = Context.getConstantFP(ID.APFloatVal);
|
2009-01-05 18:24:23 +00:00
|
|
|
|
|
|
|
if (V->getType() != Ty)
|
|
|
|
return Error(ID.Loc, "floating point constant does not have type '" +
|
|
|
|
Ty->getDescription() + "'");
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
case ValID::t_Null:
|
|
|
|
if (!isa<PointerType>(Ty))
|
|
|
|
return Error(ID.Loc, "null must be a pointer type");
|
2009-07-01 23:57:11 +00:00
|
|
|
V = Context.getConstantPointerNull(cast<PointerType>(Ty));
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
case ValID::t_Undef:
|
2009-01-05 08:13:38 +00:00
|
|
|
// FIXME: LabelTy should not be a first-class type.
|
2009-01-05 18:12:21 +00:00
|
|
|
if ((!Ty->isFirstClassType() || Ty == Type::LabelTy) &&
|
|
|
|
!isa<OpaqueType>(Ty))
|
2009-01-05 08:13:38 +00:00
|
|
|
return Error(ID.Loc, "invalid type for undef constant");
|
2009-07-02 17:04:01 +00:00
|
|
|
V = Context.getUndef(Ty);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
2009-01-05 07:52:51 +00:00
|
|
|
case ValID::t_EmptyArray:
|
|
|
|
if (!isa<ArrayType>(Ty) || cast<ArrayType>(Ty)->getNumElements() != 0)
|
|
|
|
return Error(ID.Loc, "invalid empty array initializer");
|
2009-07-02 17:04:01 +00:00
|
|
|
V = Context.getUndef(Ty);
|
2009-01-05 07:52:51 +00:00
|
|
|
return false;
|
2009-01-02 07:01:27 +00:00
|
|
|
case ValID::t_Zero:
|
2009-01-05 08:13:38 +00:00
|
|
|
// FIXME: LabelTy should not be a first-class type.
|
|
|
|
if (!Ty->isFirstClassType() || Ty == Type::LabelTy)
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(ID.Loc, "invalid type for null constant");
|
2009-07-01 23:57:11 +00:00
|
|
|
V = Context.getNullValue(Ty);
|
2009-01-02 07:01:27 +00:00
|
|
|
return false;
|
|
|
|
case ValID::t_Constant:
|
|
|
|
if (ID.ConstantVal->getType() != Ty)
|
|
|
|
return Error(ID.Loc, "constant expression type mismatch");
|
|
|
|
V = ID.ConstantVal;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LLParser::ParseGlobalTypeAndValue(Constant *&V) {
|
|
|
|
PATypeHolder Type(Type::VoidTy);
|
|
|
|
return ParseType(Type) ||
|
|
|
|
ParseGlobalValue(Type, V);
|
|
|
|
}
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
/// ParseGlobalValueVector
|
|
|
|
/// ::= /*empty*/
|
|
|
|
/// ::= TypeAndValue (',' TypeAndValue)*
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant*> &Elts) {
|
|
|
|
// Empty list.
|
|
|
|
if (Lex.getKind() == lltok::rbrace ||
|
|
|
|
Lex.getKind() == lltok::rsquare ||
|
|
|
|
Lex.getKind() == lltok::greater ||
|
|
|
|
Lex.getKind() == lltok::rparen)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Constant *C;
|
|
|
|
if (ParseGlobalTypeAndValue(C)) return true;
|
|
|
|
Elts.push_back(C);
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseGlobalTypeAndValue(C)) return true;
|
|
|
|
Elts.push_back(C);
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Function Parsing.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
bool LLParser::ConvertValIDToValue(const Type *Ty, ValID &ID, Value *&V,
|
|
|
|
PerFunctionState &PFS) {
|
|
|
|
if (ID.Kind == ValID::t_LocalID)
|
|
|
|
V = PFS.GetVal(ID.UIntVal, Ty, ID.Loc);
|
|
|
|
else if (ID.Kind == ValID::t_LocalName)
|
|
|
|
V = PFS.GetVal(ID.StrVal, Ty, ID.Loc);
|
2009-01-05 18:48:47 +00:00
|
|
|
else if (ID.Kind == ValID::t_InlineAsm) {
|
2009-01-02 07:01:27 +00:00
|
|
|
const PointerType *PTy = dyn_cast<PointerType>(Ty);
|
|
|
|
const FunctionType *FTy =
|
|
|
|
PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
|
|
|
|
if (!FTy || !InlineAsm::Verify(FTy, ID.StrVal2))
|
|
|
|
return Error(ID.Loc, "invalid type for inline asm constraint string");
|
|
|
|
V = InlineAsm::get(FTy, ID.StrVal, ID.StrVal2, ID.UIntVal);
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
Constant *C;
|
|
|
|
if (ConvertGlobalValIDToValue(Ty, ID, C)) return true;
|
|
|
|
V = C;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return V == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool LLParser::ParseValue(const Type *Ty, Value *&V, PerFunctionState &PFS) {
|
|
|
|
V = 0;
|
|
|
|
ValID ID;
|
2009-01-02 08:05:26 +00:00
|
|
|
return ParseValID(ID) ||
|
|
|
|
ConvertValIDToValue(Ty, ID, V, PFS);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState &PFS) {
|
|
|
|
PATypeHolder T(Type::VoidTy);
|
2009-01-02 08:05:26 +00:00
|
|
|
return ParseType(T) ||
|
|
|
|
ParseValue(T, V, PFS);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// FunctionHeader
|
|
|
|
/// ::= OptionalLinkage OptionalVisibility OptionalCallingConv OptRetAttrs
|
|
|
|
/// Type GlobalName '(' ArgList ')' OptFuncAttrs OptSection
|
|
|
|
/// OptionalAlign OptGC
|
|
|
|
bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
|
|
|
// Parse the linkage.
|
|
|
|
LocTy LinkageLoc = Lex.getLoc();
|
|
|
|
unsigned Linkage;
|
|
|
|
|
|
|
|
unsigned Visibility, CC, RetAttrs;
|
|
|
|
PATypeHolder RetType(Type::VoidTy);
|
|
|
|
LocTy RetTypeLoc = Lex.getLoc();
|
|
|
|
if (ParseOptionalLinkage(Linkage) ||
|
|
|
|
ParseOptionalVisibility(Visibility) ||
|
|
|
|
ParseOptionalCallingConv(CC) ||
|
|
|
|
ParseOptionalAttrs(RetAttrs, 1) ||
|
2009-03-09 04:49:14 +00:00
|
|
|
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// Verify that the linkage is ok.
|
|
|
|
switch ((GlobalValue::LinkageTypes)Linkage) {
|
|
|
|
case GlobalValue::ExternalLinkage:
|
|
|
|
break; // always ok.
|
|
|
|
case GlobalValue::DLLImportLinkage:
|
2009-03-11 08:08:06 +00:00
|
|
|
case GlobalValue::ExternalWeakLinkage:
|
2009-01-02 07:01:27 +00:00
|
|
|
if (isDefine)
|
|
|
|
return Error(LinkageLoc, "invalid linkage for function definition");
|
|
|
|
break;
|
2009-01-15 20:18:42 +00:00
|
|
|
case GlobalValue::PrivateLinkage:
|
2009-01-02 07:01:27 +00:00
|
|
|
case GlobalValue::InternalLinkage:
|
2009-04-13 07:02:02 +00:00
|
|
|
case GlobalValue::AvailableExternallyLinkage:
|
Introduce new linkage types linkonce_odr, weak_odr, common_odr
and extern_weak_odr. These are the same as the non-odr versions,
except that they indicate that the global will only be overridden
by an *equivalent* global. In C, a function with weak linkage can
be overridden by a function which behaves completely differently.
This means that IP passes have to skip weak functions, since any
deductions made from the function definition might be wrong, since
the definition could be replaced by something completely different
at link time. This is not allowed in C++, thanks to the ODR
(One-Definition-Rule): if a function is replaced by another at
link-time, then the new function must be the same as the original
function. If a language knows that a function or other global can
only be overridden by an equivalent global, it can give it the
weak_odr linkage type, and the optimizers will understand that it
is alright to make deductions based on the function body. The
code generators on the other hand map weak and weak_odr linkage
to the same thing.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66339 91177308-0d34-0410-b5e6-96231b3b80d8
2009-03-07 15:45:40 +00:00
|
|
|
case GlobalValue::LinkOnceAnyLinkage:
|
|
|
|
case GlobalValue::LinkOnceODRLinkage:
|
|
|
|
case GlobalValue::WeakAnyLinkage:
|
|
|
|
case GlobalValue::WeakODRLinkage:
|
2009-01-02 07:01:27 +00:00
|
|
|
case GlobalValue::DLLExportLinkage:
|
|
|
|
if (!isDefine)
|
|
|
|
return Error(LinkageLoc, "invalid linkage for function declaration");
|
|
|
|
break;
|
|
|
|
case GlobalValue::AppendingLinkage:
|
|
|
|
case GlobalValue::GhostLinkage:
|
2009-03-11 20:14:15 +00:00
|
|
|
case GlobalValue::CommonLinkage:
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(LinkageLoc, "invalid function linkage type");
|
|
|
|
}
|
|
|
|
|
2009-01-05 08:00:30 +00:00
|
|
|
if (!FunctionType::isValidReturnType(RetType) ||
|
|
|
|
isa<OpaqueType>(RetType))
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(RetTypeLoc, "invalid function return type");
|
|
|
|
|
2009-02-18 21:48:13 +00:00
|
|
|
LocTy NameLoc = Lex.getLoc();
|
|
|
|
|
|
|
|
std::string FunctionName;
|
|
|
|
if (Lex.getKind() == lltok::GlobalVar) {
|
|
|
|
FunctionName = Lex.getStrVal();
|
|
|
|
} else if (Lex.getKind() == lltok::GlobalID) { // @42 is ok.
|
|
|
|
unsigned NameID = Lex.getUIntVal();
|
|
|
|
|
|
|
|
if (NameID != NumberedVals.size())
|
|
|
|
return TokError("function expected to be numbered '%" +
|
|
|
|
utostr(NumberedVals.size()) + "'");
|
|
|
|
} else {
|
2009-01-02 07:01:27 +00:00
|
|
|
return TokError("expected function name");
|
2009-02-18 21:48:13 +00:00
|
|
|
}
|
2009-01-02 07:01:27 +00:00
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
Lex.Lex();
|
2009-01-02 07:01:27 +00:00
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (Lex.getKind() != lltok::lparen)
|
2009-01-02 07:01:27 +00:00
|
|
|
return TokError("expected '(' in function argument list");
|
|
|
|
|
|
|
|
std::vector<ArgInfo> ArgList;
|
|
|
|
bool isVarArg;
|
|
|
|
unsigned FuncAttrs;
|
|
|
|
std::string Section;
|
|
|
|
unsigned Alignment;
|
2009-01-02 08:05:26 +00:00
|
|
|
std::string GC;
|
|
|
|
|
2009-01-05 18:34:07 +00:00
|
|
|
if (ParseArgumentList(ArgList, isVarArg, false) ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseOptionalAttrs(FuncAttrs, 2) ||
|
|
|
|
(EatIfPresent(lltok::kw_section) &&
|
|
|
|
ParseStringConstant(Section)) ||
|
|
|
|
ParseOptionalAlignment(Alignment) ||
|
|
|
|
(EatIfPresent(lltok::kw_gc) &&
|
|
|
|
ParseStringConstant(GC)))
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
// If the alignment was parsed as an attribute, move to the alignment field.
|
|
|
|
if (FuncAttrs & Attribute::Alignment) {
|
|
|
|
Alignment = Attribute::getAlignmentFromAttrs(FuncAttrs);
|
|
|
|
FuncAttrs &= ~Attribute::Alignment;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Okay, if we got here, the function is syntactically valid. Convert types
|
|
|
|
// and do semantic checks.
|
|
|
|
std::vector<const Type*> ParamTypeList;
|
|
|
|
SmallVector<AttributeWithIndex, 8> Attrs;
|
|
|
|
// FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
|
|
|
// attributes.
|
|
|
|
unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg;
|
|
|
|
if (FuncAttrs & ObsoleteFuncAttrs) {
|
|
|
|
RetAttrs |= FuncAttrs & ObsoleteFuncAttrs;
|
|
|
|
FuncAttrs &= ~ObsoleteFuncAttrs;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
if (ArgList[i].Attrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (FuncAttrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs));
|
|
|
|
|
|
|
|
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
|
|
|
|
2009-03-09 04:49:14 +00:00
|
|
|
if (PAL.paramHasAttr(1, Attribute::StructRet) &&
|
|
|
|
RetType != Type::VoidTy)
|
|
|
|
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
const FunctionType *FT =
|
|
|
|
Context.getFunctionType(RetType, ParamTypeList, isVarArg);
|
|
|
|
const PointerType *PFT = Context.getPointerTypeUnqual(FT);
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
Fn = 0;
|
|
|
|
if (!FunctionName.empty()) {
|
|
|
|
// If this was a definition of a forward reference, remove the definition
|
|
|
|
// from the forward reference table and fill in the forward ref.
|
|
|
|
std::map<std::string, std::pair<GlobalValue*, LocTy> >::iterator FRVI =
|
|
|
|
ForwardRefVals.find(FunctionName);
|
|
|
|
if (FRVI != ForwardRefVals.end()) {
|
|
|
|
Fn = M->getFunction(FunctionName);
|
|
|
|
ForwardRefVals.erase(FRVI);
|
|
|
|
} else if ((Fn = M->getFunction(FunctionName))) {
|
|
|
|
// If this function already exists in the symbol table, then it is
|
|
|
|
// multiply defined. We accept a few cases for old backwards compat.
|
|
|
|
// FIXME: Remove this stuff for LLVM 3.0.
|
|
|
|
if (Fn->getType() != PFT || Fn->getAttributes() != PAL ||
|
|
|
|
(!Fn->isDeclaration() && isDefine)) {
|
|
|
|
// If the redefinition has different type or different attributes,
|
|
|
|
// reject it. If both have bodies, reject it.
|
|
|
|
return Error(NameLoc, "invalid redefinition of function '" +
|
|
|
|
FunctionName + "'");
|
|
|
|
} else if (Fn->isDeclaration()) {
|
|
|
|
// Make sure to strip off any argument names so we can't get conflicts.
|
|
|
|
for (Function::arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end();
|
|
|
|
AI != AE; ++AI)
|
|
|
|
AI->setName("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (FunctionName.empty()) {
|
|
|
|
// If this is a definition of a forward referenced function, make sure the
|
|
|
|
// types agree.
|
|
|
|
std::map<unsigned, std::pair<GlobalValue*, LocTy> >::iterator I
|
|
|
|
= ForwardRefValIDs.find(NumberedVals.size());
|
|
|
|
if (I != ForwardRefValIDs.end()) {
|
|
|
|
Fn = cast<Function>(I->second.first);
|
|
|
|
if (Fn->getType() != PFT)
|
|
|
|
return Error(NameLoc, "type of definition and forward reference of '@" +
|
|
|
|
utostr(NumberedVals.size()) +"' disagree");
|
|
|
|
ForwardRefValIDs.erase(I);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Fn == 0)
|
|
|
|
Fn = Function::Create(FT, GlobalValue::ExternalLinkage, FunctionName, M);
|
|
|
|
else // Move the forward-reference to the correct spot in the module.
|
|
|
|
M->getFunctionList().splice(M->end(), M->getFunctionList(), Fn);
|
|
|
|
|
|
|
|
if (FunctionName.empty())
|
|
|
|
NumberedVals.push_back(Fn);
|
|
|
|
|
|
|
|
Fn->setLinkage((GlobalValue::LinkageTypes)Linkage);
|
|
|
|
Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
|
|
|
|
Fn->setCallingConv(CC);
|
|
|
|
Fn->setAttributes(PAL);
|
|
|
|
Fn->setAlignment(Alignment);
|
|
|
|
Fn->setSection(Section);
|
|
|
|
if (!GC.empty()) Fn->setGC(GC.c_str());
|
|
|
|
|
|
|
|
// Add all of the arguments we parsed to the function.
|
|
|
|
Function::arg_iterator ArgIt = Fn->arg_begin();
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
|
|
|
|
// If the argument has a name, insert it into the argument symbol table.
|
|
|
|
if (ArgList[i].Name.empty()) continue;
|
|
|
|
|
|
|
|
// Set the name, if it conflicted, it will be auto-renamed.
|
|
|
|
ArgIt->setName(ArgList[i].Name);
|
|
|
|
|
|
|
|
if (ArgIt->getNameStr() != ArgList[i].Name)
|
|
|
|
return Error(ArgList[i].Loc, "redefinition of argument '%" +
|
|
|
|
ArgList[i].Name + "'");
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ParseFunctionBody
|
|
|
|
/// ::= '{' BasicBlock+ '}'
|
|
|
|
/// ::= 'begin' BasicBlock+ 'end' // FIXME: remove in LLVM 3.0
|
|
|
|
///
|
|
|
|
bool LLParser::ParseFunctionBody(Function &Fn) {
|
|
|
|
if (Lex.getKind() != lltok::lbrace && Lex.getKind() != lltok::kw_begin)
|
|
|
|
return TokError("expected '{' in function body");
|
|
|
|
Lex.Lex(); // eat the {.
|
|
|
|
|
|
|
|
PerFunctionState PFS(*this, Fn);
|
|
|
|
|
|
|
|
while (Lex.getKind() != lltok::rbrace && Lex.getKind() != lltok::kw_end)
|
|
|
|
if (ParseBasicBlock(PFS)) return true;
|
|
|
|
|
|
|
|
// Eat the }.
|
|
|
|
Lex.Lex();
|
|
|
|
|
|
|
|
// Verify function is ok.
|
|
|
|
return PFS.VerifyFunctionComplete();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseBasicBlock
|
|
|
|
/// ::= LabelStr? Instruction*
|
|
|
|
bool LLParser::ParseBasicBlock(PerFunctionState &PFS) {
|
|
|
|
// If this basic block starts out with a name, remember it.
|
|
|
|
std::string Name;
|
|
|
|
LocTy NameLoc = Lex.getLoc();
|
|
|
|
if (Lex.getKind() == lltok::LabelStr) {
|
|
|
|
Name = Lex.getStrVal();
|
|
|
|
Lex.Lex();
|
|
|
|
}
|
|
|
|
|
|
|
|
BasicBlock *BB = PFS.DefineBB(Name, NameLoc);
|
|
|
|
if (BB == 0) return true;
|
|
|
|
|
|
|
|
std::string NameStr;
|
|
|
|
|
|
|
|
// Parse the instructions in this block until we get a terminator.
|
|
|
|
Instruction *Inst;
|
|
|
|
do {
|
|
|
|
// This instruction may have three possibilities for a name: a) none
|
|
|
|
// specified, b) name specified "%foo =", c) number specified: "%4 =".
|
|
|
|
LocTy NameLoc = Lex.getLoc();
|
|
|
|
int NameID = -1;
|
|
|
|
NameStr = "";
|
|
|
|
|
|
|
|
if (Lex.getKind() == lltok::LocalVarID) {
|
|
|
|
NameID = Lex.getUIntVal();
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::equal, "expected '=' after instruction id"))
|
|
|
|
return true;
|
|
|
|
} else if (Lex.getKind() == lltok::LocalVar ||
|
|
|
|
// FIXME: REMOVE IN LLVM 3.0
|
|
|
|
Lex.getKind() == lltok::StringConstant) {
|
|
|
|
NameStr = Lex.getStrVal();
|
|
|
|
Lex.Lex();
|
|
|
|
if (ParseToken(lltok::equal, "expected '=' after instruction name"))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ParseInstruction(Inst, BB, PFS)) return true;
|
|
|
|
|
|
|
|
BB->getInstList().push_back(Inst);
|
|
|
|
|
|
|
|
// Set the name on the instruction.
|
|
|
|
if (PFS.SetInstName(NameID, NameStr, NameLoc, Inst)) return true;
|
|
|
|
} while (!isa<TerminatorInst>(Inst));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Instruction Parsing.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseInstruction - Parse one of the many different instructions.
|
|
|
|
///
|
|
|
|
bool LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
|
|
|
|
PerFunctionState &PFS) {
|
|
|
|
lltok::Kind Token = Lex.getKind();
|
|
|
|
if (Token == lltok::Eof)
|
|
|
|
return TokError("found end of file when expecting more instructions");
|
|
|
|
LocTy Loc = Lex.getLoc();
|
2009-03-01 00:53:13 +00:00
|
|
|
unsigned KeywordVal = Lex.getUIntVal();
|
2009-01-02 07:01:27 +00:00
|
|
|
Lex.Lex(); // Eat the keyword.
|
|
|
|
|
|
|
|
switch (Token) {
|
|
|
|
default: return Error(Loc, "expected instruction opcode");
|
|
|
|
// Terminator Instructions.
|
|
|
|
case lltok::kw_unwind: Inst = new UnwindInst(); return false;
|
|
|
|
case lltok::kw_unreachable: Inst = new UnreachableInst(); return false;
|
|
|
|
case lltok::kw_ret: return ParseRet(Inst, BB, PFS);
|
|
|
|
case lltok::kw_br: return ParseBr(Inst, PFS);
|
|
|
|
case lltok::kw_switch: return ParseSwitch(Inst, PFS);
|
|
|
|
case lltok::kw_invoke: return ParseInvoke(Inst, PFS);
|
|
|
|
// Binary Operators.
|
|
|
|
case lltok::kw_add:
|
|
|
|
case lltok::kw_sub:
|
2009-06-04 22:49:04 +00:00
|
|
|
case lltok::kw_mul:
|
|
|
|
// API compatibility: Accept either integer or floating-point types.
|
|
|
|
return ParseArithmetic(Inst, PFS, KeywordVal, 0);
|
|
|
|
case lltok::kw_fadd:
|
|
|
|
case lltok::kw_fsub:
|
|
|
|
case lltok::kw_fmul: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
|
|
|
|
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_udiv:
|
|
|
|
case lltok::kw_sdiv:
|
|
|
|
case lltok::kw_urem:
|
2009-03-01 00:53:13 +00:00
|
|
|
case lltok::kw_srem: return ParseArithmetic(Inst, PFS, KeywordVal, 1);
|
2009-01-05 08:24:46 +00:00
|
|
|
case lltok::kw_fdiv:
|
2009-03-01 00:53:13 +00:00
|
|
|
case lltok::kw_frem: return ParseArithmetic(Inst, PFS, KeywordVal, 2);
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_shl:
|
|
|
|
case lltok::kw_lshr:
|
|
|
|
case lltok::kw_ashr:
|
|
|
|
case lltok::kw_and:
|
|
|
|
case lltok::kw_or:
|
2009-03-01 00:53:13 +00:00
|
|
|
case lltok::kw_xor: return ParseLogical(Inst, PFS, KeywordVal);
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_icmp:
|
|
|
|
case lltok::kw_fcmp:
|
|
|
|
case lltok::kw_vicmp:
|
2009-03-01 00:53:13 +00:00
|
|
|
case lltok::kw_vfcmp: return ParseCompare(Inst, PFS, KeywordVal);
|
2009-01-02 07:01:27 +00:00
|
|
|
// Casts.
|
|
|
|
case lltok::kw_trunc:
|
|
|
|
case lltok::kw_zext:
|
|
|
|
case lltok::kw_sext:
|
|
|
|
case lltok::kw_fptrunc:
|
|
|
|
case lltok::kw_fpext:
|
|
|
|
case lltok::kw_bitcast:
|
|
|
|
case lltok::kw_uitofp:
|
|
|
|
case lltok::kw_sitofp:
|
|
|
|
case lltok::kw_fptoui:
|
|
|
|
case lltok::kw_fptosi:
|
|
|
|
case lltok::kw_inttoptr:
|
2009-03-01 00:53:13 +00:00
|
|
|
case lltok::kw_ptrtoint: return ParseCast(Inst, PFS, KeywordVal);
|
2009-01-02 07:01:27 +00:00
|
|
|
// Other.
|
|
|
|
case lltok::kw_select: return ParseSelect(Inst, PFS);
|
2009-01-05 08:18:44 +00:00
|
|
|
case lltok::kw_va_arg: return ParseVA_Arg(Inst, PFS);
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_extractelement: return ParseExtractElement(Inst, PFS);
|
|
|
|
case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS);
|
|
|
|
case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS);
|
|
|
|
case lltok::kw_phi: return ParsePHI(Inst, PFS);
|
|
|
|
case lltok::kw_call: return ParseCall(Inst, PFS, false);
|
|
|
|
case lltok::kw_tail: return ParseCall(Inst, PFS, true);
|
|
|
|
// Memory.
|
|
|
|
case lltok::kw_alloca:
|
2009-03-01 00:53:13 +00:00
|
|
|
case lltok::kw_malloc: return ParseAlloc(Inst, PFS, KeywordVal);
|
2009-01-02 07:01:27 +00:00
|
|
|
case lltok::kw_free: return ParseFree(Inst, PFS);
|
|
|
|
case lltok::kw_load: return ParseLoad(Inst, PFS, false);
|
|
|
|
case lltok::kw_store: return ParseStore(Inst, PFS, false);
|
|
|
|
case lltok::kw_volatile:
|
2009-01-02 08:05:26 +00:00
|
|
|
if (EatIfPresent(lltok::kw_load))
|
2009-01-02 07:01:27 +00:00
|
|
|
return ParseLoad(Inst, PFS, true);
|
2009-01-02 08:05:26 +00:00
|
|
|
else if (EatIfPresent(lltok::kw_store))
|
2009-01-02 07:01:27 +00:00
|
|
|
return ParseStore(Inst, PFS, true);
|
2009-01-02 08:05:26 +00:00
|
|
|
else
|
2009-01-02 07:01:27 +00:00
|
|
|
return TokError("expected 'load' or 'store'");
|
|
|
|
case lltok::kw_getresult: return ParseGetResult(Inst, PFS);
|
|
|
|
case lltok::kw_getelementptr: return ParseGetElementPtr(Inst, PFS);
|
|
|
|
case lltok::kw_extractvalue: return ParseExtractValue(Inst, PFS);
|
|
|
|
case lltok::kw_insertvalue: return ParseInsertValue(Inst, PFS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseCmpPredicate - Parse an integer or fp predicate, based on Kind.
|
|
|
|
bool LLParser::ParseCmpPredicate(unsigned &P, unsigned Opc) {
|
|
|
|
// FIXME: REMOVE vicmp/vfcmp!
|
|
|
|
if (Opc == Instruction::FCmp || Opc == Instruction::VFCmp) {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default: TokError("expected fcmp predicate (e.g. 'oeq')");
|
|
|
|
case lltok::kw_oeq: P = CmpInst::FCMP_OEQ; break;
|
|
|
|
case lltok::kw_one: P = CmpInst::FCMP_ONE; break;
|
|
|
|
case lltok::kw_olt: P = CmpInst::FCMP_OLT; break;
|
|
|
|
case lltok::kw_ogt: P = CmpInst::FCMP_OGT; break;
|
|
|
|
case lltok::kw_ole: P = CmpInst::FCMP_OLE; break;
|
|
|
|
case lltok::kw_oge: P = CmpInst::FCMP_OGE; break;
|
|
|
|
case lltok::kw_ord: P = CmpInst::FCMP_ORD; break;
|
|
|
|
case lltok::kw_uno: P = CmpInst::FCMP_UNO; break;
|
|
|
|
case lltok::kw_ueq: P = CmpInst::FCMP_UEQ; break;
|
|
|
|
case lltok::kw_une: P = CmpInst::FCMP_UNE; break;
|
|
|
|
case lltok::kw_ult: P = CmpInst::FCMP_ULT; break;
|
|
|
|
case lltok::kw_ugt: P = CmpInst::FCMP_UGT; break;
|
|
|
|
case lltok::kw_ule: P = CmpInst::FCMP_ULE; break;
|
|
|
|
case lltok::kw_uge: P = CmpInst::FCMP_UGE; break;
|
|
|
|
case lltok::kw_true: P = CmpInst::FCMP_TRUE; break;
|
|
|
|
case lltok::kw_false: P = CmpInst::FCMP_FALSE; break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch (Lex.getKind()) {
|
|
|
|
default: TokError("expected icmp predicate (e.g. 'eq')");
|
|
|
|
case lltok::kw_eq: P = CmpInst::ICMP_EQ; break;
|
|
|
|
case lltok::kw_ne: P = CmpInst::ICMP_NE; break;
|
|
|
|
case lltok::kw_slt: P = CmpInst::ICMP_SLT; break;
|
|
|
|
case lltok::kw_sgt: P = CmpInst::ICMP_SGT; break;
|
|
|
|
case lltok::kw_sle: P = CmpInst::ICMP_SLE; break;
|
|
|
|
case lltok::kw_sge: P = CmpInst::ICMP_SGE; break;
|
|
|
|
case lltok::kw_ult: P = CmpInst::ICMP_ULT; break;
|
|
|
|
case lltok::kw_ugt: P = CmpInst::ICMP_UGT; break;
|
|
|
|
case lltok::kw_ule: P = CmpInst::ICMP_ULE; break;
|
|
|
|
case lltok::kw_uge: P = CmpInst::ICMP_UGE; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Lex.Lex();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Terminator Instructions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseRet - Parse a return instruction.
|
|
|
|
/// ::= 'ret' void
|
|
|
|
/// ::= 'ret' TypeAndValue
|
|
|
|
/// ::= 'ret' TypeAndValue (',' TypeAndValue)+ [[obsolete: LLVM 3.0]]
|
|
|
|
bool LLParser::ParseRet(Instruction *&Inst, BasicBlock *BB,
|
|
|
|
PerFunctionState &PFS) {
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
2009-03-09 04:49:14 +00:00
|
|
|
if (ParseType(Ty, true /*void allowed*/)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
if (Ty == Type::VoidTy) {
|
|
|
|
Inst = ReturnInst::Create();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value *RV;
|
|
|
|
if (ParseValue(Ty, RV, PFS)) return true;
|
|
|
|
|
|
|
|
// The normal case is one return value.
|
|
|
|
if (Lex.getKind() == lltok::comma) {
|
|
|
|
// FIXME: LLVM 3.0 remove MRV support for 'ret i32 1, i32 2', requiring use
|
|
|
|
// of 'ret {i32,i32} {i32 1, i32 2}'
|
|
|
|
SmallVector<Value*, 8> RVs;
|
|
|
|
RVs.push_back(RV);
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseTypeAndValue(RV, PFS)) return true;
|
|
|
|
RVs.push_back(RV);
|
|
|
|
}
|
|
|
|
|
2009-07-02 17:04:01 +00:00
|
|
|
RV = Context.getUndef(PFS.getFunction().getReturnType());
|
2009-01-02 07:01:27 +00:00
|
|
|
for (unsigned i = 0, e = RVs.size(); i != e; ++i) {
|
|
|
|
Instruction *I = InsertValueInst::Create(RV, RVs[i], i, "mrv");
|
|
|
|
BB->getInstList().push_back(I);
|
|
|
|
RV = I;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Inst = ReturnInst::Create(RV);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ParseBr
|
|
|
|
/// ::= 'br' TypeAndValue
|
|
|
|
/// ::= 'br' TypeAndValue ',' TypeAndValue ',' TypeAndValue
|
|
|
|
bool LLParser::ParseBr(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy Loc, Loc2;
|
|
|
|
Value *Op0, *Op1, *Op2;
|
|
|
|
if (ParseTypeAndValue(Op0, Loc, PFS)) return true;
|
|
|
|
|
|
|
|
if (BasicBlock *BB = dyn_cast<BasicBlock>(Op0)) {
|
|
|
|
Inst = BranchInst::Create(BB);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Op0->getType() != Type::Int1Ty)
|
|
|
|
return Error(Loc, "branch condition must have 'i1' type");
|
|
|
|
|
|
|
|
if (ParseToken(lltok::comma, "expected ',' after branch condition") ||
|
|
|
|
ParseTypeAndValue(Op1, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after true destination") ||
|
|
|
|
ParseTypeAndValue(Op2, Loc2, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<BasicBlock>(Op1))
|
|
|
|
return Error(Loc, "true destination of branch must be a basic block");
|
|
|
|
if (!isa<BasicBlock>(Op2))
|
|
|
|
return Error(Loc2, "true destination of branch must be a basic block");
|
|
|
|
|
|
|
|
Inst = BranchInst::Create(cast<BasicBlock>(Op1), cast<BasicBlock>(Op2), Op0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseSwitch
|
|
|
|
/// Instruction
|
|
|
|
/// ::= 'switch' TypeAndValue ',' TypeAndValue '[' JumpTable ']'
|
|
|
|
/// JumpTable
|
|
|
|
/// ::= (TypeAndValue ',' TypeAndValue)*
|
|
|
|
bool LLParser::ParseSwitch(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy CondLoc, BBLoc;
|
|
|
|
Value *Cond, *DefaultBB;
|
|
|
|
if (ParseTypeAndValue(Cond, CondLoc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after switch condition") ||
|
|
|
|
ParseTypeAndValue(DefaultBB, BBLoc, PFS) ||
|
|
|
|
ParseToken(lltok::lsquare, "expected '[' with switch table"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<IntegerType>(Cond->getType()))
|
|
|
|
return Error(CondLoc, "switch condition must have integer type");
|
|
|
|
if (!isa<BasicBlock>(DefaultBB))
|
|
|
|
return Error(BBLoc, "default destination must be a basic block");
|
|
|
|
|
|
|
|
// Parse the jump table pairs.
|
|
|
|
SmallPtrSet<Value*, 32> SeenCases;
|
|
|
|
SmallVector<std::pair<ConstantInt*, BasicBlock*>, 32> Table;
|
|
|
|
while (Lex.getKind() != lltok::rsquare) {
|
|
|
|
Value *Constant, *DestBB;
|
|
|
|
|
|
|
|
if (ParseTypeAndValue(Constant, CondLoc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after case value") ||
|
|
|
|
ParseTypeAndValue(DestBB, BBLoc, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!SeenCases.insert(Constant))
|
|
|
|
return Error(CondLoc, "duplicate case value in switch");
|
|
|
|
if (!isa<ConstantInt>(Constant))
|
|
|
|
return Error(CondLoc, "case value is not a constant integer");
|
|
|
|
if (!isa<BasicBlock>(DestBB))
|
|
|
|
return Error(BBLoc, "case destination is not a basic block");
|
|
|
|
|
|
|
|
Table.push_back(std::make_pair(cast<ConstantInt>(Constant),
|
|
|
|
cast<BasicBlock>(DestBB)));
|
|
|
|
}
|
|
|
|
|
|
|
|
Lex.Lex(); // Eat the ']'.
|
|
|
|
|
|
|
|
SwitchInst *SI = SwitchInst::Create(Cond, cast<BasicBlock>(DefaultBB),
|
|
|
|
Table.size());
|
|
|
|
for (unsigned i = 0, e = Table.size(); i != e; ++i)
|
|
|
|
SI->addCase(Table[i].first, Table[i].second);
|
|
|
|
Inst = SI;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseInvoke
|
|
|
|
/// ::= 'invoke' OptionalCallingConv OptionalAttrs Type Value ParamList
|
|
|
|
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
|
|
|
|
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy CallLoc = Lex.getLoc();
|
|
|
|
unsigned CC, RetAttrs, FnAttrs;
|
|
|
|
PATypeHolder RetType(Type::VoidTy);
|
|
|
|
LocTy RetTypeLoc;
|
|
|
|
ValID CalleeID;
|
|
|
|
SmallVector<ParamInfo, 16> ArgList;
|
|
|
|
|
|
|
|
Value *NormalBB, *UnwindBB;
|
|
|
|
if (ParseOptionalCallingConv(CC) ||
|
|
|
|
ParseOptionalAttrs(RetAttrs, 1) ||
|
2009-03-09 04:49:14 +00:00
|
|
|
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
|
2009-01-02 07:01:27 +00:00
|
|
|
ParseValID(CalleeID) ||
|
|
|
|
ParseParameterList(ArgList, PFS) ||
|
|
|
|
ParseOptionalAttrs(FnAttrs, 2) ||
|
|
|
|
ParseToken(lltok::kw_to, "expected 'to' in invoke") ||
|
|
|
|
ParseTypeAndValue(NormalBB, PFS) ||
|
|
|
|
ParseToken(lltok::kw_unwind, "expected 'unwind' in invoke") ||
|
|
|
|
ParseTypeAndValue(UnwindBB, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<BasicBlock>(NormalBB))
|
|
|
|
return Error(CallLoc, "normal destination is not a basic block");
|
|
|
|
if (!isa<BasicBlock>(UnwindBB))
|
|
|
|
return Error(CallLoc, "unwind destination is not a basic block");
|
|
|
|
|
|
|
|
// If RetType is a non-function pointer type, then this is the short syntax
|
|
|
|
// for the call, which means that RetType is just the return type. Infer the
|
|
|
|
// rest of the function argument types from the arguments that are present.
|
|
|
|
const PointerType *PFTy = 0;
|
|
|
|
const FunctionType *Ty = 0;
|
|
|
|
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;
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
|
|
|
|
ParamTypes.push_back(ArgList[i].V->getType());
|
|
|
|
|
|
|
|
if (!FunctionType::isValidReturnType(RetType))
|
|
|
|
return Error(RetTypeLoc, "Invalid result type for LLVM function");
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
Ty = Context.getFunctionType(RetType, ParamTypes, false);
|
|
|
|
PFTy = Context.getPointerTypeUnqual(Ty);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Look up the callee.
|
|
|
|
Value *Callee;
|
|
|
|
if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
|
|
|
|
|
|
|
|
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
|
|
|
|
// function attributes.
|
|
|
|
unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg;
|
|
|
|
if (FnAttrs & ObsoleteFuncAttrs) {
|
|
|
|
RetAttrs |= FnAttrs & ObsoleteFuncAttrs;
|
|
|
|
FnAttrs &= ~ObsoleteFuncAttrs;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set up the Attributes for the function.
|
|
|
|
SmallVector<AttributeWithIndex, 8> Attrs;
|
|
|
|
if (RetAttrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
|
|
|
|
|
|
|
SmallVector<Value*, 8> Args;
|
|
|
|
|
|
|
|
// Loop through FunctionType's arguments and ensure they are specified
|
|
|
|
// correctly. Also, gather any parameter attributes.
|
|
|
|
FunctionType::param_iterator I = Ty->param_begin();
|
|
|
|
FunctionType::param_iterator E = Ty->param_end();
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
|
|
|
const Type *ExpectedTy = 0;
|
|
|
|
if (I != E) {
|
|
|
|
ExpectedTy = *I++;
|
|
|
|
} else if (!Ty->isVarArg()) {
|
|
|
|
return Error(ArgList[i].Loc, "too many arguments specified");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ExpectedTy && ExpectedTy != ArgList[i].V->getType())
|
|
|
|
return Error(ArgList[i].Loc, "argument is not of expected type '" +
|
|
|
|
ExpectedTy->getDescription() + "'");
|
|
|
|
Args.push_back(ArgList[i].V);
|
|
|
|
if (ArgList[i].Attrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (I != E)
|
|
|
|
return Error(CallLoc, "not enough parameters specified for call");
|
|
|
|
|
|
|
|
if (FnAttrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
|
|
|
|
|
|
|
|
// Finish off the Attributes and check them
|
|
|
|
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
|
|
|
|
|
|
|
InvokeInst *II = InvokeInst::Create(Callee, cast<BasicBlock>(NormalBB),
|
|
|
|
cast<BasicBlock>(UnwindBB),
|
|
|
|
Args.begin(), Args.end());
|
|
|
|
II->setCallingConv(CC);
|
|
|
|
II->setAttributes(PAL);
|
|
|
|
Inst = II;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Binary Operators.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseArithmetic
|
2009-01-05 08:24:46 +00:00
|
|
|
/// ::= ArithmeticOps TypeAndValue ',' Value
|
|
|
|
///
|
|
|
|
/// If OperandType is 0, then any FP or integer operand is allowed. If it is 1,
|
|
|
|
/// then any integer operand is allowed, if it is 2, any fp operand is allowed.
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseArithmetic(Instruction *&Inst, PerFunctionState &PFS,
|
2009-01-05 08:24:46 +00:00
|
|
|
unsigned Opc, unsigned OperandType) {
|
2009-01-02 07:01:27 +00:00
|
|
|
LocTy Loc; Value *LHS, *RHS;
|
|
|
|
if (ParseTypeAndValue(LHS, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' in arithmetic operation") ||
|
|
|
|
ParseValue(LHS->getType(), RHS, PFS))
|
|
|
|
return true;
|
|
|
|
|
2009-01-05 08:24:46 +00:00
|
|
|
bool Valid;
|
|
|
|
switch (OperandType) {
|
|
|
|
default: assert(0 && "Unknown operand type!");
|
|
|
|
case 0: // int or FP.
|
|
|
|
Valid = LHS->getType()->isIntOrIntVector() ||
|
|
|
|
LHS->getType()->isFPOrFPVector();
|
|
|
|
break;
|
|
|
|
case 1: Valid = LHS->getType()->isIntOrIntVector(); break;
|
|
|
|
case 2: Valid = LHS->getType()->isFPOrFPVector(); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Valid)
|
|
|
|
return Error(Loc, "invalid operand type for instruction");
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseLogical
|
|
|
|
/// ::= ArithmeticOps TypeAndValue ',' Value {
|
|
|
|
bool LLParser::ParseLogical(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
unsigned Opc) {
|
|
|
|
LocTy Loc; Value *LHS, *RHS;
|
|
|
|
if (ParseTypeAndValue(LHS, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' in logical operation") ||
|
|
|
|
ParseValue(LHS->getType(), RHS, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!LHS->getType()->isIntOrIntVector())
|
|
|
|
return Error(Loc,"instruction requires integer or integer vector operands");
|
|
|
|
|
|
|
|
Inst = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ParseCompare
|
|
|
|
/// ::= 'icmp' IPredicates TypeAndValue ',' Value
|
|
|
|
/// ::= 'fcmp' FPredicates TypeAndValue ',' Value
|
|
|
|
/// ::= 'vicmp' IPredicates TypeAndValue ',' Value
|
|
|
|
/// ::= 'vfcmp' FPredicates TypeAndValue ',' Value
|
|
|
|
bool LLParser::ParseCompare(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
unsigned Opc) {
|
|
|
|
// Parse the integer/fp comparison predicate.
|
|
|
|
LocTy Loc;
|
|
|
|
unsigned Pred;
|
|
|
|
Value *LHS, *RHS;
|
|
|
|
if (ParseCmpPredicate(Pred, Opc) ||
|
|
|
|
ParseTypeAndValue(LHS, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after compare value") ||
|
|
|
|
ParseValue(LHS->getType(), RHS, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (Opc == Instruction::FCmp) {
|
|
|
|
if (!LHS->getType()->isFPOrFPVector())
|
|
|
|
return Error(Loc, "fcmp requires floating point operands");
|
|
|
|
Inst = new FCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
|
|
|
|
} else if (Opc == Instruction::ICmp) {
|
|
|
|
if (!LHS->getType()->isIntOrIntVector() &&
|
|
|
|
!isa<PointerType>(LHS->getType()))
|
|
|
|
return Error(Loc, "icmp requires integer operands");
|
|
|
|
Inst = new ICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
|
|
|
|
} else if (Opc == Instruction::VFCmp) {
|
2009-01-05 08:09:48 +00:00
|
|
|
if (!LHS->getType()->isFPOrFPVector() || !isa<VectorType>(LHS->getType()))
|
|
|
|
return Error(Loc, "vfcmp requires vector floating point operands");
|
2009-01-02 07:01:27 +00:00
|
|
|
Inst = new VFCmpInst(CmpInst::Predicate(Pred), LHS, RHS);
|
|
|
|
} else if (Opc == Instruction::VICmp) {
|
2009-01-05 08:09:48 +00:00
|
|
|
if (!LHS->getType()->isIntOrIntVector() || !isa<VectorType>(LHS->getType()))
|
|
|
|
return Error(Loc, "vicmp requires vector floating point operands");
|
2009-01-02 07:01:27 +00:00
|
|
|
Inst = new VICmpInst(CmpInst::Predicate(Pred), LHS, RHS);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Other Instructions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
|
|
/// ParseCast
|
|
|
|
/// ::= CastOpc TypeAndValue 'to' Type
|
|
|
|
bool LLParser::ParseCast(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
unsigned Opc) {
|
|
|
|
LocTy Loc; Value *Op;
|
|
|
|
PATypeHolder DestTy(Type::VoidTy);
|
|
|
|
if (ParseTypeAndValue(Op, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::kw_to, "expected 'to' after cast value") ||
|
|
|
|
ParseType(DestTy))
|
|
|
|
return true;
|
|
|
|
|
2009-03-01 00:53:13 +00:00
|
|
|
if (!CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy)) {
|
|
|
|
CastInst::castIsValid((Instruction::CastOps)Opc, Op, DestTy);
|
2009-01-02 07:01:27 +00:00
|
|
|
return Error(Loc, "invalid cast opcode for cast from '" +
|
|
|
|
Op->getType()->getDescription() + "' to '" +
|
|
|
|
DestTy->getDescription() + "'");
|
2009-03-01 00:53:13 +00:00
|
|
|
}
|
2009-01-02 07:01:27 +00:00
|
|
|
Inst = CastInst::Create((Instruction::CastOps)Opc, Op, DestTy);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseSelect
|
|
|
|
/// ::= 'select' TypeAndValue ',' TypeAndValue ',' TypeAndValue
|
|
|
|
bool LLParser::ParseSelect(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy Loc;
|
|
|
|
Value *Op0, *Op1, *Op2;
|
|
|
|
if (ParseTypeAndValue(Op0, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after select condition") ||
|
|
|
|
ParseTypeAndValue(Op1, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after select value") ||
|
|
|
|
ParseTypeAndValue(Op2, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (const char *Reason = SelectInst::areInvalidOperands(Op0, Op1, Op2))
|
|
|
|
return Error(Loc, Reason);
|
|
|
|
|
|
|
|
Inst = SelectInst::Create(Op0, Op1, Op2);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-01-05 08:18:44 +00:00
|
|
|
/// ParseVA_Arg
|
|
|
|
/// ::= 'va_arg' TypeAndValue ',' Type
|
|
|
|
bool LLParser::ParseVA_Arg(Instruction *&Inst, PerFunctionState &PFS) {
|
2009-01-02 07:01:27 +00:00
|
|
|
Value *Op;
|
|
|
|
PATypeHolder EltTy(Type::VoidTy);
|
2009-01-05 08:18:44 +00:00
|
|
|
LocTy TypeLoc;
|
2009-01-02 07:01:27 +00:00
|
|
|
if (ParseTypeAndValue(Op, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after vaarg operand") ||
|
2009-01-05 08:18:44 +00:00
|
|
|
ParseType(EltTy, TypeLoc))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
2009-01-05 08:18:44 +00:00
|
|
|
|
|
|
|
if (!EltTy->isFirstClassType())
|
|
|
|
return Error(TypeLoc, "va_arg requires operand with first class type");
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
Inst = new VAArgInst(Op, EltTy);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseExtractElement
|
|
|
|
/// ::= 'extractelement' TypeAndValue ',' TypeAndValue
|
|
|
|
bool LLParser::ParseExtractElement(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy Loc;
|
|
|
|
Value *Op0, *Op1;
|
|
|
|
if (ParseTypeAndValue(Op0, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after extract value") ||
|
|
|
|
ParseTypeAndValue(Op1, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!ExtractElementInst::isValidOperands(Op0, Op1))
|
|
|
|
return Error(Loc, "invalid extractelement operands");
|
|
|
|
|
|
|
|
Inst = new ExtractElementInst(Op0, Op1);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseInsertElement
|
|
|
|
/// ::= 'insertelement' TypeAndValue ',' TypeAndValue ',' TypeAndValue
|
|
|
|
bool LLParser::ParseInsertElement(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy Loc;
|
|
|
|
Value *Op0, *Op1, *Op2;
|
|
|
|
if (ParseTypeAndValue(Op0, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after insertelement value") ||
|
|
|
|
ParseTypeAndValue(Op1, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after insertelement value") ||
|
|
|
|
ParseTypeAndValue(Op2, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!InsertElementInst::isValidOperands(Op0, Op1, Op2))
|
|
|
|
return Error(Loc, "invalid extractelement operands");
|
|
|
|
|
|
|
|
Inst = InsertElementInst::Create(Op0, Op1, Op2);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseShuffleVector
|
|
|
|
/// ::= 'shufflevector' TypeAndValue ',' TypeAndValue ',' TypeAndValue
|
|
|
|
bool LLParser::ParseShuffleVector(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
LocTy Loc;
|
|
|
|
Value *Op0, *Op1, *Op2;
|
|
|
|
if (ParseTypeAndValue(Op0, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after shuffle mask") ||
|
|
|
|
ParseTypeAndValue(Op1, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after shuffle value") ||
|
|
|
|
ParseTypeAndValue(Op2, PFS))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!ShuffleVectorInst::isValidOperands(Op0, Op1, Op2))
|
|
|
|
return Error(Loc, "invalid extractelement operands");
|
|
|
|
|
|
|
|
Inst = new ShuffleVectorInst(Op0, Op1, Op2);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParsePHI
|
|
|
|
/// ::= 'phi' Type '[' Value ',' Value ']' (',' '[' Value ',' Valueß ']')*
|
|
|
|
bool LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
|
|
|
Value *Op0, *Op1;
|
|
|
|
LocTy TypeLoc = Lex.getLoc();
|
|
|
|
|
|
|
|
if (ParseType(Ty) ||
|
|
|
|
ParseToken(lltok::lsquare, "expected '[' in phi value list") ||
|
|
|
|
ParseValue(Ty, Op0, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after insertelement value") ||
|
|
|
|
ParseValue(Type::LabelTy, Op1, PFS) ||
|
|
|
|
ParseToken(lltok::rsquare, "expected ']' in phi value list"))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
SmallVector<std::pair<Value*, BasicBlock*>, 16> PHIVals;
|
|
|
|
while (1) {
|
|
|
|
PHIVals.push_back(std::make_pair(Op0, cast<BasicBlock>(Op1)));
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (!EatIfPresent(lltok::comma))
|
2009-01-02 07:01:27 +00:00
|
|
|
break;
|
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseToken(lltok::lsquare, "expected '[' in phi value list") ||
|
2009-01-02 07:01:27 +00:00
|
|
|
ParseValue(Ty, Op0, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after insertelement value") ||
|
|
|
|
ParseValue(Type::LabelTy, Op1, PFS) ||
|
|
|
|
ParseToken(lltok::rsquare, "expected ']' in phi value list"))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Ty->isFirstClassType())
|
|
|
|
return Error(TypeLoc, "phi node must have first class type");
|
|
|
|
|
|
|
|
PHINode *PN = PHINode::Create(Ty);
|
|
|
|
PN->reserveOperandSpace(PHIVals.size());
|
|
|
|
for (unsigned i = 0, e = PHIVals.size(); i != e; ++i)
|
|
|
|
PN->addIncoming(PHIVals[i].first, PHIVals[i].second);
|
|
|
|
Inst = PN;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseCall
|
|
|
|
/// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value
|
|
|
|
/// ParameterList OptionalAttrs
|
|
|
|
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
bool isTail) {
|
|
|
|
unsigned CC, RetAttrs, FnAttrs;
|
|
|
|
PATypeHolder RetType(Type::VoidTy);
|
|
|
|
LocTy RetTypeLoc;
|
|
|
|
ValID CalleeID;
|
|
|
|
SmallVector<ParamInfo, 16> ArgList;
|
|
|
|
LocTy CallLoc = Lex.getLoc();
|
|
|
|
|
|
|
|
if ((isTail && ParseToken(lltok::kw_call, "expected 'tail call'")) ||
|
|
|
|
ParseOptionalCallingConv(CC) ||
|
|
|
|
ParseOptionalAttrs(RetAttrs, 1) ||
|
2009-03-09 04:49:14 +00:00
|
|
|
ParseType(RetType, RetTypeLoc, true /*void allowed*/) ||
|
2009-01-02 07:01:27 +00:00
|
|
|
ParseValID(CalleeID) ||
|
|
|
|
ParseParameterList(ArgList, PFS) ||
|
|
|
|
ParseOptionalAttrs(FnAttrs, 2))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// If RetType is a non-function pointer type, then this is the short syntax
|
|
|
|
// for the call, which means that RetType is just the return type. Infer the
|
|
|
|
// rest of the function argument types from the arguments that are present.
|
|
|
|
const PointerType *PFTy = 0;
|
|
|
|
const FunctionType *Ty = 0;
|
|
|
|
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;
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i)
|
|
|
|
ParamTypes.push_back(ArgList[i].V->getType());
|
|
|
|
|
|
|
|
if (!FunctionType::isValidReturnType(RetType))
|
|
|
|
return Error(RetTypeLoc, "Invalid result type for LLVM function");
|
|
|
|
|
2009-07-01 23:57:11 +00:00
|
|
|
Ty = Context.getFunctionType(RetType, ParamTypes, false);
|
|
|
|
PFTy = Context.getPointerTypeUnqual(Ty);
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Look up the callee.
|
|
|
|
Value *Callee;
|
|
|
|
if (ConvertValIDToValue(PFTy, CalleeID, Callee, PFS)) return true;
|
|
|
|
|
|
|
|
// FIXME: In LLVM 3.0, stop accepting zext, sext and inreg as optional
|
|
|
|
// function attributes.
|
|
|
|
unsigned ObsoleteFuncAttrs = Attribute::ZExt|Attribute::SExt|Attribute::InReg;
|
|
|
|
if (FnAttrs & ObsoleteFuncAttrs) {
|
|
|
|
RetAttrs |= FnAttrs & ObsoleteFuncAttrs;
|
|
|
|
FnAttrs &= ~ObsoleteFuncAttrs;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set up the Attributes for the function.
|
|
|
|
SmallVector<AttributeWithIndex, 8> Attrs;
|
|
|
|
if (RetAttrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
|
|
|
|
|
|
|
SmallVector<Value*, 8> Args;
|
|
|
|
|
|
|
|
// Loop through FunctionType's arguments and ensure they are specified
|
|
|
|
// correctly. Also, gather any parameter attributes.
|
|
|
|
FunctionType::param_iterator I = Ty->param_begin();
|
|
|
|
FunctionType::param_iterator E = Ty->param_end();
|
|
|
|
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
|
|
|
const Type *ExpectedTy = 0;
|
|
|
|
if (I != E) {
|
|
|
|
ExpectedTy = *I++;
|
|
|
|
} else if (!Ty->isVarArg()) {
|
|
|
|
return Error(ArgList[i].Loc, "too many arguments specified");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ExpectedTy && ExpectedTy != ArgList[i].V->getType())
|
|
|
|
return Error(ArgList[i].Loc, "argument is not of expected type '" +
|
|
|
|
ExpectedTy->getDescription() + "'");
|
|
|
|
Args.push_back(ArgList[i].V);
|
|
|
|
if (ArgList[i].Attrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(i+1, ArgList[i].Attrs));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (I != E)
|
|
|
|
return Error(CallLoc, "not enough parameters specified for call");
|
|
|
|
|
|
|
|
if (FnAttrs != Attribute::None)
|
|
|
|
Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs));
|
|
|
|
|
|
|
|
// Finish off the Attributes and check them
|
|
|
|
AttrListPtr PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
|
|
|
|
|
|
|
CallInst *CI = CallInst::Create(Callee, Args.begin(), Args.end());
|
|
|
|
CI->setTailCall(isTail);
|
|
|
|
CI->setCallingConv(CC);
|
|
|
|
CI->setAttributes(PAL);
|
|
|
|
Inst = CI;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Memory Instructions.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseAlloc
|
|
|
|
/// ::= 'malloc' Type (',' TypeAndValue)? (',' OptionalAlignment)?
|
|
|
|
/// ::= 'alloca' Type (',' TypeAndValue)? (',' OptionalAlignment)?
|
|
|
|
bool LLParser::ParseAlloc(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
unsigned Opc) {
|
|
|
|
PATypeHolder Ty(Type::VoidTy);
|
|
|
|
Value *Size = 0;
|
2009-07-02 23:08:13 +00:00
|
|
|
LocTy SizeLoc;
|
2009-01-02 07:01:27 +00:00
|
|
|
unsigned Alignment = 0;
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseType(Ty)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
2009-01-02 08:05:26 +00:00
|
|
|
if (EatIfPresent(lltok::comma)) {
|
2009-01-02 07:01:27 +00:00
|
|
|
if (Lex.getKind() == lltok::kw_align) {
|
|
|
|
if (ParseOptionalAlignment(Alignment)) return true;
|
2009-01-02 08:05:26 +00:00
|
|
|
} else if (ParseTypeAndValue(Size, SizeLoc, PFS) ||
|
|
|
|
ParseOptionalCommaAlignment(Alignment)) {
|
|
|
|
return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Size && Size->getType() != Type::Int32Ty)
|
|
|
|
return Error(SizeLoc, "element count must be i32");
|
|
|
|
|
|
|
|
if (Opc == Instruction::Malloc)
|
|
|
|
Inst = new MallocInst(Ty, Size, Alignment);
|
|
|
|
else
|
|
|
|
Inst = new AllocaInst(Ty, Size, Alignment);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseFree
|
|
|
|
/// ::= 'free' TypeAndValue
|
|
|
|
bool LLParser::ParseFree(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
Value *Val; LocTy Loc;
|
|
|
|
if (ParseTypeAndValue(Val, Loc, PFS)) return true;
|
|
|
|
if (!isa<PointerType>(Val->getType()))
|
|
|
|
return Error(Loc, "operand to free must be a pointer");
|
|
|
|
Inst = new FreeInst(Val);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseLoad
|
2009-06-14 23:30:43 +00:00
|
|
|
/// ::= 'volatile'? 'load' TypeAndValue (',' 'align' i32)?
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
bool isVolatile) {
|
|
|
|
Value *Val; LocTy Loc;
|
|
|
|
unsigned Alignment;
|
|
|
|
if (ParseTypeAndValue(Val, Loc, PFS) ||
|
|
|
|
ParseOptionalCommaAlignment(Alignment))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<PointerType>(Val->getType()) ||
|
|
|
|
!cast<PointerType>(Val->getType())->getElementType()->isFirstClassType())
|
|
|
|
return Error(Loc, "load operand must be a pointer to a first class type");
|
|
|
|
|
|
|
|
Inst = new LoadInst(Val, "", isVolatile, Alignment);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseStore
|
2009-06-14 23:30:43 +00:00
|
|
|
/// ::= 'volatile'? 'store' TypeAndValue ',' TypeAndValue (',' 'align' i32)?
|
2009-01-02 07:01:27 +00:00
|
|
|
bool LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS,
|
|
|
|
bool isVolatile) {
|
|
|
|
Value *Val, *Ptr; LocTy Loc, PtrLoc;
|
|
|
|
unsigned Alignment;
|
|
|
|
if (ParseTypeAndValue(Val, Loc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after store operand") ||
|
|
|
|
ParseTypeAndValue(Ptr, PtrLoc, PFS) ||
|
|
|
|
ParseOptionalCommaAlignment(Alignment))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<PointerType>(Ptr->getType()))
|
|
|
|
return Error(PtrLoc, "store operand must be a pointer");
|
|
|
|
if (!Val->getType()->isFirstClassType())
|
|
|
|
return Error(Loc, "store operand must be a first class value");
|
|
|
|
if (cast<PointerType>(Ptr->getType())->getElementType() != Val->getType())
|
|
|
|
return Error(Loc, "stored value and pointer type do not match");
|
|
|
|
|
|
|
|
Inst = new StoreInst(Val, Ptr, isVolatile, Alignment);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseGetResult
|
2009-06-14 23:30:43 +00:00
|
|
|
/// ::= 'getresult' TypeAndValue ',' i32
|
2009-01-02 07:01:27 +00:00
|
|
|
/// FIXME: Remove support for getresult in LLVM 3.0
|
|
|
|
bool LLParser::ParseGetResult(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
Value *Val; LocTy ValLoc, EltLoc;
|
|
|
|
unsigned Element;
|
|
|
|
if (ParseTypeAndValue(Val, ValLoc, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected ',' after getresult operand") ||
|
2009-01-02 08:05:26 +00:00
|
|
|
ParseUInt32(Element, EltLoc))
|
2009-01-02 07:01:27 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
|
|
|
|
return Error(ValLoc, "getresult inst requires an aggregate operand");
|
|
|
|
if (!ExtractValueInst::getIndexedType(Val->getType(), Element))
|
|
|
|
return Error(EltLoc, "invalid getresult index for value");
|
|
|
|
Inst = ExtractValueInst::Create(Val, Element);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseGetElementPtr
|
|
|
|
/// ::= 'getelementptr' TypeAndValue (',' TypeAndValue)*
|
|
|
|
bool LLParser::ParseGetElementPtr(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
Value *Ptr, *Val; LocTy Loc, EltLoc;
|
2009-01-02 08:05:26 +00:00
|
|
|
if (ParseTypeAndValue(Ptr, Loc, PFS)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
|
|
|
|
if (!isa<PointerType>(Ptr->getType()))
|
|
|
|
return Error(Loc, "base of getelementptr must be a pointer");
|
|
|
|
|
|
|
|
SmallVector<Value*, 16> Indices;
|
2009-01-02 08:05:26 +00:00
|
|
|
while (EatIfPresent(lltok::comma)) {
|
|
|
|
if (ParseTypeAndValue(Val, EltLoc, PFS)) return true;
|
2009-01-02 07:01:27 +00:00
|
|
|
if (!isa<IntegerType>(Val->getType()))
|
|
|
|
return Error(EltLoc, "getelementptr index must be an integer");
|
|
|
|
Indices.push_back(Val);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GetElementPtrInst::getIndexedType(Ptr->getType(),
|
|
|
|
Indices.begin(), Indices.end()))
|
|
|
|
return Error(Loc, "invalid getelementptr indices");
|
|
|
|
Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseExtractValue
|
|
|
|
/// ::= 'extractvalue' TypeAndValue (',' uint32)+
|
|
|
|
bool LLParser::ParseExtractValue(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
Value *Val; LocTy Loc;
|
|
|
|
SmallVector<unsigned, 4> Indices;
|
|
|
|
if (ParseTypeAndValue(Val, Loc, PFS) ||
|
|
|
|
ParseIndexList(Indices))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<StructType>(Val->getType()) && !isa<ArrayType>(Val->getType()))
|
|
|
|
return Error(Loc, "extractvalue operand must be array or struct");
|
|
|
|
|
|
|
|
if (!ExtractValueInst::getIndexedType(Val->getType(), Indices.begin(),
|
|
|
|
Indices.end()))
|
|
|
|
return Error(Loc, "invalid indices for extractvalue");
|
|
|
|
Inst = ExtractValueInst::Create(Val, Indices.begin(), Indices.end());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// ParseInsertValue
|
|
|
|
/// ::= 'insertvalue' TypeAndValue ',' TypeAndValue (',' uint32)+
|
|
|
|
bool LLParser::ParseInsertValue(Instruction *&Inst, PerFunctionState &PFS) {
|
|
|
|
Value *Val0, *Val1; LocTy Loc0, Loc1;
|
|
|
|
SmallVector<unsigned, 4> Indices;
|
|
|
|
if (ParseTypeAndValue(Val0, Loc0, PFS) ||
|
|
|
|
ParseToken(lltok::comma, "expected comma after insertvalue operand") ||
|
|
|
|
ParseTypeAndValue(Val1, Loc1, PFS) ||
|
|
|
|
ParseIndexList(Indices))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (!isa<StructType>(Val0->getType()) && !isa<ArrayType>(Val0->getType()))
|
|
|
|
return Error(Loc0, "extractvalue operand must be array or struct");
|
|
|
|
|
|
|
|
if (!ExtractValueInst::getIndexedType(Val0->getType(), Indices.begin(),
|
|
|
|
Indices.end()))
|
|
|
|
return Error(Loc0, "invalid indices for insertvalue");
|
|
|
|
Inst = InsertValueInst::Create(Val0, Val1, Indices.begin(), Indices.end());
|
|
|
|
return false;
|
|
|
|
}
|
2009-04-04 07:22:01 +00:00
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// Embedded metadata.
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
/// ParseMDNodeVector
|
2009-05-10 20:57:05 +00:00
|
|
|
/// ::= Element (',' Element)*
|
|
|
|
/// Element
|
|
|
|
/// ::= 'null' | TypeAndValue
|
|
|
|
bool LLParser::ParseMDNodeVector(SmallVectorImpl<Value*> &Elts) {
|
2009-04-04 07:22:01 +00:00
|
|
|
assert(Lex.getKind() == lltok::lbrace);
|
|
|
|
Lex.Lex();
|
|
|
|
do {
|
2009-05-10 20:57:05 +00:00
|
|
|
Value *V;
|
|
|
|
if (Lex.getKind() == lltok::kw_null) {
|
|
|
|
Lex.Lex();
|
|
|
|
V = 0;
|
|
|
|
} else {
|
|
|
|
Constant *C;
|
|
|
|
if (ParseGlobalTypeAndValue(C)) return true;
|
|
|
|
V = C;
|
|
|
|
}
|
|
|
|
Elts.push_back(V);
|
2009-04-04 07:22:01 +00:00
|
|
|
} while (EatIfPresent(lltok::comma));
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|