Update clang to r89337.
This commit is contained in:
parent
b3d5a323a5
commit
f5bd02d290
@ -1,408 +0,0 @@
|
||||
//===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
|
||||
//
|
||||
// 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 CFG and CFGBuilder classes for representing and
|
||||
// building Control-Flow Graphs (CFGs) from ASTs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_CFG_H
|
||||
#define LLVM_CLANG_CFG_H
|
||||
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
class raw_ostream;
|
||||
}
|
||||
namespace clang {
|
||||
class Stmt;
|
||||
class Expr;
|
||||
class CFG;
|
||||
class PrinterHelper;
|
||||
class BlockEdge;
|
||||
class LangOptions;
|
||||
|
||||
/// CFGBlock - Represents a single basic block in a source-level CFG.
|
||||
/// It consists of:
|
||||
///
|
||||
/// (1) A set of statements/expressions (which may contain subexpressions).
|
||||
/// (2) A "terminator" statement (not in the set of statements).
|
||||
/// (3) A list of successors and predecessors.
|
||||
///
|
||||
/// Terminator: The terminator represents the type of control-flow that occurs
|
||||
/// at the end of the basic block. The terminator is a Stmt* referring to an
|
||||
/// AST node that has control-flow: if-statements, breaks, loops, etc.
|
||||
/// If the control-flow is conditional, the condition expression will appear
|
||||
/// within the set of statements in the block (usually the last statement).
|
||||
///
|
||||
/// Predecessors: the order in the set of predecessors is arbitrary.
|
||||
///
|
||||
/// Successors: the order in the set of successors is NOT arbitrary. We
|
||||
/// currently have the following orderings based on the terminator:
|
||||
///
|
||||
/// Terminator Successor Ordering
|
||||
/// -----------------------------------------------------
|
||||
/// if Then Block; Else Block
|
||||
/// ? operator LHS expression; RHS expression
|
||||
/// &&, || expression that uses result of && or ||, RHS
|
||||
///
|
||||
class CFGBlock {
|
||||
typedef std::vector<Stmt*> StatementListTy;
|
||||
/// Stmts - The set of statements in the basic block.
|
||||
StatementListTy Stmts;
|
||||
|
||||
/// Label - An (optional) label that prefixes the executable
|
||||
/// statements in the block. When this variable is non-NULL, it is
|
||||
/// either an instance of LabelStmt or SwitchCase.
|
||||
Stmt *Label;
|
||||
|
||||
/// Terminator - The terminator for a basic block that
|
||||
/// indicates the type of control-flow that occurs between a block
|
||||
/// and its successors.
|
||||
Stmt *Terminator;
|
||||
|
||||
/// LoopTarget - Some blocks are used to represent the "loop edge" to
|
||||
/// the start of a loop from within the loop body. This Stmt* will be
|
||||
/// refer to the loop statement for such blocks (and be null otherwise).
|
||||
const Stmt *LoopTarget;
|
||||
|
||||
/// BlockID - A numerical ID assigned to a CFGBlock during construction
|
||||
/// of the CFG.
|
||||
unsigned BlockID;
|
||||
|
||||
/// Predecessors/Successors - Keep track of the predecessor / successor
|
||||
/// CFG blocks.
|
||||
typedef std::vector<CFGBlock*> AdjacentBlocks;
|
||||
AdjacentBlocks Preds;
|
||||
AdjacentBlocks Succs;
|
||||
|
||||
public:
|
||||
explicit CFGBlock(unsigned blockid) : Label(NULL), Terminator(NULL),
|
||||
LoopTarget(NULL), BlockID(blockid) {}
|
||||
~CFGBlock() {};
|
||||
|
||||
// Statement iterators
|
||||
typedef StatementListTy::iterator iterator;
|
||||
typedef StatementListTy::const_iterator const_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
|
||||
Stmt* front() const { return Stmts.front(); }
|
||||
Stmt* back() const { return Stmts.back(); }
|
||||
|
||||
iterator begin() { return Stmts.begin(); }
|
||||
iterator end() { return Stmts.end(); }
|
||||
const_iterator begin() const { return Stmts.begin(); }
|
||||
const_iterator end() const { return Stmts.end(); }
|
||||
|
||||
reverse_iterator rbegin() { return Stmts.rbegin(); }
|
||||
reverse_iterator rend() { return Stmts.rend(); }
|
||||
const_reverse_iterator rbegin() const { return Stmts.rbegin(); }
|
||||
const_reverse_iterator rend() const { return Stmts.rend(); }
|
||||
|
||||
unsigned size() const { return Stmts.size(); }
|
||||
bool empty() const { return Stmts.empty(); }
|
||||
|
||||
Stmt* operator[](size_t i) const { assert (i < size()); return Stmts[i]; }
|
||||
|
||||
// CFG iterators
|
||||
typedef AdjacentBlocks::iterator pred_iterator;
|
||||
typedef AdjacentBlocks::const_iterator const_pred_iterator;
|
||||
typedef AdjacentBlocks::reverse_iterator pred_reverse_iterator;
|
||||
typedef AdjacentBlocks::const_reverse_iterator const_pred_reverse_iterator;
|
||||
|
||||
typedef AdjacentBlocks::iterator succ_iterator;
|
||||
typedef AdjacentBlocks::const_iterator const_succ_iterator;
|
||||
typedef AdjacentBlocks::reverse_iterator succ_reverse_iterator;
|
||||
typedef AdjacentBlocks::const_reverse_iterator const_succ_reverse_iterator;
|
||||
|
||||
pred_iterator pred_begin() { return Preds.begin(); }
|
||||
pred_iterator pred_end() { return Preds.end(); }
|
||||
const_pred_iterator pred_begin() const { return Preds.begin(); }
|
||||
const_pred_iterator pred_end() const { return Preds.end(); }
|
||||
|
||||
pred_reverse_iterator pred_rbegin() { return Preds.rbegin(); }
|
||||
pred_reverse_iterator pred_rend() { return Preds.rend(); }
|
||||
const_pred_reverse_iterator pred_rbegin() const { return Preds.rbegin(); }
|
||||
const_pred_reverse_iterator pred_rend() const { return Preds.rend(); }
|
||||
|
||||
succ_iterator succ_begin() { return Succs.begin(); }
|
||||
succ_iterator succ_end() { return Succs.end(); }
|
||||
const_succ_iterator succ_begin() const { return Succs.begin(); }
|
||||
const_succ_iterator succ_end() const { return Succs.end(); }
|
||||
|
||||
succ_reverse_iterator succ_rbegin() { return Succs.rbegin(); }
|
||||
succ_reverse_iterator succ_rend() { return Succs.rend(); }
|
||||
const_succ_reverse_iterator succ_rbegin() const { return Succs.rbegin(); }
|
||||
const_succ_reverse_iterator succ_rend() const { return Succs.rend(); }
|
||||
|
||||
unsigned succ_size() const { return Succs.size(); }
|
||||
bool succ_empty() const { return Succs.empty(); }
|
||||
|
||||
unsigned pred_size() const { return Preds.size(); }
|
||||
bool pred_empty() const { return Preds.empty(); }
|
||||
|
||||
// Manipulation of block contents
|
||||
|
||||
void appendStmt(Stmt* Statement) { Stmts.push_back(Statement); }
|
||||
void setTerminator(Stmt* Statement) { Terminator = Statement; }
|
||||
void setLabel(Stmt* Statement) { Label = Statement; }
|
||||
void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
|
||||
|
||||
Stmt* getTerminator() { return Terminator; }
|
||||
const Stmt* getTerminator() const { return Terminator; }
|
||||
|
||||
Stmt* getTerminatorCondition();
|
||||
|
||||
const Stmt* getTerminatorCondition() const {
|
||||
return const_cast<CFGBlock*>(this)->getTerminatorCondition();
|
||||
}
|
||||
|
||||
const Stmt *getLoopTarget() const { return LoopTarget; }
|
||||
|
||||
bool hasBinaryBranchTerminator() const;
|
||||
|
||||
Stmt* getLabel() { return Label; }
|
||||
const Stmt* getLabel() const { return Label; }
|
||||
|
||||
void reverseStmts();
|
||||
|
||||
void addSuccessor(CFGBlock* Block) {
|
||||
Block->Preds.push_back(this);
|
||||
Succs.push_back(Block);
|
||||
}
|
||||
|
||||
unsigned getBlockID() const { return BlockID; }
|
||||
|
||||
void dump(const CFG *cfg, const LangOptions &LO) const;
|
||||
void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
|
||||
void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
|
||||
};
|
||||
|
||||
|
||||
/// CFG - Represents a source-level, intra-procedural CFG that represents the
|
||||
/// control-flow of a Stmt. The Stmt can represent an entire function body,
|
||||
/// or a single expression. A CFG will always contain one empty block that
|
||||
/// represents the Exit point of the CFG. A CFG will also contain a designated
|
||||
/// Entry block. The CFG solely represents control-flow; it consists of
|
||||
/// CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
|
||||
/// was constructed from.
|
||||
class CFG {
|
||||
public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// CFG Construction & Manipulation.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// buildCFG - Builds a CFG from an AST. The responsibility to free the
|
||||
/// constructed CFG belongs to the caller.
|
||||
static CFG* buildCFG(Stmt* AST);
|
||||
|
||||
/// createBlock - Create a new block in the CFG. The CFG owns the block;
|
||||
/// the caller should not directly free it.
|
||||
CFGBlock* createBlock();
|
||||
|
||||
/// setEntry - Set the entry block of the CFG. This is typically used
|
||||
/// only during CFG construction. Most CFG clients expect that the
|
||||
/// entry block has no predecessors and contains no statements.
|
||||
void setEntry(CFGBlock *B) { Entry = B; }
|
||||
|
||||
/// setExit - Set the exit block of the CFG. This is typically used
|
||||
/// only during CFG construction. Most CFG clients expect that the
|
||||
/// exit block has no successors and contains no statements.
|
||||
void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Block Iterators
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
typedef std::list<CFGBlock> CFGBlockListTy;
|
||||
|
||||
typedef CFGBlockListTy::iterator iterator;
|
||||
typedef CFGBlockListTy::const_iterator const_iterator;
|
||||
typedef std::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
CFGBlock& front() { return Blocks.front(); }
|
||||
CFGBlock& back() { return Blocks.back(); }
|
||||
|
||||
iterator begin() { return Blocks.begin(); }
|
||||
iterator end() { return Blocks.end(); }
|
||||
const_iterator begin() const { return Blocks.begin(); }
|
||||
const_iterator end() const { return Blocks.end(); }
|
||||
|
||||
reverse_iterator rbegin() { return Blocks.rbegin(); }
|
||||
reverse_iterator rend() { return Blocks.rend(); }
|
||||
const_reverse_iterator rbegin() const { return Blocks.rbegin(); }
|
||||
const_reverse_iterator rend() const { return Blocks.rend(); }
|
||||
|
||||
CFGBlock& getEntry() { return *Entry; }
|
||||
const CFGBlock& getEntry() const { return *Entry; }
|
||||
CFGBlock& getExit() { return *Exit; }
|
||||
const CFGBlock& getExit() const { return *Exit; }
|
||||
|
||||
CFGBlock* getIndirectGotoBlock() { return IndirectGotoBlock; }
|
||||
const CFGBlock* getIndirectGotoBlock() const { return IndirectGotoBlock; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Member templates useful for various batch operations over CFGs.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
template <typename CALLBACK>
|
||||
void VisitBlockStmts(CALLBACK& O) const {
|
||||
for (const_iterator I=begin(), E=end(); I != E; ++I)
|
||||
for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI != BE; ++BI)
|
||||
O(*BI);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// CFG Introspection.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
struct BlkExprNumTy {
|
||||
const signed Idx;
|
||||
explicit BlkExprNumTy(signed idx) : Idx(idx) {}
|
||||
explicit BlkExprNumTy() : Idx(-1) {}
|
||||
operator bool() const { return Idx >= 0; }
|
||||
operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
|
||||
};
|
||||
|
||||
bool isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
|
||||
BlkExprNumTy getBlkExprNum(const Stmt* S);
|
||||
unsigned getNumBlkExprs();
|
||||
|
||||
unsigned getNumBlockIDs() const { return NumBlockIDs; }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// CFG Debugging: Pretty-Printing and Visualization.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
void viewCFG(const LangOptions &LO) const;
|
||||
void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
|
||||
void dump(const LangOptions &LO) const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Internal: constructors and data.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
|
||||
BlkExprMap(NULL) {};
|
||||
|
||||
~CFG();
|
||||
|
||||
llvm::BumpPtrAllocator& getAllocator() {
|
||||
return Alloc;
|
||||
}
|
||||
|
||||
private:
|
||||
CFGBlock* Entry;
|
||||
CFGBlock* Exit;
|
||||
CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch
|
||||
// for indirect gotos
|
||||
CFGBlockListTy Blocks;
|
||||
unsigned NumBlockIDs;
|
||||
|
||||
// BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
|
||||
// It represents a map from Expr* to integers to record the set of
|
||||
// block-level expressions and their "statement number" in the CFG.
|
||||
void* BlkExprMap;
|
||||
|
||||
/// Alloc - An internal allocator.
|
||||
llvm::BumpPtrAllocator Alloc;
|
||||
};
|
||||
} // end namespace clang
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace llvm {
|
||||
|
||||
// Traits for: CFGBlock
|
||||
|
||||
template <> struct GraphTraits<clang::CFGBlock* > {
|
||||
typedef clang::CFGBlock NodeType;
|
||||
typedef clang::CFGBlock::succ_iterator ChildIteratorType;
|
||||
|
||||
static NodeType* getEntryNode(clang::CFGBlock* BB)
|
||||
{ return BB; }
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType* N)
|
||||
{ return N->succ_begin(); }
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType* N)
|
||||
{ return N->succ_end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<const clang::CFGBlock* > {
|
||||
typedef const clang::CFGBlock NodeType;
|
||||
typedef clang::CFGBlock::const_succ_iterator ChildIteratorType;
|
||||
|
||||
static NodeType* getEntryNode(const clang::CFGBlock* BB)
|
||||
{ return BB; }
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType* N)
|
||||
{ return N->succ_begin(); }
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType* N)
|
||||
{ return N->succ_end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const clang::CFGBlock*> > {
|
||||
typedef const clang::CFGBlock NodeType;
|
||||
typedef clang::CFGBlock::const_pred_iterator ChildIteratorType;
|
||||
|
||||
static NodeType *getEntryNode(Inverse<const clang::CFGBlock*> G)
|
||||
{ return G.Graph; }
|
||||
|
||||
static inline ChildIteratorType child_begin(NodeType* N)
|
||||
{ return N->pred_begin(); }
|
||||
|
||||
static inline ChildIteratorType child_end(NodeType* N)
|
||||
{ return N->pred_end(); }
|
||||
};
|
||||
|
||||
// Traits for: CFG
|
||||
|
||||
template <> struct GraphTraits<clang::CFG* >
|
||||
: public GraphTraits<clang::CFGBlock* > {
|
||||
|
||||
typedef clang::CFG::iterator nodes_iterator;
|
||||
|
||||
static NodeType *getEntryNode(clang::CFG* F) { return &F->getEntry(); }
|
||||
static nodes_iterator nodes_begin(clang::CFG* F) { return F->begin(); }
|
||||
static nodes_iterator nodes_end(clang::CFG* F) { return F->end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits< const clang::CFG* >
|
||||
: public GraphTraits< const clang::CFGBlock* > {
|
||||
|
||||
typedef clang::CFG::const_iterator nodes_iterator;
|
||||
|
||||
static NodeType *getEntryNode( const clang::CFG* F) { return &F->getEntry(); }
|
||||
static nodes_iterator nodes_begin( const clang::CFG* F) { return F->begin(); }
|
||||
static nodes_iterator nodes_end( const clang::CFG* F) { return F->end(); }
|
||||
};
|
||||
|
||||
template <> struct GraphTraits<Inverse<const clang::CFG*> >
|
||||
: public GraphTraits<Inverse<const clang::CFGBlock*> > {
|
||||
|
||||
typedef clang::CFG::const_iterator nodes_iterator;
|
||||
|
||||
static NodeType *getEntryNode(const clang::CFG* F) { return &F->getExit(); }
|
||||
static nodes_iterator nodes_begin(const clang::CFG* F) { return F->begin();}
|
||||
static nodes_iterator nodes_end(const clang::CFG* F) { return F->end(); }
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
@ -808,7 +808,7 @@ class ObjCForwardProtocolDecl : public Decl {
|
||||
/// - myMethod;
|
||||
/// @end
|
||||
///
|
||||
/// Cateogries also allow you to split the implementation of a class across
|
||||
/// Categories also allow you to split the implementation of a class across
|
||||
/// several files (a feature more naturally supported in C++).
|
||||
///
|
||||
/// Categories were originally inspired by dynamic languages such as Common
|
||||
|
@ -1,28 +0,0 @@
|
||||
//===--- AttrNonNullChecker.h - Undefined arguments checker ----*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This defines AttrNonNullChecker, a builtin check in GRExprEngine that
|
||||
// performs checks for arguments declared to have nonnull attribute.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class AttrNonNullChecker : public CheckerVisitor<AttrNonNullChecker> {
|
||||
BugType *BT;
|
||||
|
||||
public:
|
||||
AttrNonNullChecker() : BT(0) {}
|
||||
static void *getTag();
|
||||
void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
};
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
//===--- BadCallChecker.h - Bad call checker --------------------*- C++ -*--==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This defines BadCallChecker, a builtin check in GRExprEngine that performs
|
||||
// checks for bad callee at call sites.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class BadCallChecker : public CheckerVisitor<BadCallChecker> {
|
||||
BuiltinBug *BT;
|
||||
|
||||
public:
|
||||
BadCallChecker() : BT(0) {}
|
||||
|
||||
static void *getTag();
|
||||
|
||||
void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
};
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//== DivZeroChecker.h - Division by zero checker ----------------*- C++ -*--==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This defines DivZeroChecker, a builtin check in GRExprEngine that performs
|
||||
// checks for division by zeros.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class DivZeroChecker : public CheckerVisitor<DivZeroChecker> {
|
||||
BuiltinBug *BT;
|
||||
public:
|
||||
DivZeroChecker() : BT(0) {}
|
||||
|
||||
static void *getTag();
|
||||
void PreVisitBinaryOperator(CheckerContext &C, const BinaryOperator *B);
|
||||
};
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
//===--- UndefinedArgChecker.h - Undefined arguments checker ----*- C++ -*--==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This defines BadCallChecker, a builtin check in GRExprEngine that performs
|
||||
// checks for undefined arguments.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_UNDEFARGCHECKER
|
||||
#define LLVM_CLANG_UNDEFARGCHECKER
|
||||
|
||||
#include "clang/Analysis/PathSensitive/CheckerVisitor.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class UndefinedArgChecker : public CheckerVisitor<UndefinedArgChecker> {
|
||||
BugType *BT;
|
||||
|
||||
public:
|
||||
UndefinedArgChecker() : BT(0) {}
|
||||
|
||||
static void *getTag();
|
||||
|
||||
void PreVisitCallExpr(CheckerContext &C, const CallExpr *CE);
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -1,39 +0,0 @@
|
||||
//=== VLASizeChecker.h - Undefined dereference checker ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This defines two VLASizeCheckers, a builtin check in GRExprEngine that
|
||||
// performs checks for declaration of VLA of undefined or zero size.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Analysis/PathSensitive/Checker.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
class UndefSizedVLAChecker : public Checker {
|
||||
BugType *BT;
|
||||
|
||||
public:
|
||||
UndefSizedVLAChecker() : BT(0) {}
|
||||
static void *getTag();
|
||||
ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
|
||||
const GRState *state, Stmt *S, GRExprEngine &Eng);
|
||||
};
|
||||
|
||||
class ZeroSizedVLAChecker : public Checker {
|
||||
BugType *BT;
|
||||
|
||||
public:
|
||||
ZeroSizedVLAChecker() : BT(0) {}
|
||||
static void *getTag();
|
||||
ExplodedNode *CheckType(QualType T, ExplodedNode *Pred,
|
||||
const GRState *state, Stmt *S, GRExprEngine &Eng);
|
||||
};
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
//==- CFGVarDeclVisitor - Generic visitor of VarDecls in a CFG --*- C++ --*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the template class CFGVarDeclVisitor, which provides
|
||||
// a generic way to visit all the VarDecl's in a CFG.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_ANALYSIS_CFG_VARDECL_VISITOR_H
|
||||
#define LLVM_CLANG_ANALYSIS_CFG_VARDECL_VISITOR_H
|
||||
|
||||
#include "clang/Analysis/Visitors/CFGStmtVisitor.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/Stmt.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
template <typename ImplClass>
|
||||
class CFGVarDeclVisitor : public CFGStmtVisitor<ImplClass> {
|
||||
const CFG& cfg;
|
||||
public:
|
||||
CFGVarDeclVisitor(const CFG& c) : cfg(c) {}
|
||||
|
||||
void VisitStmt(Stmt* S) {
|
||||
static_cast<ImplClass*>(this)->VisitChildren(S);
|
||||
}
|
||||
|
||||
void VisitDeclRefExpr(DeclRefExpr* DR) {
|
||||
static_cast<ImplClass*>(this)->VisitDeclChain(DR->getDecl());
|
||||
}
|
||||
|
||||
void VisitDeclStmt(DeclStmt* DS) {
|
||||
static_cast<ImplClass*>(this)->VisitDeclChain(DS->getDecl());
|
||||
}
|
||||
|
||||
void VisitDeclChain(ScopedDecl* D) {
|
||||
for (; D != NULL ; D = D->getNextDeclarator())
|
||||
static_cast<ImplClass*>(this)->VisitScopedDecl(D);
|
||||
}
|
||||
|
||||
void VisitScopedDecl(ScopedDecl* D) {
|
||||
if (VarDecl* V = dyn_cast<VarDecl>(D))
|
||||
static_cast<ImplClass*>(this)->VisitVarDecl(V);
|
||||
}
|
||||
|
||||
void VisitVarDecl(VarDecl* D) {}
|
||||
|
||||
void VisitAllDecls() {
|
||||
for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI)
|
||||
for (CFGBlock::const_iterator SI=BI->begin(),SE = BI->end();SI != SE;++SI)
|
||||
static_cast<ImplClass*>(this)->BlockStmt_Visit(const_cast<Stmt*>(*SI));
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -235,8 +235,8 @@ class Diagnostic {
|
||||
// Diagnostic characterization methods, used by a client to customize how
|
||||
//
|
||||
|
||||
DiagnosticClient *getClient() { return Client; };
|
||||
const DiagnosticClient *getClient() const { return Client; };
|
||||
DiagnosticClient *getClient() { return Client; }
|
||||
const DiagnosticClient *getClient() const { return Client; }
|
||||
|
||||
|
||||
/// pushMappings - Copies the current DiagMappings and pushes the new copy
|
||||
|
@ -117,8 +117,6 @@ def err_expected_semi_after_static_assert : Error<
|
||||
"expected ';' after static_assert">;
|
||||
def err_expected_semi_for : Error<"expected ';' in 'for' statement specifier">;
|
||||
def err_expected_colon_after : Error<"expected ':' after %0">;
|
||||
def err_pointer_to_member_type : Error<
|
||||
"invalid use of pointer to member type after %0">;
|
||||
def err_label_end_of_compound_statement : Error<
|
||||
"label at end of compound statement: expected statement">;
|
||||
def err_expected_string_literal : Error<"expected string literal">;
|
||||
@ -201,6 +199,8 @@ def warn_expected_implementation : Warning<
|
||||
"@end must appear in an @implementation context">;
|
||||
def error_property_ivar_decl : Error<
|
||||
"property synthesize requires specification of an ivar">;
|
||||
def err_synthesized_property_name : Error<
|
||||
"expected a property name in @synthesize">;
|
||||
def warn_semicolon_before_method_body : Warning<
|
||||
"semicolon before method body is ignored">,
|
||||
InGroup<DiagGroup<"semicolon-before-method-body">>, DefaultIgnore;
|
||||
|
@ -979,6 +979,8 @@ def err_template_arg_not_pointer_to_member_form : Error<
|
||||
"non-type template argument is not a pointer to member constant">;
|
||||
def err_template_arg_extra_parens : Error<
|
||||
"non-type template argument cannot be surrounded by parentheses">;
|
||||
def err_pointer_to_member_type : Error<
|
||||
"invalid use of pointer to member type after %select{.*|->*}0">;
|
||||
|
||||
// C++ template specialization
|
||||
def err_template_spec_unknown_kind : Error<
|
||||
@ -1811,6 +1813,8 @@ def err_typecheck_bool_condition : Error<
|
||||
"value of type %0 is not contextually convertible to 'bool'">;
|
||||
def err_typecheck_ambiguous_condition : Error<
|
||||
"conversion from %0 to %1 is ambiguous">;
|
||||
def err_typecheck_nonviable_condition : Error<
|
||||
"no viable conversion from %0 to %1 is possible">;
|
||||
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
|
||||
def err_invalid_declarator_scope : Error<
|
||||
"definition or redeclaration of %0 not in a namespace enclosing %1">;
|
||||
|
@ -1 +1,2 @@
|
||||
add_subdirectory(Basic)
|
||||
add_subdirectory(Driver)
|
||||
|
@ -10,8 +10,7 @@
|
||||
#ifndef CLANG_DRIVER_ARGLIST_H_
|
||||
#define CLANG_DRIVER_ARGLIST_H_
|
||||
|
||||
#include "clang/Driver/Options.h"
|
||||
|
||||
#include "clang/Driver/OptSpecifier.h"
|
||||
#include "clang/Driver/Util.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
@ -26,6 +25,7 @@ namespace llvm {
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
class Arg;
|
||||
class Option;
|
||||
|
||||
/// ArgList - Ordered collection of driver arguments.
|
||||
///
|
||||
@ -77,20 +77,26 @@ namespace driver {
|
||||
/// hasArg - Does the arg list contain any option matching \arg Id.
|
||||
///
|
||||
/// \arg Claim Whether the argument should be claimed, if it exists.
|
||||
bool hasArg(options::ID Id, bool Claim=true) const {
|
||||
return getLastArg(Id, Claim) != 0;
|
||||
bool hasArgNoClaim(OptSpecifier Id) const {
|
||||
return getLastArgNoClaim(Id) != 0;
|
||||
}
|
||||
bool hasArg(options::ID Id0, options::ID Id1, bool Claim=true) const {
|
||||
return getLastArg(Id0, Id1, Claim) != 0;
|
||||
bool hasArg(OptSpecifier Id) const {
|
||||
return getLastArg(Id) != 0;
|
||||
}
|
||||
bool hasArg(OptSpecifier Id0, OptSpecifier Id1) const {
|
||||
return getLastArg(Id0, Id1) != 0;
|
||||
}
|
||||
bool hasArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const {
|
||||
return getLastArg(Id0, Id1, Id2) != 0;
|
||||
}
|
||||
|
||||
/// getLastArg - Return the last argument matching \arg Id, or null.
|
||||
///
|
||||
/// \arg Claim Whether the argument should be claimed, if it exists.
|
||||
Arg *getLastArg(options::ID Id, bool Claim=true) const;
|
||||
Arg *getLastArg(options::ID Id0, options::ID Id1, bool Claim=true) const;
|
||||
Arg *getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
|
||||
bool Claim=true) const;
|
||||
Arg *getLastArgNoClaim(OptSpecifier Id) const;
|
||||
Arg *getLastArg(OptSpecifier Id) const;
|
||||
Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
|
||||
Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
|
||||
|
||||
/// getArgString - Return the input argument string at \arg Index.
|
||||
virtual const char *getArgString(unsigned Index) const = 0;
|
||||
@ -102,24 +108,24 @@ namespace driver {
|
||||
/// negation is present, and \arg Default if neither option is
|
||||
/// given. If both the option and its negation are present, the
|
||||
/// last one wins.
|
||||
bool hasFlag(options::ID Pos, options::ID Neg, bool Default=true) const;
|
||||
bool hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default=true) const;
|
||||
|
||||
/// AddLastArg - Render only the last argument match \arg Id0, if
|
||||
/// present.
|
||||
void AddLastArg(ArgStringList &Output, options::ID Id0) const;
|
||||
void AddLastArg(ArgStringList &Output, OptSpecifier Id0) const;
|
||||
|
||||
/// AddAllArgs - Render all arguments matching the given ids.
|
||||
void AddAllArgs(ArgStringList &Output, options::ID Id0) const;
|
||||
void AddAllArgs(ArgStringList &Output, options::ID Id0,
|
||||
options::ID Id1) const;
|
||||
void AddAllArgs(ArgStringList &Output, options::ID Id0, options::ID Id1,
|
||||
options::ID Id2) const;
|
||||
void AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const;
|
||||
void AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
|
||||
OptSpecifier Id1) const;
|
||||
void AddAllArgs(ArgStringList &Output, OptSpecifier Id0, OptSpecifier Id1,
|
||||
OptSpecifier Id2) const;
|
||||
|
||||
/// AddAllArgValues - Render the argument values of all arguments
|
||||
/// matching the given ids.
|
||||
void AddAllArgValues(ArgStringList &Output, options::ID Id0) const;
|
||||
void AddAllArgValues(ArgStringList &Output, options::ID Id0,
|
||||
options::ID Id1) const;
|
||||
void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const;
|
||||
void AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
|
||||
OptSpecifier Id1) const;
|
||||
|
||||
/// AddAllArgsTranslated - Render all the arguments matching the
|
||||
/// given ids, but forced to separate args and using the provided
|
||||
@ -127,13 +133,13 @@ namespace driver {
|
||||
///
|
||||
/// \param Joined - If true, render the argument as joined with
|
||||
/// the option specifier.
|
||||
void AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
|
||||
void AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
|
||||
const char *Translation,
|
||||
bool Joined = false) const;
|
||||
|
||||
/// ClaimAllArgs - Claim all arguments which match the given
|
||||
/// option id.
|
||||
void ClaimAllArgs(options::ID Id0) const;
|
||||
void ClaimAllArgs(OptSpecifier Id0) const;
|
||||
|
||||
/// @}
|
||||
/// @name Arg Synthesis
|
||||
|
34
include/clang/Driver/CC1Options.h
Normal file
34
include/clang/Driver/CC1Options.h
Normal file
@ -0,0 +1,34 @@
|
||||
//===--- CC1Options.h - Clang CC1 Options Table -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_DRIVER_CC1OPTIONS_H
|
||||
#define CLANG_DRIVER_CC1OPTIONS_H
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
class OptTable;
|
||||
|
||||
namespace cc1options {
|
||||
enum ID {
|
||||
OPT_INVALID = 0, // This is not an option ID.
|
||||
OPT_INPUT, // Reserved ID for input option.
|
||||
OPT_UNKNOWN, // Reserved ID for unknown option.
|
||||
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR) OPT_##ID,
|
||||
#include "clang/Driver/CC1Options.inc"
|
||||
LastOption
|
||||
#undef OPTION
|
||||
};
|
||||
}
|
||||
|
||||
OptTable *createCC1OptTable();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
26
include/clang/Driver/CC1Options.td
Normal file
26
include/clang/Driver/CC1Options.td
Normal file
@ -0,0 +1,26 @@
|
||||
//===--- CC1Options.td - Options for clang -cc1 ---------------------------===//
|
||||
//
|
||||
// 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 options accepted by clang -cc1.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Include the common option parsing interfaces.
|
||||
include "OptParser.td"
|
||||
|
||||
// Target Options
|
||||
|
||||
def target_abi : Separate<"-target-abi">,
|
||||
HelpText<"Target a particular ABI type">;
|
||||
def target_cpu : Separate<"-mcpu">,
|
||||
HelpText<"Target a specific cpu type (-mcpu=help for details)">;
|
||||
def target_features : Separate<"-target-feature">,
|
||||
HelpText<"Target specific attributes">;
|
||||
def target_triple : Separate<"-triple">,
|
||||
HelpText<"Specify target triple (e.g. i686-apple-darwin9)">;
|
11
include/clang/Driver/CMakeLists.txt
Normal file
11
include/clang/Driver/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
set(LLVM_TARGET_DEFINITIONS Options.td)
|
||||
tablegen(Options.inc
|
||||
-gen-opt-parser-defs)
|
||||
add_custom_target(ClangDriverOptions
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Options.inc)
|
||||
|
||||
set(LLVM_TARGET_DEFINITIONS CC1Options.td)
|
||||
tablegen(CC1Options.inc
|
||||
-gen-opt-parser-defs)
|
||||
add_custom_target(ClangCC1Options
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CC1Options.inc)
|
16
include/clang/Driver/Makefile
Normal file
16
include/clang/Driver/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
LEVEL = ../../../../..
|
||||
BUILT_SOURCES = Options.inc CC1Options.inc
|
||||
|
||||
TABLEGEN_INC_FILES_COMMON = 1
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
$(ObjDir)/Options.inc.tmp : Options.td OptParser.td $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang Driver Option tables with tblgen"
|
||||
$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(ObjDir)/CC1Options.inc.tmp : CC1Options.td OptParser.td $(ObjDir)/.dir
|
||||
$(Echo) "Building Clang CC1 Option tables with tblgen"
|
||||
$(Verb) $(TableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
|
||||
|
||||
|
116
include/clang/Driver/OptParser.td
Normal file
116
include/clang/Driver/OptParser.td
Normal file
@ -0,0 +1,116 @@
|
||||
//===--- OptParser.td - Common Option Parsing Interfaces ------------------===//
|
||||
//
|
||||
// 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 common interfaces used by the option parsing TableGen
|
||||
// backend.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Define the kinds of options.
|
||||
|
||||
class OptionKind<string name, int predecence = 0> {
|
||||
string Name = name;
|
||||
// The kind precedence, kinds with lower precedence are matched first.
|
||||
int Precedence = predecence;
|
||||
}
|
||||
|
||||
// An option group.
|
||||
def KIND_GROUP : OptionKind<"Group">;
|
||||
// A flag with no values.
|
||||
def KIND_FLAG : OptionKind<"Flag">;
|
||||
// An option which prefixes its (single) value.
|
||||
def KIND_JOINED : OptionKind<"Joined", 1>;
|
||||
// An option which is followed by its value.
|
||||
def KIND_SEPARATE : OptionKind<"Separate">;
|
||||
// An option followed by its values, which are separated by commas.
|
||||
def KIND_COMMAJOINED : OptionKind<"CommaJoined">;
|
||||
// An option which is which takes multiple (separate) arguments.
|
||||
def KIND_MULTIARG : OptionKind<"MultiArg">;
|
||||
// An option which is either joined to its (non-empty) value, or followed by its
|
||||
// value.
|
||||
def KIND_JOINED_OR_SEPARATE : OptionKind<"JoinedOrSeparate">;
|
||||
// An option which is both joined to its (first) value, and followed by its
|
||||
// (second) value.
|
||||
def KIND_JOINED_AND_SEPARATE : OptionKind<"JoinedAndSeparate">;
|
||||
|
||||
// Define the option flags.
|
||||
|
||||
class OptionFlag {}
|
||||
|
||||
// DriverOption - The option is a "driver" option, and should not be forwarded
|
||||
// to gcc.
|
||||
def DriverOption : OptionFlag;
|
||||
|
||||
// LinkerInput - The option is a linker input.
|
||||
def LinkerInput : OptionFlag;
|
||||
|
||||
// NoArgumentUnused - Don't report argument unused warnings for this option; this
|
||||
// is useful for options like -static or -dynamic which a user may always end up
|
||||
// passing, even if the platform defaults to (or only supports) that option.
|
||||
def NoArgumentUnused : OptionFlag;
|
||||
|
||||
// RenderAsInput - The option should not render the name when rendered as an
|
||||
// input (i.e., the option is rendered as values).
|
||||
def RenderAsInput : OptionFlag;
|
||||
|
||||
// RenderJoined - The option should be rendered joined, even if separate (only
|
||||
// sensible on single value separate options).
|
||||
def RenderJoined : OptionFlag;
|
||||
|
||||
// RenderSeparate - The option should be rendered separately, even if joined
|
||||
// (only sensible on joined options).
|
||||
def RenderSeparate : OptionFlag;
|
||||
|
||||
// Unsupported - The option is unsupported, and the driver will reject command
|
||||
// lines that use it.
|
||||
def Unsupported : OptionFlag;
|
||||
|
||||
// Define the option group class.
|
||||
|
||||
class OptionGroup<string name> {
|
||||
string EnumName = ?; // Uses the def name if undefined.
|
||||
string Name = name;
|
||||
OptionGroup Group = ?;
|
||||
}
|
||||
|
||||
// Define the option class.
|
||||
|
||||
class Option<string name, OptionKind kind> {
|
||||
string EnumName = ?; // Uses the def name if undefined.
|
||||
string Name = name;
|
||||
OptionKind Kind = kind;
|
||||
// Used by MultiArg option kind.
|
||||
int NumArgs = 0;
|
||||
string HelpText = ?;
|
||||
string MetaVarName = ?;
|
||||
list<OptionFlag> Flags = [];
|
||||
OptionGroup Group = ?;
|
||||
Option Alias = ?;
|
||||
}
|
||||
|
||||
// Helpers for defining options.
|
||||
|
||||
class Flag<string name> : Option<name, KIND_FLAG>;
|
||||
class Joined<string name> : Option<name, KIND_JOINED>;
|
||||
class Separate<string name> : Option<name, KIND_SEPARATE>;
|
||||
class CommaJoined<string name> : Option<name, KIND_COMMAJOINED>;
|
||||
class MultiArg<string name, int numargs> : Option<name, KIND_MULTIARG> {
|
||||
int NumArgs = numargs;
|
||||
}
|
||||
class JoinedOrSeparate<string name> : Option<name, KIND_JOINED_OR_SEPARATE>;
|
||||
class JoinedAndSeparate<string name> : Option<name, KIND_JOINED_AND_SEPARATE>;
|
||||
|
||||
// Mix-ins for adding optional attributes.
|
||||
|
||||
class Alias<Option alias> { Option Alias = alias; }
|
||||
class EnumName<string name> { string EnumName = name; }
|
||||
class Flags<list<OptionFlag> flags> { list<OptionFlag> Flags = flags; }
|
||||
class Group<OptionGroup group> { OptionGroup Group = group; }
|
||||
class HelpText<string text> { string HelpText = text; }
|
||||
class MetaVarName<string name> { string MetaVarName = name; }
|
36
include/clang/Driver/OptSpecifier.h
Normal file
36
include/clang/Driver/OptSpecifier.h
Normal file
@ -0,0 +1,36 @@
|
||||
//===--- OptSpecifier.h - Option Specifiers ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_DRIVER_OPTSPECIFIER_H
|
||||
#define CLANG_DRIVER_OPTSPECIFIER_H
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
class Option;
|
||||
|
||||
/// OptSpecifier - Wrapper class for abstracting references to option IDs.
|
||||
class OptSpecifier {
|
||||
unsigned ID;
|
||||
|
||||
private:
|
||||
explicit OptSpecifier(bool); // DO NOT IMPLEMENT
|
||||
|
||||
public:
|
||||
/*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
|
||||
/*implicit*/ OptSpecifier(const Option *Opt);
|
||||
|
||||
unsigned getID() const { return ID; }
|
||||
|
||||
bool operator==(OptSpecifier Opt) const { return ID == Opt.getID(); }
|
||||
bool operator!=(OptSpecifier Opt) const { return !(*this == Opt); }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
163
include/clang/Driver/OptTable.h
Normal file
163
include/clang/Driver/OptTable.h
Normal file
@ -0,0 +1,163 @@
|
||||
//===--- OptTable.h - Option Table ------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_DRIVER_OPTTABLE_H
|
||||
#define CLANG_DRIVER_OPTTABLE_H
|
||||
|
||||
#include "clang/Driver/OptSpecifier.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
namespace options {
|
||||
enum DriverFlag {
|
||||
DriverOption = (1 << 0),
|
||||
LinkerInput = (1 << 1),
|
||||
NoArgumentUnused = (1 << 2),
|
||||
RenderAsInput = (1 << 3),
|
||||
RenderJoined = (1 << 4),
|
||||
RenderSeparate = (1 << 5),
|
||||
Unsupported = (1 << 6)
|
||||
};
|
||||
}
|
||||
|
||||
class Arg;
|
||||
class InputArgList;
|
||||
class Option;
|
||||
|
||||
/// OptTable - Provide access to the Option info table.
|
||||
///
|
||||
/// The OptTable class provides a layer of indirection which allows Option
|
||||
/// instance to be created lazily. In the common case, only a few options will
|
||||
/// be needed at runtime; the OptTable class maintains enough information to
|
||||
/// parse command lines without instantiating Options, while letting other
|
||||
/// parts of the driver still use Option instances where convenient.
|
||||
class OptTable {
|
||||
public:
|
||||
/// Info - Entry for a single option instance in the option data table.
|
||||
struct Info {
|
||||
const char *Name;
|
||||
const char *HelpText;
|
||||
const char *MetaVar;
|
||||
unsigned char Kind;
|
||||
unsigned char Flags;
|
||||
unsigned char Param;
|
||||
unsigned short GroupID;
|
||||
unsigned short AliasID;
|
||||
};
|
||||
|
||||
private:
|
||||
/// The static option information table.
|
||||
const Info *OptionInfos;
|
||||
unsigned NumOptionInfos;
|
||||
|
||||
/// The lazily constructed options table, indexed by option::ID - 1.
|
||||
mutable Option **Options;
|
||||
|
||||
/// Prebound input option instance.
|
||||
const Option *TheInputOption;
|
||||
|
||||
/// Prebound unknown option instance.
|
||||
const Option *TheUnknownOption;
|
||||
|
||||
/// The index of the first option which can be parsed (i.e., is not a
|
||||
/// special option like 'input' or 'unknown', and is not an option group).
|
||||
unsigned FirstSearchableIndex;
|
||||
|
||||
private:
|
||||
const Info &getInfo(OptSpecifier Opt) const {
|
||||
unsigned id = Opt.getID();
|
||||
assert(id > 0 && id - 1 < getNumOptions() && "Invalid Option ID.");
|
||||
return OptionInfos[id - 1];
|
||||
}
|
||||
|
||||
Option *CreateOption(unsigned id) const;
|
||||
|
||||
protected:
|
||||
OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos);
|
||||
public:
|
||||
~OptTable();
|
||||
|
||||
/// getNumOptions - Return the total number of option classes.
|
||||
unsigned getNumOptions() const { return NumOptionInfos; }
|
||||
|
||||
/// getOption - Get the given \arg id's Option instance, lazily creating it
|
||||
/// if necessary.
|
||||
///
|
||||
/// \return The option, or null for the INVALID option id.
|
||||
const Option *getOption(OptSpecifier Opt) const {
|
||||
unsigned id = Opt.getID();
|
||||
if (id == 0)
|
||||
return 0;
|
||||
|
||||
assert((unsigned) (id - 1) < getNumOptions() && "Invalid ID.");
|
||||
Option *&Entry = Options[id - 1];
|
||||
if (!Entry)
|
||||
Entry = CreateOption(id);
|
||||
return Entry;
|
||||
}
|
||||
|
||||
/// getOptionName - Lookup the name of the given option.
|
||||
const char *getOptionName(OptSpecifier id) const {
|
||||
return getInfo(id).Name;
|
||||
}
|
||||
|
||||
/// getOptionKind - Get the kind of the given option.
|
||||
unsigned getOptionKind(OptSpecifier id) const {
|
||||
return getInfo(id).Kind;
|
||||
}
|
||||
|
||||
/// getOptionHelpText - Get the help text to use to describe this option.
|
||||
const char *getOptionHelpText(OptSpecifier id) const {
|
||||
return getInfo(id).HelpText;
|
||||
}
|
||||
|
||||
/// getOptionMetaVar - Get the meta-variable name to use when describing
|
||||
/// this options values in the help text.
|
||||
const char *getOptionMetaVar(OptSpecifier id) const {
|
||||
return getInfo(id).MetaVar;
|
||||
}
|
||||
|
||||
/// ParseOneArg - Parse a single argument; returning the new argument and
|
||||
/// updating Index.
|
||||
///
|
||||
/// \param [in] [out] Index - The current parsing position in the argument
|
||||
/// string list; on return this will be the index of the next argument
|
||||
/// string to parse.
|
||||
///
|
||||
/// \return - The parsed argument, or 0 if the argument is missing values
|
||||
/// (in which case Index still points at the conceptual next argument string
|
||||
/// to parse).
|
||||
Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
|
||||
|
||||
/// ParseArgs - Parse an list of arguments into an InputArgList.
|
||||
///
|
||||
/// The resulting InputArgList will reference the strings in [ArgBegin,
|
||||
/// ArgEnd), and their lifetime should extend past that of the returned
|
||||
/// InputArgList.
|
||||
///
|
||||
/// The only error that can occur in this routine is if an argument is
|
||||
/// missing values; in this case \arg MissingArgCount will be non-zero.
|
||||
///
|
||||
/// \param ArgBegin - The beginning of the argument vector.
|
||||
/// \param ArgEnd - The end of the argument vector.
|
||||
/// \param MissingArgIndex - On error, the index of the option which could
|
||||
/// not be parsed.
|
||||
/// \param MissingArgCount - On error, the number of missing options.
|
||||
/// \return - An InputArgList; on error this will contain all the options
|
||||
/// which could be parsed.
|
||||
InputArgList *ParseArgs(const char **ArgBegin,
|
||||
const char **ArgEnd,
|
||||
unsigned &MissingArgIndex,
|
||||
unsigned &MissingArgCount) const;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -10,8 +10,7 @@
|
||||
#ifndef CLANG_DRIVER_OPTION_H_
|
||||
#define CLANG_DRIVER_OPTION_H_
|
||||
|
||||
#include "Options.h"
|
||||
|
||||
#include "clang/Driver/OptSpecifier.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
using llvm::isa;
|
||||
using llvm::cast;
|
||||
@ -54,7 +53,8 @@ namespace driver {
|
||||
private:
|
||||
OptionClass Kind;
|
||||
|
||||
options::ID ID;
|
||||
/// The option ID.
|
||||
OptSpecifier ID;
|
||||
|
||||
/// The option name.
|
||||
const char *Name;
|
||||
@ -89,12 +89,12 @@ namespace driver {
|
||||
bool NoArgumentUnused : 1;
|
||||
|
||||
protected:
|
||||
Option(OptionClass Kind, options::ID ID, const char *Name,
|
||||
Option(OptionClass Kind, OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias);
|
||||
public:
|
||||
virtual ~Option();
|
||||
|
||||
options::ID getId() const { return ID; }
|
||||
unsigned getID() const { return ID.getID(); }
|
||||
OptionClass getKind() const { return Kind; }
|
||||
const char *getName() const { return Name; }
|
||||
const OptionGroup *getGroup() const { return Group; }
|
||||
@ -138,8 +138,11 @@ namespace driver {
|
||||
|
||||
/// matches - Predicate for whether this option is part of the
|
||||
/// given option (which may be a group).
|
||||
bool matches(const Option *Opt) const;
|
||||
bool matches(options::ID Id) const;
|
||||
///
|
||||
/// Note that matches against options which are an alias should never be
|
||||
/// done -- aliases do not participate in matching and so such a query will
|
||||
/// always be false.
|
||||
bool matches(OptSpecifier ID) const;
|
||||
|
||||
/// accept - Potentially accept the current argument, returning a
|
||||
/// new Arg instance, or 0 if the option does not accept this
|
||||
@ -159,7 +162,7 @@ namespace driver {
|
||||
/// by the driver.
|
||||
class OptionGroup : public Option {
|
||||
public:
|
||||
OptionGroup(options::ID ID, const char *Name, const OptionGroup *Group);
|
||||
OptionGroup(OptSpecifier ID, const char *Name, const OptionGroup *Group);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
|
||||
@ -174,7 +177,7 @@ namespace driver {
|
||||
/// InputOption - Dummy option class for representing driver inputs.
|
||||
class InputOption : public Option {
|
||||
public:
|
||||
InputOption();
|
||||
InputOption(OptSpecifier ID);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
|
||||
@ -187,7 +190,7 @@ namespace driver {
|
||||
/// UnknownOption - Dummy option class for represent unknown arguments.
|
||||
class UnknownOption : public Option {
|
||||
public:
|
||||
UnknownOption();
|
||||
UnknownOption(OptSpecifier ID);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
|
||||
@ -201,7 +204,7 @@ namespace driver {
|
||||
|
||||
class FlagOption : public Option {
|
||||
public:
|
||||
FlagOption(options::ID ID, const char *Name, const OptionGroup *Group,
|
||||
FlagOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
|
||||
const Option *Alias);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
@ -214,7 +217,7 @@ namespace driver {
|
||||
|
||||
class JoinedOption : public Option {
|
||||
public:
|
||||
JoinedOption(options::ID ID, const char *Name, const OptionGroup *Group,
|
||||
JoinedOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
|
||||
const Option *Alias);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
@ -227,8 +230,8 @@ namespace driver {
|
||||
|
||||
class SeparateOption : public Option {
|
||||
public:
|
||||
SeparateOption(options::ID ID, const char *Name, const OptionGroup *Group,
|
||||
const Option *Alias);
|
||||
SeparateOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
|
||||
@ -240,7 +243,7 @@ namespace driver {
|
||||
|
||||
class CommaJoinedOption : public Option {
|
||||
public:
|
||||
CommaJoinedOption(options::ID ID, const char *Name,
|
||||
CommaJoinedOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
@ -259,7 +262,7 @@ namespace driver {
|
||||
unsigned NumArgs;
|
||||
|
||||
public:
|
||||
MultiArgOption(options::ID ID, const char *Name, const OptionGroup *Group,
|
||||
MultiArgOption(OptSpecifier ID, const char *Name, const OptionGroup *Group,
|
||||
const Option *Alias, unsigned NumArgs);
|
||||
|
||||
unsigned getNumArgs() const { return NumArgs; }
|
||||
@ -276,7 +279,7 @@ namespace driver {
|
||||
/// prefixes its (non-empty) value, or is follwed by a value.
|
||||
class JoinedOrSeparateOption : public Option {
|
||||
public:
|
||||
JoinedOrSeparateOption(options::ID ID, const char *Name,
|
||||
JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
@ -291,7 +294,7 @@ namespace driver {
|
||||
/// value and is followed by another value.
|
||||
class JoinedAndSeparateOption : public Option {
|
||||
public:
|
||||
JoinedAndSeparateOption(options::ID ID, const char *Name,
|
||||
JoinedAndSeparateOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias);
|
||||
|
||||
virtual Arg *accept(const InputArgList &Args, unsigned &Index) const;
|
||||
|
@ -1,661 +0,0 @@
|
||||
//===--- Options.def - Driver option info -----------------------*- C++ -*-===//
|
||||
//
|
||||
// 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 driver option information. Users of this file
|
||||
// must define the OPTION macro to make use of this information.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef OPTION
|
||||
#error "Define OPTION prior to including this file!"
|
||||
#endif
|
||||
|
||||
// OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM,
|
||||
// HELPTEXT, METAVARNAME)
|
||||
|
||||
// The NAME value is the option name as a string.
|
||||
|
||||
// The ID is the internal option id, which must be a valid
|
||||
// C++ identifier, and results in a clang::driver::options::OPT_XX
|
||||
// enum constant for XX.
|
||||
//
|
||||
// We want to unambiguously be able to refer to options from the
|
||||
// driver source code, for this reason the option name is mangled into
|
||||
// an id. This mangling isn't guaranteed to have an inverse, but for
|
||||
// practical purposes it does.
|
||||
//
|
||||
// The mangling scheme is to ignore the leading '-', and perform the
|
||||
// following substitutions:
|
||||
// _ => __
|
||||
// - => _
|
||||
// # => _HASH
|
||||
// , => _COMMA
|
||||
// = => _EQ
|
||||
// C++ => CXX
|
||||
|
||||
// The KIND value is the option type, one of Group, Flag, Joined,
|
||||
// Separate, CommaJoined, JoinedOrSeparate, JoinedAndSeparate.
|
||||
|
||||
// The GROUP value is the internal name of the option group, or
|
||||
// INVALID if the option is not part of a group.
|
||||
|
||||
// The ALIAS value is the internal name of an aliased option, or
|
||||
// INVALID if the option is not an alias.
|
||||
|
||||
// The PARAM value is a string containing option flags. Valid values:
|
||||
// d: The option is a "driver" option, and should not be forwarded to
|
||||
// gcc.
|
||||
//
|
||||
// i: The option should not render the name when rendered as an
|
||||
// input (i.e., the option is rendered as values).
|
||||
//
|
||||
// l: The option is a linker input.
|
||||
//
|
||||
// q: Don't report argument unused warnings for this option; this is
|
||||
// useful for options like -static or -dynamic which a user may
|
||||
// always end up passing, even if the platform defaults to (or
|
||||
// only supports) that option.
|
||||
//
|
||||
// u: The option is unsupported, and the driver will reject command
|
||||
// lines that use it.
|
||||
//
|
||||
// S: The option should be rendered separately, even if joined (only
|
||||
// sensible on joined options).
|
||||
//
|
||||
// J: The option should be rendered joined, even if separate (only
|
||||
// sensible on single value separate options).
|
||||
|
||||
// The PARAM value is an arbitrary integer parameter; currently
|
||||
// this is only used for specifying the number of arguments for
|
||||
// Separate options.
|
||||
|
||||
// The HELPTEXT value is the string to print for this option in
|
||||
// --help, or 0 if undocumented.
|
||||
|
||||
// The METAVAR value is the name to use for this values arguments (if
|
||||
// any) in the help text. This must be defined if the help text is
|
||||
// specified and this option takes extra arguments.
|
||||
|
||||
//
|
||||
|
||||
// For now (pre-TableGen, that is) Options must be in order. The
|
||||
// ordering is *almost* lexicographic, with two exceptions. First,
|
||||
// '\0' comes at the end of the alphabet instead of the beginning
|
||||
// (thus options preceed any other options which prefix them). Second,
|
||||
// for options with the same name, the less permissive version should
|
||||
// come first; a Flag option should preceed a Joined option, for
|
||||
// example.
|
||||
|
||||
/////////
|
||||
// Groups
|
||||
|
||||
OPTION("<I group>", I_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<M group>", M_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<T group>", T_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<O group>", O_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<W group>", W_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<X group>", X_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<a group>", a_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<d group>", d_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<f group>", f_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<g group>", g_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<i group>", i_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<clang i group>", clang_i_Group, Group, i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("<m group>", m_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<m x86 features group>", m_x86_Features_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("<u group>", u_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
|
||||
OPTION("<pedantic group>", pedantic_Group, Group, INVALID, INVALID, "", 0, 0, 0)
|
||||
|
||||
// Temporary groups for clang options which we know we don't support,
|
||||
// but don't want to verbosely warn the user about.
|
||||
OPTION("<clang ignored f group>", clang_ignored_f_Group, Group, f_Group,
|
||||
INVALID, "", 0, 0, 0)
|
||||
OPTION("<clang ignored m group>", clang_ignored_m_Group, Group, m_Group,
|
||||
INVALID, "", 0, 0, 0)
|
||||
|
||||
//////////
|
||||
// Options
|
||||
|
||||
OPTION("-###", _HASH_HASH_HASH, Flag, INVALID, INVALID, "d", 0,
|
||||
"Print the commands to run for this compilation", 0)
|
||||
OPTION("--CLASSPATH=", _CLASSPATH_EQ, Joined, INVALID, fclasspath_EQ, "", 0, 0, 0)
|
||||
OPTION("--CLASSPATH", _CLASSPATH, Separate, INVALID, fclasspath_EQ, "J", 0, 0, 0)
|
||||
OPTION("--all-warnings", _all_warnings, Flag, INVALID, Wall, "", 0, 0, 0)
|
||||
OPTION("--analyze-auto", _analyze_auto, Flag, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("--analyzer-no-default-checks", _analyzer_no_default_checks, Flag, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("--analyzer-output", _analyzer_output, JoinedOrSeparate, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("--analyze", _analyze, Flag, INVALID, INVALID, "d", 0,
|
||||
"Run the static analyzer", 0)
|
||||
OPTION("--ansi", _ansi, Flag, INVALID, ansi, "", 0, 0, 0)
|
||||
OPTION("--assemble", _assemble, Flag, INVALID, S, "", 0, 0, 0)
|
||||
OPTION("--assert=", _assert_EQ, Joined, INVALID, A, "S", 0, 0, 0)
|
||||
OPTION("--assert", _assert, Separate, INVALID, A, "", 0, 0, 0)
|
||||
OPTION("--bootclasspath=", _bootclasspath_EQ, Joined, INVALID, fbootclasspath_EQ, "", 0, 0, 0)
|
||||
OPTION("--bootclasspath", _bootclasspath, Separate, INVALID, fbootclasspath_EQ, "J", 0, 0, 0)
|
||||
OPTION("--classpath=", _classpath_EQ, Joined, INVALID, fclasspath_EQ, "", 0, 0, 0)
|
||||
OPTION("--classpath", _classpath, Separate, INVALID, fclasspath_EQ, "J", 0, 0, 0)
|
||||
OPTION("--combine", _combine, Flag, INVALID, combine, "u", 0, 0, 0)
|
||||
OPTION("--comments-in-macros", _comments_in_macros, Flag, INVALID, CC, "", 0, 0, 0)
|
||||
OPTION("--comments", _comments, Flag, INVALID, C, "", 0, 0, 0)
|
||||
OPTION("--compile", _compile, Flag, INVALID, c, "", 0, 0, 0)
|
||||
OPTION("--constant-cfstrings", _constant_cfstrings, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("--coverage", _coverage, Flag, INVALID, coverage, "", 0, 0, 0)
|
||||
OPTION("--debug=", _debug_EQ, Joined, INVALID, g_Flag, "u", 0, 0, 0)
|
||||
OPTION("--debug", _debug, Flag, INVALID, g_Flag, "u", 0, 0, 0)
|
||||
OPTION("--define-macro=", _define_macro_EQ, Joined, INVALID, D, "", 0, 0, 0)
|
||||
OPTION("--define-macro", _define_macro, Separate, INVALID, D, "J", 0, 0, 0)
|
||||
OPTION("--dependencies", _dependencies, Flag, INVALID, M, "", 0, 0, 0)
|
||||
OPTION("--encoding=", _encoding_EQ, Joined, INVALID, fencoding_EQ, "", 0, 0, 0)
|
||||
OPTION("--encoding", _encoding, Separate, INVALID, fencoding_EQ, "J", 0, 0, 0)
|
||||
OPTION("--entry", _entry, Flag, INVALID, e, "", 0, 0, 0)
|
||||
OPTION("--extdirs=", _extdirs_EQ, Joined, INVALID, fextdirs_EQ, "", 0, 0, 0)
|
||||
OPTION("--extdirs", _extdirs, Separate, INVALID, fextdirs_EQ, "J", 0, 0, 0)
|
||||
OPTION("--extra-warnings", _extra_warnings, Flag, INVALID, W_Joined, "", 0, 0, 0)
|
||||
OPTION("--for-linker=", _for_linker_EQ, Joined, INVALID, Xlinker, "liS", 0, 0, 0)
|
||||
OPTION("--for-linker", _for_linker, Separate, INVALID, Xlinker, "li", 0, 0, 0)
|
||||
OPTION("--force-link=", _force_link_EQ, Joined, INVALID, u, "S", 0, 0, 0)
|
||||
OPTION("--force-link", _force_link, Separate, INVALID, u, "", 0, 0, 0)
|
||||
OPTION("--help-hidden", _help_hidden, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("--help", _help, Flag, INVALID, INVALID, "", 0,
|
||||
"Display available options", 0)
|
||||
OPTION("--imacros=", _imacros_EQ, Joined, INVALID, imacros, "S", 0, 0, 0)
|
||||
OPTION("--imacros", _imacros, Separate, INVALID, imacros, "", 0, 0, 0)
|
||||
OPTION("--include-barrier", _include_barrier, Flag, INVALID, I_, "", 0, 0, 0)
|
||||
OPTION("--include-directory-after=", _include_directory_after_EQ, Joined, INVALID, idirafter, "S", 0, 0, 0)
|
||||
OPTION("--include-directory-after", _include_directory_after, Separate, INVALID, idirafter, "", 0, 0, 0)
|
||||
OPTION("--include-directory=", _include_directory_EQ, Joined, INVALID, I, "", 0, 0, 0)
|
||||
OPTION("--include-directory", _include_directory, Separate, INVALID, I, "J", 0, 0, 0)
|
||||
OPTION("--include-prefix=", _include_prefix_EQ, Joined, INVALID, iprefix, "S", 0, 0, 0)
|
||||
OPTION("--include-prefix", _include_prefix, Separate, INVALID, iprefix, "", 0, 0, 0)
|
||||
OPTION("--include-with-prefix-after=", _include_with_prefix_after_EQ, Joined, INVALID, iwithprefix, "S", 0, 0, 0)
|
||||
OPTION("--include-with-prefix-after", _include_with_prefix_after, Separate, INVALID, iwithprefix, "", 0, 0, 0)
|
||||
OPTION("--include-with-prefix-before=", _include_with_prefix_before_EQ, Joined, INVALID, iwithprefixbefore, "S", 0, 0, 0)
|
||||
OPTION("--include-with-prefix-before", _include_with_prefix_before, Separate, INVALID, iwithprefixbefore, "", 0, 0, 0)
|
||||
OPTION("--include-with-prefix=", _include_with_prefix_EQ, Joined, INVALID, iwithprefix, "S", 0, 0, 0)
|
||||
OPTION("--include-with-prefix", _include_with_prefix, Separate, INVALID, iwithprefix, "", 0, 0, 0)
|
||||
OPTION("--include=", _include_EQ, Joined, INVALID, include, "S", 0, 0, 0)
|
||||
OPTION("--include", _include, Separate, INVALID, include, "", 0, 0, 0)
|
||||
OPTION("--language=", _language_EQ, Joined, INVALID, x, "S", 0, 0, 0)
|
||||
OPTION("--language", _language, Separate, INVALID, x, "", 0, 0, 0)
|
||||
OPTION("--library-directory=", _library_directory_EQ, Joined, INVALID, L, "S", 0, 0, 0)
|
||||
OPTION("--library-directory", _library_directory, Separate, INVALID, L, "", 0, 0, 0)
|
||||
OPTION("--machine-=", _machine__EQ, Joined, INVALID, m_Joined, "u", 0, 0, 0)
|
||||
OPTION("--machine-", _machine_, Joined, INVALID, m_Joined, "u", 0, 0, 0)
|
||||
OPTION("--machine=", _machine_EQ, Joined, INVALID, m_Joined, "", 0, 0, 0)
|
||||
OPTION("--machine", _machine, Separate, INVALID, m_Joined, "J", 0, 0, 0)
|
||||
OPTION("--no-integrated-cpp", _no_integrated_cpp, Flag, INVALID, no_integrated_cpp, "", 0, 0, 0)
|
||||
OPTION("--no-line-commands", _no_line_commands, Flag, INVALID, P, "", 0, 0, 0)
|
||||
OPTION("--no-standard-includes", _no_standard_includes, Flag, INVALID, nostdinc, "", 0, 0, 0)
|
||||
OPTION("--no-standard-libraries", _no_standard_libraries, Flag, INVALID, nostdlib, "", 0, 0, 0)
|
||||
OPTION("--no-undefined", _no_undefined, Flag, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("--no-warnings", _no_warnings, Flag, INVALID, w, "", 0, 0, 0)
|
||||
OPTION("--optimize=", _optimize_EQ, Joined, INVALID, O, "u", 0, 0, 0)
|
||||
OPTION("--optimize", _optimize, Flag, INVALID, O, "u", 0, 0, 0)
|
||||
OPTION("--output-class-directory=", _output_class_directory_EQ, Joined, INVALID, foutput_class_dir_EQ, "", 0, 0, 0)
|
||||
OPTION("--output-class-directory", _output_class_directory, Separate, INVALID, foutput_class_dir_EQ, "J", 0, 0, 0)
|
||||
OPTION("--output=", _output_EQ, Joined, INVALID, o, "S", 0, 0, 0)
|
||||
OPTION("--output", _output, Separate, INVALID, o, "", 0, 0, 0)
|
||||
OPTION("--param=", _param_EQ, Joined, INVALID, _param, "S", 0, 0, 0)
|
||||
OPTION("--param", _param, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("--pass-exit-codes", _pass_exit_codes, Flag, INVALID, pass_exit_codes, "", 0, 0, 0)
|
||||
OPTION("--pedantic-errors", _pedantic_errors, Flag, INVALID, pedantic_errors, "", 0, 0, 0)
|
||||
OPTION("--pedantic", _pedantic, Flag, INVALID, pedantic, "", 0, 0, 0)
|
||||
OPTION("--pipe", _pipe, Flag, INVALID, pipe, "d", 0, 0, 0)
|
||||
OPTION("--prefix=", _prefix_EQ, Joined, INVALID, B, "S", 0, 0, 0)
|
||||
OPTION("--prefix", _prefix, Separate, INVALID, B, "", 0, 0, 0)
|
||||
OPTION("--preprocess", _preprocess, Flag, INVALID, E, "", 0, 0, 0)
|
||||
OPTION("--print-file-name=", _print_file_name_EQ, Joined, INVALID, print_file_name_EQ, "", 0, 0, 0)
|
||||
OPTION("--print-file-name", _print_file_name, Separate, INVALID, print_file_name_EQ, "", 0, 0, 0)
|
||||
OPTION("--print-libgcc-file-name", _print_libgcc_file_name, Flag, INVALID, print_libgcc_file_name, "", 0, 0, 0)
|
||||
OPTION("--print-missing-file-dependencies", _print_missing_file_dependencies, Flag, INVALID, MG, "", 0, 0, 0)
|
||||
OPTION("--print-multi-directory", _print_multi_directory, Flag, INVALID, print_multi_directory, "", 0, 0, 0)
|
||||
OPTION("--print-multi-lib", _print_multi_lib, Flag, INVALID, print_multi_lib, "", 0, 0, 0)
|
||||
OPTION("--print-multi-os-directory", _print_multi_os_directory, Flag, INVALID, print_multi_os_directory, "", 0, 0, 0)
|
||||
OPTION("--print-prog-name=", _print_prog_name_EQ, Joined, INVALID, print_prog_name_EQ, "", 0, 0, 0)
|
||||
OPTION("--print-prog-name", _print_prog_name, Separate, INVALID, print_prog_name_EQ, "", 0, 0, 0)
|
||||
OPTION("--print-search-dirs", _print_search_dirs, Flag, INVALID, print_search_dirs, "", 0, 0, 0)
|
||||
OPTION("--profile-blocks", _profile_blocks, Flag, INVALID, a, "", 0, 0, 0)
|
||||
OPTION("--profile", _profile, Flag, INVALID, p, "", 0, 0, 0)
|
||||
OPTION("--relocatable-pch", _relocatable_pch, Flag, INVALID, INVALID, "", 0,
|
||||
"Build a relocatable precompiled header", 0)
|
||||
OPTION("--resource=", _resource_EQ, Joined, INVALID, fcompile_resource_EQ, "", 0, 0, 0)
|
||||
OPTION("--resource", _resource, Separate, INVALID, fcompile_resource_EQ, "J", 0, 0, 0)
|
||||
OPTION("--save-temps", _save_temps, Flag, INVALID, save_temps, "", 0, 0, 0)
|
||||
OPTION("--shared", _shared, Flag, INVALID, shared, "", 0, 0, 0)
|
||||
OPTION("--signed-char", _signed_char, Flag, INVALID, fsigned_char, "", 0, 0, 0)
|
||||
OPTION("--specs=", _specs_EQ, Joined, INVALID, specs_EQ, "u", 0, 0, 0)
|
||||
OPTION("--specs", _specs, Separate, INVALID, specs_EQ, "uJ", 0, 0, 0)
|
||||
OPTION("--static", _static, Flag, INVALID, static, "", 0, 0, 0)
|
||||
OPTION("--std=", _std_EQ, Joined, INVALID, std_EQ, "", 0, 0, 0)
|
||||
OPTION("--std", _std, Separate, INVALID, std_EQ, "J", 0, 0, 0)
|
||||
OPTION("--sysroot=", _sysroot_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("--sysroot", _sysroot, Separate, INVALID, _sysroot_EQ, "J", 0, 0, 0)
|
||||
OPTION("--target-help", _target_help, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("--trace-includes", _trace_includes, Flag, INVALID, H, "", 0, 0, 0)
|
||||
OPTION("--traditional-cpp", _traditional_cpp, Flag, INVALID, traditional_cpp, "", 0, 0, 0)
|
||||
OPTION("--traditional", _traditional, Flag, INVALID, traditional, "", 0, 0, 0)
|
||||
OPTION("--trigraphs", _trigraphs, Flag, INVALID, trigraphs, "", 0, 0, 0)
|
||||
OPTION("--undefine-macro=", _undefine_macro_EQ, Joined, INVALID, U, "", 0, 0, 0)
|
||||
OPTION("--undefine-macro", _undefine_macro, Separate, INVALID, U, "J", 0, 0, 0)
|
||||
OPTION("--unsigned-char", _unsigned_char, Flag, INVALID, funsigned_char, "", 0, 0, 0)
|
||||
OPTION("--user-dependencies", _user_dependencies, Flag, INVALID, MM, "", 0, 0, 0)
|
||||
OPTION("--verbose", _verbose, Flag, INVALID, v, "", 0, 0, 0)
|
||||
OPTION("--version", _version, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("--warn-=", _warn__EQ, Joined, INVALID, W_Joined, "u", 0, 0, 0)
|
||||
OPTION("--warn-", _warn_, Joined, INVALID, W_Joined, "u", 0, 0, 0)
|
||||
OPTION("--write-dependencies", _write_dependencies, Flag, INVALID, MD, "", 0, 0, 0)
|
||||
OPTION("--write-user-dependencies", _write_user_dependencies, Flag, INVALID, MMD, "", 0, 0, 0)
|
||||
OPTION("--", _, Joined, INVALID, f, "u", 0, 0, 0)
|
||||
OPTION("-A", A, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-B", B, JoinedOrSeparate, INVALID, INVALID, "u", 0, 0, 0)
|
||||
OPTION("-CC", CC, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-C", C, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-D", D, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-E", E, Flag, INVALID, INVALID, "d", 0,
|
||||
"Only run the preprocessor", 0)
|
||||
OPTION("-F", F, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-H", H, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-I-", I_, Flag, I_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-I", I, JoinedOrSeparate, I_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-L", L, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MD", MD, Flag, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MF", MF, JoinedOrSeparate, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MG", MG, Flag, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MMD", MMD, Flag, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MM", MM, Flag, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MP", MP, Flag, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MQ", MQ, JoinedOrSeparate, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-MT", MT, JoinedOrSeparate, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Mach", Mach, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-M", M, Flag, M_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-O4", O4, Joined, O_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-ObjC++", ObjCXX, Flag, INVALID, INVALID, "d", 0,
|
||||
"Treat source input files as Objective-C++ inputs", 0)
|
||||
OPTION("-ObjC", ObjC, Flag, INVALID, INVALID, "d", 0,
|
||||
"Treat source input files as Objective-C inputs", 0)
|
||||
OPTION("-O", O, Joined, O_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-P", P, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Qn", Qn, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Qunused-arguments", Qunused_arguments, Flag, INVALID, INVALID, "d", 0,
|
||||
"Don't emit warning for unused driver arguments", 0)
|
||||
OPTION("-Q", Q, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-R", R, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-S", S, Flag, INVALID, INVALID, "d", 0,
|
||||
"Only run preprocess and compilation steps", 0)
|
||||
OPTION("-Tbss", Tbss, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Tdata", Tdata, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Ttext", Ttext, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-T", T, JoinedOrSeparate, T_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-U", U, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-V", V, JoinedOrSeparate, INVALID, INVALID, "du", 0, 0, 0)
|
||||
OPTION("-Wa,", Wa_COMMA, CommaJoined, INVALID, INVALID, "", 0,
|
||||
"Pass the comma separated arguments in <arg> to the assembler", "<arg>")
|
||||
OPTION("-Wall", Wall, Flag, W_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Wextra", Wextra, Flag, W_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Wl,", Wl_COMMA, CommaJoined, INVALID, INVALID, "li", 0,
|
||||
"Pass the comma separated arguments in <arg> to the linker", "<arg>")
|
||||
OPTION("-Wno-nonportable-cfstrings", Wno_nonportable_cfstrings, Joined, W_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Wnonportable-cfstrings", Wnonportable_cfstrings, Joined, W_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Wp,", Wp_COMMA, CommaJoined, INVALID, INVALID, "", 0,
|
||||
"Pass the comma separated arguments in <arg> to the preprocessor", "<arg>")
|
||||
OPTION("-W", W_Joined, Joined, W_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Xanalyzer", Xanalyzer, Separate, INVALID, INVALID, "", 0,
|
||||
"Pass <arg> to the static analyzer", "<arg>")
|
||||
OPTION("-Xarch_", Xarch__, JoinedAndSeparate, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-Xassembler", Xassembler, Separate, INVALID, INVALID, "", 0,
|
||||
"Pass <arg> to the assembler", "<arg>")
|
||||
OPTION("-Xclang", Xclang, Separate, INVALID, INVALID, "", 0,
|
||||
"Pass <arg> to the clang compiler", "<arg>")
|
||||
OPTION("-Xlinker", Xlinker, Separate, INVALID, INVALID, "li", 0,
|
||||
"Pass <arg> to the linker", "<arg>")
|
||||
OPTION("-Xpreprocessor", Xpreprocessor, Separate, INVALID, INVALID, "", 0,
|
||||
"Pass <arg> to the preprocessor", "<arg>")
|
||||
OPTION("-X", X_Flag, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-X", X_Joined, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Z", Z_Flag, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-Z", Z_Joined, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-all_load", all__load, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-allowable_client", allowable__client, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-ansi", ansi, Flag, a_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-arch_errors_fatal", arch__errors__fatal, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-arch", arch, Separate, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-a", a, Joined, a_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-bind_at_load", bind__at__load, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-bundle_loader", bundle__loader, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-bundle", bundle, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-b", b, JoinedOrSeparate, INVALID, INVALID, "u", 0, 0, 0)
|
||||
OPTION("-client_name", client__name, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-combine", combine, Flag, INVALID, INVALID, "du", 0, 0, 0)
|
||||
OPTION("-compatibility_version", compatibility__version, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-coverage", coverage, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-cpp-precomp", cpp_precomp, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-current_version", current__version, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-c", c, Flag, INVALID, INVALID, "d", 0,
|
||||
"Only run preprocess, compile, and assemble steps", 0)
|
||||
OPTION("-dA", dA, Flag, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dD", dD, Flag, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dM", dM, Flag, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dead_strip", dead__strip, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dependency-file", dependency_file, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dumpmachine", dumpmachine, Flag, INVALID, INVALID, "u", 0, 0, 0)
|
||||
OPTION("-dumpspecs", dumpspecs, Flag, INVALID, INVALID, "u", 0, 0, 0)
|
||||
OPTION("-dumpversion", dumpversion, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dylib_file", dylib__file, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dylinker_install_name", dylinker__install__name, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dylinker", dylinker, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dynamiclib", dynamiclib, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-dynamic", dynamic, Flag, INVALID, INVALID, "q", 0, 0, 0)
|
||||
OPTION("-d", d_Flag, Flag, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-d", d_Joined, Joined, d_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-emit-ast", emit_ast, Flag, INVALID, INVALID, "", 0,
|
||||
"Emit Clang AST files for source inputs", 0)
|
||||
OPTION("-emit-llvm", emit_llvm, Flag, INVALID, INVALID, "", 0,
|
||||
"Use the LLVM representation for assembler and object files", 0)
|
||||
OPTION("-exported_symbols_list", exported__symbols__list, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-e", e, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fPIC", fPIC, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fPIE", fPIE, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fapple-kext", fapple_kext, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fasm-blocks", fasm_blocks, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fastcp", fastcp, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fastf", fastf, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fast", fast, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fasynchronous-unwind-tables", fasynchronous_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fblock-introspection", fblock_introspection, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fblocks", fblocks, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fbootclasspath=", fbootclasspath_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fbuiltin-strcat", fbuiltin_strcat, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fbuiltin-strcpy", fbuiltin_strcpy, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fbuiltin", fbuiltin, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fclasspath=", fclasspath_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fcolor-diagnostics", fcolor_diagnostics, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fcommon", fcommon, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fcompile-resource=", fcompile_resource_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fconstant-cfstrings", fconstant_cfstrings, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fconstant-string-class=", fconstant_string_class_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fcreate-profile", fcreate_profile, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fdebug-pass-arguments", fdebug_pass_arguments, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fdebug-pass-structure", fdebug_pass_structure, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fdiagnostics-fixit-info", fdiagnostics_fixit_info, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fdiagnostics-print-source-range-info", fdiagnostics_print_source_range_info, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fdiagnostics-show-option", fdiagnostics_show_option, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fdollars-in-identifiers", fdollars_in_identifiers, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-feliminate-unused-debug-symbols", feliminate_unused_debug_symbols, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-femit-all-decls", femit_all_decls, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fencoding=", fencoding_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fexceptions", fexceptions, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fextdirs=", fextdirs_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-ffreestanding", ffreestanding, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fgnu-runtime", fgnu_runtime, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fheinous-gnu-extensions", fheinous_gnu_extensions, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-filelist", filelist, Separate, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-findirect-virtual-calls", findirect_virtual_calls, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-finline-functions", finline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-finline", finline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fkeep-inline-functions", fkeep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-flat_namespace", flat__namespace, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-flax-vector-conversions", flax_vector_conversions, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-flimited-precision=", flimited_precision_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-flto", flto, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fmath-errno", fmath_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fmerge-all-constants", fmerge_all_constants, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fmessage-length=", fmessage_length_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fms-extensions", fms_extensions, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fmudflapth", fmudflapth, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fmudflap", fmudflap, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fnested-functions", fnested_functions, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fnext-runtime", fnext_runtime, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-asynchronous-unwind-tables", fno_asynchronous_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-blocks", fno_blocks, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-builtin-strcat", fno_builtin_strcat, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-builtin-strcpy", fno_builtin_strcpy, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-builtin", fno_builtin, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-caret-diagnostics", fno_caret_diagnostics, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-color-diagnostics", fno_color_diagnostics, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-common", fno_common, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-constant-cfstrings", fno_constant_cfstrings, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-diagnostics-fixit-info", fno_diagnostics_fixit_info, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-diagnostics-show-option", fno_diagnostics_show_option, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-dollars-in-identifiers", fno_dollars_in_identifiers, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-eliminate-unused-debug-symbols", fno_eliminate_unused_debug_symbols, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-exceptions", fno_exceptions, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-inline-functions", fno_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-inline", fno_inline, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-keep-inline-functions", fno_keep_inline_functions, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-math-errno", fno_math_errno, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-merge-all-constants", fno_merge_all_constants, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-ms-extensions", fno_ms_extensions, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-omit-frame-pointer", fno_omit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-pascal-strings", fno_pascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-rtti", fno_rtti, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-show-column", fno_show_column, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-show-source-location", fno_show_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-stack-protector", fno_stack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-strict-aliasing", fno_strict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-unit-at-a-time", fno_unit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-unwind-tables", fno_unwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-working-directory", fno_working_directory, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fno-zero-initialized-in-bss", fno_zero_initialized_in_bss, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-atdefs", fobjc_atdefs, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-call-cxx-cdtors", fobjc_call_cxx_cdtors, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-gc-only", fobjc_gc_only, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-gc", fobjc_gc, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-new-property", fobjc_new_property, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-nonfragile-abi", fobjc_nonfragile_abi, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc-sender-dependent-dispatch", fobjc_sender_dependent_dispatch, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fobjc", fobjc, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fomit-frame-pointer", fomit_frame_pointer, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fopenmp", fopenmp, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-force_cpusubtype_ALL", force__cpusubtype__ALL, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-force_flat_namespace", force__flat__namespace, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-foutput-class-dir=", foutput_class_dir_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fpascal-strings", fpascal_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fpch-preprocess", fpch_preprocess, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fpic", fpic, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fpie", fpie, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fprofile-arcs", fprofile_arcs, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fprofile-generate", fprofile_generate, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-framework", framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-frtti", frtti, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fshort-wchar", fshort_wchar, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fshow-source-location", fshow_source_location, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fsigned-bitfields", fsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fsigned-char", fsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fstack-protector-all", fstack_protector_all, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fstack-protector", fstack_protector, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fstrict-aliasing", fstrict_aliasing, Flag, clang_ignored_f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fsyntax-only", fsyntax_only, Flag, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-ftemplate-depth-", ftemplate_depth_, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fterminated-vtables", fterminated_vtables, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-ftime-report", ftime_report, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-ftrapv", ftrapv, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-funit-at-a-time", funit_at_a_time, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-funsigned-bitfields", funsigned_bitfields, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-funsigned-char", funsigned_char, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-funwind-tables", funwind_tables, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fverbose-asm", fverbose_asm, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fvisibility=", fvisibility_EQ, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fwritable-strings", fwritable_strings, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-fzero-initialized-in-bss", fzero_initialized_in_bss, Flag, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-f", f, Joined, f_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-g0", g0, Joined, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-g3", g3, Joined, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-gfull", gfull, Joined, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-gstabs", gstabs, Joined, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-gused", gused, Joined, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-g", g_Flag, Flag, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-g", g_Joined, Joined, g_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-headerpad_max_install_names", headerpad__max__install__names, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-idirafter", idirafter, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-iframework", iframework, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-imacros", imacros, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-image_base", image__base, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-include", include, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-init", init, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-install_name", install__name, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-iprefix", iprefix, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-iquote", iquote, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-isysroot", isysroot, JoinedOrSeparate, i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-isystem", isystem, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-iwithprefixbefore", iwithprefixbefore, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-iwithprefix", iwithprefix, JoinedOrSeparate, clang_i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-iwithsysroot", iwithsysroot, JoinedOrSeparate, i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-i", i, Joined, i_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-keep_private_externs", keep__private__externs, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-l", l, JoinedOrSeparate, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-m32", m32, Flag, m_Group, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-m3dnowa", m3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-m3dnow", m3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-m64", m64, Flag, m_Group, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-mabi=", mabi_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-march=", march_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-mcmodel=", mcmodel_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-mconstant-cfstrings", mconstant_cfstrings, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mcpu=", mcpu_EQ, Joined, m_Group, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-mdynamic-no-pic", mdynamic_no_pic, Joined, m_Group, INVALID, "q", 0, 0, 0)
|
||||
OPTION("-mfix-and-continue", mfix_and_continue, Flag, clang_ignored_m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mfloat-abi=", mfloat_abi_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mhard-float", mhard_float, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-miphoneos-version-min=", miphoneos_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mkernel", mkernel, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mllvm", mllvm, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mmacosx-version-min=", mmacosx_version_min_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mmmx", mmmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-3dnowa", mno_3dnowa, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-3dnow", mno_3dnow, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-constant-cfstrings", mno_constant_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-mmx", mno_mmx, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-pascal-strings", mno_pascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-red-zone", mno_red_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-soft-float", mno_soft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-sse2", mno_sse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-sse3", mno_sse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-sse4a", mno_sse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-sse4", mno_sse4, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-sse", mno_sse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-ssse3", mno_ssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-thumb", mno_thumb, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mno-warn-nonportable-cfstrings", mno_warn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mpascal-strings", mpascal_strings, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mred-zone", mred_zone, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-msoft-float", msoft_float, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-msse2", msse2, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-msse3", msse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-msse4a", msse4a, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-msse4", msse4, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-msse", msse, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mssse3", mssse3, Flag, m_x86_Features_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mthumb", mthumb, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mtune=", mtune_EQ, Joined, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-multi_module", multi__module, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-multiply_defined_unused", multiply__defined__unused, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-multiply_defined", multiply__defined, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-mwarn-nonportable-cfstrings", mwarn_nonportable_cfstrings, Flag, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-m", m_Separate, Separate, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-m", m_Joined, Joined, m_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-no-cpp-precomp", no_cpp_precomp, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-no-integrated-cpp", no_integrated_cpp, Flag, INVALID, INVALID, "d", 0, 0, 0)
|
||||
OPTION("-no_dead_strip_inits_and_terms", no__dead__strip__inits__and__terms, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nobuiltininc", nobuiltininc, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nodefaultlibs", nodefaultlibs, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nofixprebinding", nofixprebinding, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nolibc", nolibc, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nomultidefs", nomultidefs, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-noprebind", noprebind, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-noseglinkedit", noseglinkedit, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nostartfiles", nostartfiles, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nostdinc", nostdinc, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-nostdlib", nostdlib, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-object", object, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-o", o, JoinedOrSeparate, INVALID, INVALID, "di", 0,
|
||||
"Write output to <file>", "<file>")
|
||||
OPTION("-pagezero_size", pagezero__size, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-pass-exit-codes", pass_exit_codes, Flag, INVALID, INVALID, "u", 0, 0, 0)
|
||||
OPTION("-pedantic-errors", pedantic_errors, Flag, pedantic_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-pedantic", pedantic, Flag, pedantic_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-pg", pg, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-pipe", pipe, Flag, INVALID, INVALID, "", 0,
|
||||
"Use pipes between commands, when possible", 0)
|
||||
OPTION("-prebind_all_twolevel_modules", prebind__all__twolevel__modules, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-prebind", prebind, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-preload", preload, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-print-file-name=", print_file_name_EQ, Joined, INVALID, INVALID, "", 0,
|
||||
"Print the full library path of <file>", "<file>")
|
||||
OPTION("-print-ivar-layout", print_ivar_layout, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-print-libgcc-file-name", print_libgcc_file_name, Flag, INVALID, INVALID, "", 0,
|
||||
"Print the library path for \"libgcc.a\"", 0)
|
||||
OPTION("-print-multi-directory", print_multi_directory, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-print-multi-lib", print_multi_lib, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-print-multi-os-directory", print_multi_os_directory, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-print-prog-name=", print_prog_name_EQ, Joined, INVALID, INVALID, "", 0,
|
||||
"Print the full program path of <name>", "<name>")
|
||||
OPTION("-print-search-dirs", print_search_dirs, Flag, INVALID, INVALID, "", 0,
|
||||
"Print the paths used for finding libraries and programs", 0)
|
||||
OPTION("-private_bundle", private__bundle, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-pthreads", pthreads, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-pthread", pthread, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-p", p, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-read_only_relocs", read__only__relocs, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-remap", remap, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-rpath", rpath, Separate, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-r", r, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-save-temps", save_temps, Flag, INVALID, INVALID, "d", 0,
|
||||
"Save intermediate compilation results", 0)
|
||||
OPTION("-sectalign", sectalign, MultiArg, INVALID, INVALID, "", 3, 0, 0)
|
||||
OPTION("-sectcreate", sectcreate, MultiArg, INVALID, INVALID, "", 3, 0, 0)
|
||||
OPTION("-sectobjectsymbols", sectobjectsymbols, MultiArg, INVALID, INVALID, "", 2, 0, 0)
|
||||
OPTION("-sectorder", sectorder, MultiArg, INVALID, INVALID, "", 3, 0, 0)
|
||||
OPTION("-seg1addr", seg1addr, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-seg_addr_table_filename", seg__addr__table__filename, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-seg_addr_table", seg__addr__table, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-segaddr", segaddr, MultiArg, INVALID, INVALID, "", 2, 0, 0)
|
||||
OPTION("-segcreate", segcreate, MultiArg, INVALID, INVALID, "", 3, 0, 0)
|
||||
OPTION("-seglinkedit", seglinkedit, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-segprot", segprot, MultiArg, INVALID, INVALID, "", 3, 0, 0)
|
||||
OPTION("-segs_read_only_addr", segs__read__only__addr, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-segs_read_write_addr", segs__read__write__addr, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-segs_read_", segs__read__, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-shared-libgcc", shared_libgcc, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-shared", shared, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-single_module", single__module, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-specs=", specs_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-specs", specs, Separate, INVALID, INVALID, "u", 0, 0, 0)
|
||||
OPTION("-static-libgcc", static_libgcc, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-static", static, Flag, INVALID, INVALID, "q", 0, 0, 0)
|
||||
OPTION("-std-default=", std_default_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-std=", std_EQ, Joined, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-sub_library", sub__library, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-sub_umbrella", sub__umbrella, JoinedOrSeparate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-s", s, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-time", time, Flag, INVALID, INVALID, "", 0,
|
||||
"Time individual commands", 0)
|
||||
OPTION("-traditional-cpp", traditional_cpp, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-traditional", traditional, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-trigraphs", trigraphs, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-twolevel_namespace_hints", twolevel__namespace__hints, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-twolevel_namespace", twolevel__namespace, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-t", t, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-umbrella", umbrella, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-undefined", undefined, JoinedOrSeparate, u_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-undef", undef, Flag, u_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-unexported_symbols_list", unexported__symbols__list, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-u", u, JoinedOrSeparate, u_Group, INVALID, "", 0, 0, 0)
|
||||
OPTION("-v", v, Flag, INVALID, INVALID, "", 0,
|
||||
"Show commands to run and use verbose output", 0)
|
||||
OPTION("-weak-l", weak_l, Joined, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-weak_framework", weak__framework, Separate, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-weak_library", weak__library, Separate, INVALID, INVALID, "l", 0, 0, 0)
|
||||
OPTION("-weak_reference_mismatches", weak__reference__mismatches, Separate, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-whatsloaded", whatsloaded, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-whyload", whyload, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-w", w, Flag, INVALID, INVALID, "", 0, 0, 0)
|
||||
OPTION("-x", x, JoinedOrSeparate, INVALID, INVALID, "d", 0,
|
||||
"Treat subsequent input files as having type <language>", "<language>")
|
||||
OPTION("-y", y, Joined, INVALID, INVALID, "", 0, 0, 0)
|
@ -7,11 +7,13 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef CLANG_DRIVER_OPTIONS_H_
|
||||
#define CLANG_DRIVER_OPTIONS_H_
|
||||
#ifndef CLANG_DRIVER_OPTIONS_H
|
||||
#define CLANG_DRIVER_OPTIONS_H
|
||||
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
class OptTable;
|
||||
|
||||
namespace options {
|
||||
enum ID {
|
||||
OPT_INVALID = 0, // This is not an option ID.
|
||||
@ -19,71 +21,13 @@ namespace options {
|
||||
OPT_UNKNOWN, // Reserved ID for unknown option.
|
||||
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR) OPT_##ID,
|
||||
#include "clang/Driver/Options.def"
|
||||
#include "clang/Driver/Options.inc"
|
||||
LastOption
|
||||
#undef OPTION
|
||||
};
|
||||
}
|
||||
|
||||
class Arg;
|
||||
class InputArgList;
|
||||
class Option;
|
||||
|
||||
/// OptTable - Provide access to the Option info table.
|
||||
///
|
||||
/// The OptTable class provides a layer of indirection which allows
|
||||
/// Option instance to be created lazily. In the common case, only a
|
||||
/// few options will be needed at runtime; the OptTable class
|
||||
/// maintains enough information to parse command lines without
|
||||
/// instantiating Options, while letting other parts of the driver
|
||||
/// still use Option instances where convient.
|
||||
class OptTable {
|
||||
/// The table of options which have been constructed, indexed by
|
||||
/// option::ID - 1.
|
||||
mutable Option **Options;
|
||||
|
||||
/// The index of the first option which can be parsed (i.e., is
|
||||
/// not a special option like 'input' or 'unknown', and is not an
|
||||
/// option group).
|
||||
unsigned FirstSearchableOption;
|
||||
|
||||
Option *constructOption(options::ID id) const;
|
||||
|
||||
public:
|
||||
OptTable();
|
||||
~OptTable();
|
||||
|
||||
unsigned getNumOptions() const;
|
||||
|
||||
const char *getOptionName(options::ID id) const;
|
||||
|
||||
/// getOption - Get the given \arg id's Option instance, lazily
|
||||
/// creating it if necessary.
|
||||
const Option *getOption(options::ID id) const;
|
||||
|
||||
/// getOptionKind - Get the kind of the given option.
|
||||
unsigned getOptionKind(options::ID id) const;
|
||||
|
||||
/// getOptionHelpText - Get the help text to use to describe this
|
||||
/// option.
|
||||
const char *getOptionHelpText(options::ID id) const;
|
||||
|
||||
/// getOptionMetaVar - Get the meta-variable name to use when
|
||||
/// describing this options values in the help text.
|
||||
const char *getOptionMetaVar(options::ID id) const;
|
||||
|
||||
/// parseOneArg - Parse a single argument; returning the new
|
||||
/// argument and updating Index.
|
||||
///
|
||||
/// \param [in] [out] Index - The current parsing position in the
|
||||
/// argument string list; on return this will be the index of the
|
||||
/// next argument string to parse.
|
||||
///
|
||||
/// \return - The parsed argument, or 0 if the argument is missing
|
||||
/// values (in which case Index still points at the conceptual
|
||||
/// next argument string to parse).
|
||||
Arg *ParseOneArg(const InputArgList &Args, unsigned &Index) const;
|
||||
};
|
||||
OptTable *createDriverOptTable();
|
||||
}
|
||||
}
|
||||
|
||||
|
607
include/clang/Driver/Options.td
Normal file
607
include/clang/Driver/Options.td
Normal file
@ -0,0 +1,607 @@
|
||||
//===--- DriverOptions.td - Options for clang -----------------------------===//
|
||||
//
|
||||
// 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 options accepted by clang.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Include the common option parsing interfaces.
|
||||
include "OptParser.td"
|
||||
|
||||
/////////
|
||||
// Groups
|
||||
|
||||
def I_Group : OptionGroup<"<I group>">;
|
||||
def M_Group : OptionGroup<"<M group>">;
|
||||
def T_Group : OptionGroup<"<T group>">;
|
||||
def O_Group : OptionGroup<"<O group>">;
|
||||
def W_Group : OptionGroup<"<W group>">;
|
||||
def X_Group : OptionGroup<"<X group>">;
|
||||
def a_Group : OptionGroup<"<a group>">;
|
||||
def d_Group : OptionGroup<"<d group>">;
|
||||
def f_Group : OptionGroup<"<f group>">;
|
||||
def g_Group : OptionGroup<"<g group>">;
|
||||
def i_Group : OptionGroup<"<i group>">;
|
||||
def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>;
|
||||
def m_Group : OptionGroup<"<m group>">;
|
||||
def m_x86_Features_Group : OptionGroup<"<m x86 features group>">;
|
||||
def u_Group : OptionGroup<"<u group>">;
|
||||
|
||||
def pedantic_Group : OptionGroup<"<pedantic group>">;
|
||||
|
||||
// Temporary groups for clang options which we know we don't support,
|
||||
// but don't want to verbosely warn the user about.
|
||||
def clang_ignored_f_Group : OptionGroup<"<clang ignored f group>">,
|
||||
Group<f_Group>;
|
||||
def clang_ignored_m_Group : OptionGroup<"<clang ignored m group>">,
|
||||
Group<m_Group>;
|
||||
|
||||
/////////
|
||||
// Options
|
||||
|
||||
// The internal option ID must be a valid C++ identifier and results in a
|
||||
// clang::driver::options::OPT_XX enum constant for XX.
|
||||
//
|
||||
// We want to unambiguously be able to refer to options from the driver source
|
||||
// code, for this reason the option name is mangled into an ID. This mangling
|
||||
// isn't guaranteed to have an inverse, but for practical purposes it does.
|
||||
//
|
||||
// The mangling scheme is to ignore the leading '-', and perform the following
|
||||
// substitutions:
|
||||
// _ => __
|
||||
// - => _
|
||||
// # => _HASH
|
||||
// , => _COMMA
|
||||
// = => _EQ
|
||||
// C++ => CXX
|
||||
|
||||
def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>,
|
||||
HelpText<"Print the commands to run for this compilation">;
|
||||
def A : JoinedOrSeparate<"-A">;
|
||||
def B : JoinedOrSeparate<"-B">, Flags<[Unsupported]>;
|
||||
def CC : Flag<"-CC">;
|
||||
def C : Flag<"-C">;
|
||||
def D : JoinedOrSeparate<"-D">;
|
||||
def E : Flag<"-E">, Flags<[DriverOption]>,
|
||||
HelpText<"Only run the preprocessor">;
|
||||
def F : JoinedOrSeparate<"-F">;
|
||||
def H : Flag<"-H">;
|
||||
def I_ : Flag<"-I-">, Group<I_Group>;
|
||||
def I : JoinedOrSeparate<"-I">, Group<I_Group>;
|
||||
def L : JoinedOrSeparate<"-L">;
|
||||
def MD : Flag<"-MD">, Group<M_Group>;
|
||||
def MF : JoinedOrSeparate<"-MF">, Group<M_Group>;
|
||||
def MG : Flag<"-MG">, Group<M_Group>;
|
||||
def MMD : Flag<"-MMD">, Group<M_Group>;
|
||||
def MM : Flag<"-MM">, Group<M_Group>;
|
||||
def MP : Flag<"-MP">, Group<M_Group>;
|
||||
def MQ : JoinedOrSeparate<"-MQ">, Group<M_Group>;
|
||||
def MT : JoinedOrSeparate<"-MT">, Group<M_Group>;
|
||||
def Mach : Flag<"-Mach">;
|
||||
def M : Flag<"-M">, Group<M_Group>;
|
||||
def O4 : Joined<"-O4">, Group<O_Group>;
|
||||
def ObjCXX : Flag<"-ObjC++">, Flags<[DriverOption]>,
|
||||
HelpText<"Treat source input files as Objective-C++ inputs">;
|
||||
def ObjC : Flag<"-ObjC">, Flags<[DriverOption]>,
|
||||
HelpText<"Treat source input files as Objective-C inputs">;
|
||||
def O : Joined<"-O">, Group<O_Group>;
|
||||
def P : Flag<"-P">;
|
||||
def Qn : Flag<"-Qn">;
|
||||
def Qunused_arguments : Flag<"-Qunused-arguments">, Flags<[DriverOption]>,
|
||||
HelpText<"Don't emit warning for unused driver arguments">;
|
||||
def Q : Flag<"-Q">;
|
||||
def R : Flag<"-R">;
|
||||
def S : Flag<"-S">, Flags<[DriverOption]>,
|
||||
HelpText<"Only run preprocess and compilation steps">;
|
||||
def Tbss : JoinedOrSeparate<"-Tbss">, Group<T_Group>;
|
||||
def Tdata : JoinedOrSeparate<"-Tdata">, Group<T_Group>;
|
||||
def Ttext : JoinedOrSeparate<"-Ttext">, Group<T_Group>;
|
||||
def T : JoinedOrSeparate<"-T">, Group<T_Group>;
|
||||
def U : JoinedOrSeparate<"-U">;
|
||||
def V : JoinedOrSeparate<"-V">, Flags<[DriverOption, Unsupported]>;
|
||||
def Wa_COMMA : CommaJoined<"-Wa,">,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the assembler">,
|
||||
MetaVarName<"<arg>">;
|
||||
def Wall : Flag<"-Wall">, Group<W_Group>;
|
||||
def Wextra : Flag<"-Wextra">, Group<W_Group>;
|
||||
def Wl_COMMA : CommaJoined<"-Wl,">, Flags<[LinkerInput, RenderAsInput]>,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the linker">,
|
||||
MetaVarName<"<arg>">;
|
||||
def Wno_nonportable_cfstrings : Joined<"-Wno-nonportable-cfstrings">, Group<W_Group>;
|
||||
def Wnonportable_cfstrings : Joined<"-Wnonportable-cfstrings">, Group<W_Group>;
|
||||
def Wp_COMMA : CommaJoined<"-Wp,">,
|
||||
HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">,
|
||||
MetaVarName<"<arg>">;
|
||||
def W_Joined : Joined<"-W">, Group<W_Group>;
|
||||
def Xanalyzer : Separate<"-Xanalyzer">,
|
||||
HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">;
|
||||
def Xarch__ : JoinedAndSeparate<"-Xarch_">, Flags<[DriverOption]>;
|
||||
def Xassembler : Separate<"-Xassembler">,
|
||||
HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">;
|
||||
def Xclang : Separate<"-Xclang">,
|
||||
HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">;
|
||||
def Xlinker : Separate<"-Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
|
||||
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">;
|
||||
def Xpreprocessor : Separate<"-Xpreprocessor">,
|
||||
HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
|
||||
def X_Flag : Flag<"-X">;
|
||||
def X_Joined : Joined<"-X">;
|
||||
def Z_Flag : Flag<"-Z">;
|
||||
def Z_Joined : Joined<"-Z">;
|
||||
def all__load : Flag<"-all_load">;
|
||||
def allowable__client : Separate<"-allowable_client">;
|
||||
def ansi : Flag<"-ansi">, Group<a_Group>;
|
||||
def arch__errors__fatal : Flag<"-arch_errors_fatal">;
|
||||
def arch : Separate<"-arch">, Flags<[DriverOption]>;
|
||||
def a : Joined<"-a">, Group<a_Group>;
|
||||
def bind__at__load : Flag<"-bind_at_load">;
|
||||
def bundle__loader : Separate<"-bundle_loader">;
|
||||
def bundle : Flag<"-bundle">;
|
||||
def b : JoinedOrSeparate<"-b">, Flags<[Unsupported]>;
|
||||
def client__name : JoinedOrSeparate<"-client_name">;
|
||||
def combine : Flag<"-combine">, Flags<[DriverOption, Unsupported]>;
|
||||
def compatibility__version : JoinedOrSeparate<"-compatibility_version">;
|
||||
def coverage : Flag<"-coverage">;
|
||||
def cpp_precomp : Flag<"-cpp-precomp">;
|
||||
def current__version : JoinedOrSeparate<"-current_version">;
|
||||
def c : Flag<"-c">, Flags<[DriverOption]>,
|
||||
HelpText<"Only run preprocess, compile, and assemble steps">;
|
||||
def dA : Flag<"-dA">, Group<d_Group>;
|
||||
def dD : Flag<"-dD">, Group<d_Group>;
|
||||
def dM : Flag<"-dM">, Group<d_Group>;
|
||||
def dead__strip : Flag<"-dead_strip">;
|
||||
def dependency_file : Separate<"-dependency-file">;
|
||||
def dumpmachine : Flag<"-dumpmachine">, Flags<[Unsupported]>;
|
||||
def dumpspecs : Flag<"-dumpspecs">, Flags<[Unsupported]>;
|
||||
def dumpversion : Flag<"-dumpversion">;
|
||||
def dylib__file : Separate<"-dylib_file">;
|
||||
def dylinker__install__name : JoinedOrSeparate<"-dylinker_install_name">;
|
||||
def dylinker : Flag<"-dylinker">;
|
||||
def dynamiclib : Flag<"-dynamiclib">;
|
||||
def dynamic : Flag<"-dynamic">, Flags<[NoArgumentUnused]>;
|
||||
def d_Flag : Flag<"-d">, Group<d_Group>;
|
||||
def d_Joined : Joined<"-d">, Group<d_Group>;
|
||||
def emit_ast : Flag<"-emit-ast">,
|
||||
HelpText<"Emit Clang AST files for source inputs">;
|
||||
def emit_llvm : Flag<"-emit-llvm">,
|
||||
HelpText<"Use the LLVM representation for assembler and object files">;
|
||||
def exported__symbols__list : Separate<"-exported_symbols_list">;
|
||||
def e : JoinedOrSeparate<"-e">;
|
||||
def fPIC : Flag<"-fPIC">, Group<f_Group>;
|
||||
def fPIE : Flag<"-fPIE">, Group<f_Group>;
|
||||
def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
|
||||
def fasm_blocks : Flag<"-fasm-blocks">, Group<clang_ignored_f_Group>;
|
||||
def fastcp : Flag<"-fastcp">, Group<f_Group>;
|
||||
def fastf : Flag<"-fastf">, Group<f_Group>;
|
||||
def fast : Flag<"-fast">, Group<f_Group>;
|
||||
def fasynchronous_unwind_tables : Flag<"-fasynchronous-unwind-tables">, Group<f_Group>;
|
||||
def fblock_introspection : Flag<"-fblock-introspection">, Group<f_Group>;
|
||||
def fblocks : Flag<"-fblocks">, Group<f_Group>;
|
||||
def fbootclasspath_EQ : Joined<"-fbootclasspath=">, Group<f_Group>;
|
||||
def fbuiltin_strcat : Flag<"-fbuiltin-strcat">, Group<f_Group>;
|
||||
def fbuiltin_strcpy : Flag<"-fbuiltin-strcpy">, Group<f_Group>;
|
||||
def fbuiltin : Flag<"-fbuiltin">, Group<f_Group>;
|
||||
def fclasspath_EQ : Joined<"-fclasspath=">, Group<f_Group>;
|
||||
def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, Group<f_Group>;
|
||||
def fcommon : Flag<"-fcommon">, Group<f_Group>;
|
||||
def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
|
||||
def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<clang_ignored_f_Group>;
|
||||
def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
|
||||
def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
|
||||
def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
|
||||
def fdebug_pass_structure : Flag<"-fdebug-pass-structure">, Group<f_Group>;
|
||||
def fdiagnostics_fixit_info : Flag<"-fdiagnostics-fixit-info">, Group<f_Group>;
|
||||
def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-range-info">, Group<f_Group>;
|
||||
def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, Group<f_Group>;
|
||||
def fdollars_in_identifiers : Flag<"-fdollars-in-identifiers">, Group<f_Group>;
|
||||
def feliminate_unused_debug_symbols : Flag<"-feliminate-unused-debug-symbols">, Group<f_Group>;
|
||||
def femit_all_decls : Flag<"-femit-all-decls">, Group<f_Group>;
|
||||
def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
|
||||
def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
|
||||
def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
|
||||
def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
|
||||
def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
|
||||
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
|
||||
def filelist : Separate<"-filelist">, Flags<[LinkerInput]>;
|
||||
def findirect_virtual_calls : Flag<"-findirect-virtual-calls">, Group<f_Group>;
|
||||
def finline_functions : Flag<"-finline-functions">, Group<clang_ignored_f_Group>;
|
||||
def finline : Flag<"-finline">, Group<clang_ignored_f_Group>;
|
||||
def fkeep_inline_functions : Flag<"-fkeep-inline-functions">, Group<clang_ignored_f_Group>;
|
||||
def flat__namespace : Flag<"-flat_namespace">;
|
||||
def flax_vector_conversions : Flag<"-flax-vector-conversions">, Group<f_Group>;
|
||||
def flimited_precision_EQ : Joined<"-flimited-precision=">, Group<f_Group>;
|
||||
def flto : Flag<"-flto">, Group<f_Group>;
|
||||
def fmath_errno : Flag<"-fmath-errno">, Group<f_Group>;
|
||||
def fmerge_all_constants : Flag<"-fmerge-all-constants">, Group<f_Group>;
|
||||
def fmessage_length_EQ : Joined<"-fmessage-length=">, Group<f_Group>;
|
||||
def fms_extensions : Flag<"-fms-extensions">, Group<f_Group>;
|
||||
def fmudflapth : Flag<"-fmudflapth">, Group<f_Group>;
|
||||
def fmudflap : Flag<"-fmudflap">, Group<f_Group>;
|
||||
def fnested_functions : Flag<"-fnested-functions">, Group<f_Group>;
|
||||
def fnext_runtime : Flag<"-fnext-runtime">, Group<f_Group>;
|
||||
def fno_asynchronous_unwind_tables : Flag<"-fno-asynchronous-unwind-tables">, Group<f_Group>;
|
||||
def fno_blocks : Flag<"-fno-blocks">, Group<f_Group>;
|
||||
def fno_builtin_strcat : Flag<"-fno-builtin-strcat">, Group<f_Group>;
|
||||
def fno_builtin_strcpy : Flag<"-fno-builtin-strcpy">, Group<f_Group>;
|
||||
def fno_builtin : Flag<"-fno-builtin">, Group<f_Group>;
|
||||
def fno_caret_diagnostics : Flag<"-fno-caret-diagnostics">, Group<f_Group>;
|
||||
def fno_color_diagnostics : Flag<"-fno-color-diagnostics">, Group<f_Group>;
|
||||
def fno_common : Flag<"-fno-common">, Group<f_Group>;
|
||||
def fno_constant_cfstrings : Flag<"-fno-constant-cfstrings">, Group<f_Group>;
|
||||
def fno_diagnostics_fixit_info : Flag<"-fno-diagnostics-fixit-info">, Group<f_Group>;
|
||||
def fno_diagnostics_show_option : Flag<"-fno-diagnostics-show-option">, Group<f_Group>;
|
||||
def fno_dollars_in_identifiers : Flag<"-fno-dollars-in-identifiers">, Group<f_Group>;
|
||||
def fno_eliminate_unused_debug_symbols : Flag<"-fno-eliminate-unused-debug-symbols">, Group<f_Group>;
|
||||
def fno_exceptions : Flag<"-fno-exceptions">, Group<f_Group>;
|
||||
def fno_inline_functions : Flag<"-fno-inline-functions">, Group<clang_ignored_f_Group>;
|
||||
def fno_inline : Flag<"-fno-inline">, Group<clang_ignored_f_Group>;
|
||||
def fno_keep_inline_functions : Flag<"-fno-keep-inline-functions">, Group<clang_ignored_f_Group>;
|
||||
def fno_math_errno : Flag<"-fno-math-errno">, Group<f_Group>;
|
||||
def fno_merge_all_constants : Flag<"-fno-merge-all-constants">, Group<f_Group>;
|
||||
def fno_ms_extensions : Flag<"-fno-ms-extensions">, Group<f_Group>;
|
||||
def fno_omit_frame_pointer : Flag<"-fno-omit-frame-pointer">, Group<f_Group>;
|
||||
def fno_pascal_strings : Flag<"-fno-pascal-strings">, Group<f_Group>;
|
||||
def fno_rtti : Flag<"-fno-rtti">, Group<f_Group>;
|
||||
def fno_show_column : Flag<"-fno-show-column">, Group<f_Group>;
|
||||
def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
|
||||
def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
|
||||
def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
|
||||
def fno_unit_at_a_time : Flag<"-fno-unit-at-a-time">, Group<f_Group>;
|
||||
def fno_unwind_tables : Flag<"-fno-unwind-tables">, Group<f_Group>;
|
||||
def fno_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
|
||||
def fno_zero_initialized_in_bss : Flag<"-fno-zero-initialized-in-bss">, Group<f_Group>;
|
||||
def fobjc_atdefs : Flag<"-fobjc-atdefs">, Group<clang_ignored_f_Group>;
|
||||
def fobjc_call_cxx_cdtors : Flag<"-fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
|
||||
def fobjc_gc_only : Flag<"-fobjc-gc-only">, Group<f_Group>;
|
||||
def fobjc_gc : Flag<"-fobjc-gc">, Group<f_Group>;
|
||||
def fobjc_new_property : Flag<"-fobjc-new-property">, Group<clang_ignored_f_Group>;
|
||||
def fobjc_nonfragile_abi : Flag<"-fobjc-nonfragile-abi">, Group<f_Group>;
|
||||
def fobjc_sender_dependent_dispatch : Flag<"-fobjc-sender-dependent-dispatch">, Group<f_Group>;
|
||||
def fobjc : Flag<"-fobjc">, Group<f_Group>;
|
||||
def fomit_frame_pointer : Flag<"-fomit-frame-pointer">, Group<f_Group>;
|
||||
def fopenmp : Flag<"-fopenmp">, Group<f_Group>;
|
||||
def force__cpusubtype__ALL : Flag<"-force_cpusubtype_ALL">;
|
||||
def force__flat__namespace : Flag<"-force_flat_namespace">;
|
||||
def foutput_class_dir_EQ : Joined<"-foutput-class-dir=">, Group<f_Group>;
|
||||
def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
|
||||
def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
|
||||
def fpic : Flag<"-fpic">, Group<f_Group>;
|
||||
def fpie : Flag<"-fpie">, Group<f_Group>;
|
||||
def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
|
||||
def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
|
||||
def framework : Separate<"-framework">, Flags<[LinkerInput]>;
|
||||
def frtti : Flag<"-frtti">, Group<f_Group>;
|
||||
def fshort_wchar : Flag<"-fshort-wchar">, Group<f_Group>;
|
||||
def fshow_source_location : Flag<"-fshow-source-location">, Group<f_Group>;
|
||||
def fsigned_bitfields : Flag<"-fsigned-bitfields">, Group<f_Group>;
|
||||
def fsigned_char : Flag<"-fsigned-char">, Group<f_Group>;
|
||||
def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>;
|
||||
def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>;
|
||||
def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<clang_ignored_f_Group>;
|
||||
def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>;
|
||||
def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
|
||||
def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
|
||||
def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
|
||||
def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
|
||||
def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
|
||||
def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>;
|
||||
def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>;
|
||||
def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>;
|
||||
def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
|
||||
def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
|
||||
def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
|
||||
def fzero_initialized_in_bss : Flag<"-fzero-initialized-in-bss">, Group<f_Group>;
|
||||
def f : Joined<"-f">, Group<f_Group>;
|
||||
def g0 : Joined<"-g0">, Group<g_Group>;
|
||||
def g3 : Joined<"-g3">, Group<g_Group>;
|
||||
def gfull : Joined<"-gfull">, Group<g_Group>;
|
||||
def gstabs : Joined<"-gstabs">, Group<g_Group>;
|
||||
def gused : Joined<"-gused">, Group<g_Group>;
|
||||
def g_Flag : Flag<"-g">, Group<g_Group>;
|
||||
def g_Joined : Joined<"-g">, Group<g_Group>;
|
||||
def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
|
||||
def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
|
||||
def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>;
|
||||
def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>;
|
||||
def image__base : Separate<"-image_base">;
|
||||
def include_ : JoinedOrSeparate<"-include">, Group<clang_i_Group>, EnumName<"include">;
|
||||
def init : Separate<"-init">;
|
||||
def install__name : Separate<"-install_name">;
|
||||
def iprefix : JoinedOrSeparate<"-iprefix">, Group<clang_i_Group>;
|
||||
def iquote : JoinedOrSeparate<"-iquote">, Group<clang_i_Group>;
|
||||
def isysroot : JoinedOrSeparate<"-isysroot">, Group<i_Group>;
|
||||
def isystem : JoinedOrSeparate<"-isystem">, Group<clang_i_Group>;
|
||||
def iwithprefixbefore : JoinedOrSeparate<"-iwithprefixbefore">, Group<clang_i_Group>;
|
||||
def iwithprefix : JoinedOrSeparate<"-iwithprefix">, Group<clang_i_Group>;
|
||||
def iwithsysroot : JoinedOrSeparate<"-iwithsysroot">, Group<i_Group>;
|
||||
def i : Joined<"-i">, Group<i_Group>;
|
||||
def keep__private__externs : Flag<"-keep_private_externs">;
|
||||
def l : JoinedOrSeparate<"-l">, Flags<[LinkerInput]>;
|
||||
def m32 : Flag<"-m32">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def m3dnowa : Flag<"-m3dnowa">, Group<m_x86_Features_Group>;
|
||||
def m3dnow : Flag<"-m3dnow">, Group<m_x86_Features_Group>;
|
||||
def m64 : Flag<"-m64">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def mabi_EQ : Joined<"-mabi=">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def march_EQ : Joined<"-march=">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>;
|
||||
def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>, Flags<[DriverOption]>;
|
||||
def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>;
|
||||
def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>;
|
||||
def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
|
||||
def mhard_float : Flag<"-mhard-float">, Group<m_Group>;
|
||||
def miphoneos_version_min_EQ : Joined<"-miphoneos-version-min=">, Group<m_Group>;
|
||||
def mkernel : Flag<"-mkernel">, Group<m_Group>;
|
||||
def mllvm : Separate<"-mllvm">;
|
||||
def mmacosx_version_min_EQ : Joined<"-mmacosx-version-min=">, Group<m_Group>;
|
||||
def mmmx : Flag<"-mmmx">, Group<m_x86_Features_Group>;
|
||||
def mno_3dnowa : Flag<"-mno-3dnowa">, Group<m_x86_Features_Group>;
|
||||
def mno_3dnow : Flag<"-mno-3dnow">, Group<m_x86_Features_Group>;
|
||||
def mno_constant_cfstrings : Flag<"-mno-constant-cfstrings">, Group<m_Group>;
|
||||
def mno_mmx : Flag<"-mno-mmx">, Group<m_x86_Features_Group>;
|
||||
def mno_pascal_strings : Flag<"-mno-pascal-strings">, Group<m_Group>;
|
||||
def mno_red_zone : Flag<"-mno-red-zone">, Group<m_Group>;
|
||||
def mno_soft_float : Flag<"-mno-soft-float">, Group<m_Group>;
|
||||
def mno_sse2 : Flag<"-mno-sse2">, Group<m_x86_Features_Group>;
|
||||
def mno_sse3 : Flag<"-mno-sse3">, Group<m_x86_Features_Group>;
|
||||
def mno_sse4a : Flag<"-mno-sse4a">, Group<m_x86_Features_Group>;
|
||||
def mno_sse4 : Flag<"-mno-sse4">, Group<m_x86_Features_Group>;
|
||||
def mno_sse : Flag<"-mno-sse">, Group<m_x86_Features_Group>;
|
||||
def mno_ssse3 : Flag<"-mno-ssse3">, Group<m_x86_Features_Group>;
|
||||
def mno_thumb : Flag<"-mno-thumb">, Group<m_Group>;
|
||||
def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Group<m_Group>;
|
||||
def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
|
||||
def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
|
||||
def msoft_float : Flag<"-msoft-float">, Group<m_Group>;
|
||||
def msse2 : Flag<"-msse2">, Group<m_x86_Features_Group>;
|
||||
def msse3 : Flag<"-msse3">, Group<m_x86_Features_Group>;
|
||||
def msse4a : Flag<"-msse4a">, Group<m_x86_Features_Group>;
|
||||
def msse4 : Flag<"-msse4">, Group<m_x86_Features_Group>;
|
||||
def msse : Flag<"-msse">, Group<m_x86_Features_Group>;
|
||||
def mssse3 : Flag<"-mssse3">, Group<m_x86_Features_Group>;
|
||||
def mthumb : Flag<"-mthumb">, Group<m_Group>;
|
||||
def mtune_EQ : Joined<"-mtune=">, Group<m_Group>;
|
||||
def multi__module : Flag<"-multi_module">;
|
||||
def multiply__defined__unused : Separate<"-multiply_defined_unused">;
|
||||
def multiply__defined : Separate<"-multiply_defined">;
|
||||
def mwarn_nonportable_cfstrings : Flag<"-mwarn-nonportable-cfstrings">, Group<m_Group>;
|
||||
def m_Separate : Separate<"-m">, Group<m_Group>;
|
||||
def m_Joined : Joined<"-m">, Group<m_Group>;
|
||||
def no_cpp_precomp : Flag<"-no-cpp-precomp">;
|
||||
def no_integrated_cpp : Flag<"-no-integrated-cpp">, Flags<[DriverOption]>;
|
||||
def no__dead__strip__inits__and__terms : Flag<"-no_dead_strip_inits_and_terms">;
|
||||
def nobuiltininc : Flag<"-nobuiltininc">;
|
||||
def nodefaultlibs : Flag<"-nodefaultlibs">;
|
||||
def nofixprebinding : Flag<"-nofixprebinding">;
|
||||
def nolibc : Flag<"-nolibc">;
|
||||
def nomultidefs : Flag<"-nomultidefs">;
|
||||
def noprebind : Flag<"-noprebind">;
|
||||
def noseglinkedit : Flag<"-noseglinkedit">;
|
||||
def nostartfiles : Flag<"-nostartfiles">;
|
||||
def nostdinc : Flag<"-nostdinc">;
|
||||
def nostdlib : Flag<"-nostdlib">;
|
||||
def object : Flag<"-object">;
|
||||
def o : JoinedOrSeparate<"-o">, Flags<[DriverOption, RenderAsInput]>,
|
||||
HelpText<"Write output to <file>">, MetaVarName<"<file>">;
|
||||
def pagezero__size : JoinedOrSeparate<"-pagezero_size">;
|
||||
def pass_exit_codes : Flag<"-pass-exit-codes">, Flags<[Unsupported]>;
|
||||
def pedantic_errors : Flag<"-pedantic-errors">, Group<pedantic_Group>;
|
||||
def pedantic : Flag<"-pedantic">, Group<pedantic_Group>;
|
||||
def pg : Flag<"-pg">;
|
||||
def pipe : Flag<"-pipe">,
|
||||
HelpText<"Use pipes between commands, when possible">;
|
||||
def prebind__all__twolevel__modules : Flag<"-prebind_all_twolevel_modules">;
|
||||
def prebind : Flag<"-prebind">;
|
||||
def preload : Flag<"-preload">;
|
||||
def print_file_name_EQ : Joined<"-print-file-name=">,
|
||||
HelpText<"Print the full library path of <file>">, MetaVarName<"<file>">;
|
||||
def print_ivar_layout : Flag<"-print-ivar-layout">;
|
||||
def print_libgcc_file_name : Flag<"-print-libgcc-file-name">,
|
||||
HelpText<"Print the library path for \"libgcc.a\"">;
|
||||
def print_multi_directory : Flag<"-print-multi-directory">;
|
||||
def print_multi_lib : Flag<"-print-multi-lib">;
|
||||
def print_multi_os_directory : Flag<"-print-multi-os-directory">;
|
||||
def print_prog_name_EQ : Joined<"-print-prog-name=">,
|
||||
HelpText<"Print the full program path of <name>">, MetaVarName<"<name>">;
|
||||
def print_search_dirs : Flag<"-print-search-dirs">,
|
||||
HelpText<"Print the paths used for finding libraries and programs">;
|
||||
def private__bundle : Flag<"-private_bundle">;
|
||||
def pthreads : Flag<"-pthreads">;
|
||||
def pthread : Flag<"-pthread">;
|
||||
def p : Flag<"-p">;
|
||||
def read__only__relocs : Separate<"-read_only_relocs">;
|
||||
def remap : Flag<"-remap">;
|
||||
def rpath : Separate<"-rpath">, Flags<[LinkerInput]>;
|
||||
def r : Flag<"-r">;
|
||||
def save_temps : Flag<"-save-temps">, Flags<[DriverOption]>,
|
||||
HelpText<"Save intermediate compilation results">;
|
||||
def sectalign : MultiArg<"-sectalign", 3>;
|
||||
def sectcreate : MultiArg<"-sectcreate", 3>;
|
||||
def sectobjectsymbols : MultiArg<"-sectobjectsymbols", 2>;
|
||||
def sectorder : MultiArg<"-sectorder", 3>;
|
||||
def seg1addr : JoinedOrSeparate<"-seg1addr">;
|
||||
def seg__addr__table__filename : Separate<"-seg_addr_table_filename">;
|
||||
def seg__addr__table : Separate<"-seg_addr_table">;
|
||||
def segaddr : MultiArg<"-segaddr", 2>;
|
||||
def segcreate : MultiArg<"-segcreate", 3>;
|
||||
def seglinkedit : Flag<"-seglinkedit">;
|
||||
def segprot : MultiArg<"-segprot", 3>;
|
||||
def segs__read__only__addr : Separate<"-segs_read_only_addr">;
|
||||
def segs__read__write__addr : Separate<"-segs_read_write_addr">;
|
||||
def segs__read__ : Joined<"-segs_read_">;
|
||||
def shared_libgcc : Flag<"-shared-libgcc">;
|
||||
def shared : Flag<"-shared">;
|
||||
def single__module : Flag<"-single_module">;
|
||||
def specs_EQ : Joined<"-specs=">;
|
||||
def specs : Separate<"-specs">, Flags<[Unsupported]>;
|
||||
def static_libgcc : Flag<"-static-libgcc">;
|
||||
def static : Flag<"-static">, Flags<[NoArgumentUnused]>;
|
||||
def std_default_EQ : Joined<"-std-default=">;
|
||||
def std_EQ : Joined<"-std=">;
|
||||
def sub__library : JoinedOrSeparate<"-sub_library">;
|
||||
def sub__umbrella : JoinedOrSeparate<"-sub_umbrella">;
|
||||
def s : Flag<"-s">;
|
||||
def time : Flag<"-time">,
|
||||
HelpText<"Time individual commands">;
|
||||
def traditional_cpp : Flag<"-traditional-cpp">;
|
||||
def traditional : Flag<"-traditional">;
|
||||
def trigraphs : Flag<"-trigraphs">;
|
||||
def twolevel__namespace__hints : Flag<"-twolevel_namespace_hints">;
|
||||
def twolevel__namespace : Flag<"-twolevel_namespace">;
|
||||
def t : Flag<"-t">;
|
||||
def umbrella : Separate<"-umbrella">;
|
||||
def undefined : JoinedOrSeparate<"-undefined">, Group<u_Group>;
|
||||
def undef : Flag<"-undef">, Group<u_Group>;
|
||||
def unexported__symbols__list : Separate<"-unexported_symbols_list">;
|
||||
def u : JoinedOrSeparate<"-u">, Group<u_Group>;
|
||||
def v : Flag<"-v">,
|
||||
HelpText<"Show commands to run and use verbose output">;
|
||||
def weak_l : Joined<"-weak-l">, Flags<[LinkerInput]>;
|
||||
def weak__framework : Separate<"-weak_framework">, Flags<[LinkerInput]>;
|
||||
def weak__library : Separate<"-weak_library">, Flags<[LinkerInput]>;
|
||||
def weak__reference__mismatches : Separate<"-weak_reference_mismatches">;
|
||||
def whatsloaded : Flag<"-whatsloaded">;
|
||||
def whyload : Flag<"-whyload">;
|
||||
def w : Flag<"-w">;
|
||||
def x : JoinedOrSeparate<"-x">, Flags<[DriverOption]>,
|
||||
HelpText<"Treat subsequent input files as having type <language>">,
|
||||
MetaVarName<"<language>">;
|
||||
def y : Joined<"-y">;
|
||||
|
||||
// Double dash options, which are usually an alias for one of the previous
|
||||
// options.
|
||||
|
||||
def _CLASSPATH_EQ : Joined<"--CLASSPATH=">, Alias<fclasspath_EQ>;
|
||||
def _CLASSPATH : Separate<"--CLASSPATH">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
|
||||
def _all_warnings : Flag<"--all-warnings">, Alias<Wall>;
|
||||
def _analyze_auto : Flag<"--analyze-auto">, Flags<[DriverOption]>;
|
||||
def _analyzer_no_default_checks : Flag<"--analyzer-no-default-checks">, Flags<[DriverOption]>;
|
||||
def _analyzer_output : JoinedOrSeparate<"--analyzer-output">, Flags<[DriverOption]>;
|
||||
def _analyze : Flag<"--analyze">, Flags<[DriverOption]>,
|
||||
HelpText<"Run the static analyzer">;
|
||||
def _ansi : Flag<"--ansi">, Alias<ansi>;
|
||||
def _assemble : Flag<"--assemble">, Alias<S>;
|
||||
def _assert_EQ : Joined<"--assert=">, Alias<A>, Flags<[RenderSeparate]>;
|
||||
def _assert : Separate<"--assert">, Alias<A>;
|
||||
def _bootclasspath_EQ : Joined<"--bootclasspath=">, Alias<fbootclasspath_EQ>;
|
||||
def _bootclasspath : Separate<"--bootclasspath">, Alias<fbootclasspath_EQ>, Flags<[RenderJoined]>;
|
||||
def _classpath_EQ : Joined<"--classpath=">, Alias<fclasspath_EQ>;
|
||||
def _classpath : Separate<"--classpath">, Alias<fclasspath_EQ>, Flags<[RenderJoined]>;
|
||||
def _combine : Flag<"--combine">, Alias<combine>, Flags<[Unsupported]>;
|
||||
def _comments_in_macros : Flag<"--comments-in-macros">, Alias<CC>;
|
||||
def _comments : Flag<"--comments">, Alias<C>;
|
||||
def _compile : Flag<"--compile">, Alias<c>;
|
||||
def _constant_cfstrings : Flag<"--constant-cfstrings">;
|
||||
def _coverage : Flag<"--coverage">, Alias<coverage>;
|
||||
def _debug_EQ : Joined<"--debug=">, Alias<g_Flag>, Flags<[Unsupported]>;
|
||||
def _debug : Flag<"--debug">, Alias<g_Flag>, Flags<[Unsupported]>;
|
||||
def _define_macro_EQ : Joined<"--define-macro=">, Alias<D>;
|
||||
def _define_macro : Separate<"--define-macro">, Alias<D>, Flags<[RenderJoined]>;
|
||||
def _dependencies : Flag<"--dependencies">, Alias<M>;
|
||||
def _encoding_EQ : Joined<"--encoding=">, Alias<fencoding_EQ>;
|
||||
def _encoding : Separate<"--encoding">, Alias<fencoding_EQ>, Flags<[RenderJoined]>;
|
||||
def _entry : Flag<"--entry">, Alias<e>;
|
||||
def _extdirs_EQ : Joined<"--extdirs=">, Alias<fextdirs_EQ>;
|
||||
def _extdirs : Separate<"--extdirs">, Alias<fextdirs_EQ>, Flags<[RenderJoined]>;
|
||||
def _extra_warnings : Flag<"--extra-warnings">, Alias<W_Joined>;
|
||||
def _for_linker_EQ : Joined<"--for-linker=">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput, RenderSeparate]>;
|
||||
def _for_linker : Separate<"--for-linker">, Alias<Xlinker>, Flags<[LinkerInput, RenderAsInput]>;
|
||||
def _force_link_EQ : Joined<"--force-link=">, Alias<u>, Flags<[RenderSeparate]>;
|
||||
def _force_link : Separate<"--force-link">, Alias<u>;
|
||||
def _help_hidden : Flag<"--help-hidden">;
|
||||
def _help : Flag<"--help">,
|
||||
HelpText<"Display available options">;
|
||||
def _imacros_EQ : Joined<"--imacros=">, Alias<imacros>, Flags<[RenderSeparate]>;
|
||||
def _imacros : Separate<"--imacros">, Alias<imacros>;
|
||||
def _include_barrier : Flag<"--include-barrier">, Alias<I_>;
|
||||
def _include_directory_after_EQ : Joined<"--include-directory-after=">, Alias<idirafter>, Flags<[RenderSeparate]>;
|
||||
def _include_directory_after : Separate<"--include-directory-after">, Alias<idirafter>;
|
||||
def _include_directory_EQ : Joined<"--include-directory=">, Alias<I>;
|
||||
def _include_directory : Separate<"--include-directory">, Alias<I>, Flags<[RenderJoined]>;
|
||||
def _include_prefix_EQ : Joined<"--include-prefix=">, Alias<iprefix>, Flags<[RenderSeparate]>;
|
||||
def _include_prefix : Separate<"--include-prefix">, Alias<iprefix>;
|
||||
def _include_with_prefix_after_EQ : Joined<"--include-with-prefix-after=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
|
||||
def _include_with_prefix_after : Separate<"--include-with-prefix-after">, Alias<iwithprefix>;
|
||||
def _include_with_prefix_before_EQ : Joined<"--include-with-prefix-before=">, Alias<iwithprefixbefore>, Flags<[RenderSeparate]>;
|
||||
def _include_with_prefix_before : Separate<"--include-with-prefix-before">, Alias<iwithprefixbefore>;
|
||||
def _include_with_prefix_EQ : Joined<"--include-with-prefix=">, Alias<iwithprefix>, Flags<[RenderSeparate]>;
|
||||
def _include_with_prefix : Separate<"--include-with-prefix">, Alias<iwithprefix>;
|
||||
def _include_EQ : Joined<"--include=">, Alias<include_>, Flags<[RenderSeparate]>;
|
||||
def _include : Separate<"--include">, Alias<include_>;
|
||||
def _language_EQ : Joined<"--language=">, Alias<x>, Flags<[RenderSeparate]>;
|
||||
def _language : Separate<"--language">, Alias<x>;
|
||||
def _library_directory_EQ : Joined<"--library-directory=">, Alias<L>, Flags<[RenderSeparate]>;
|
||||
def _library_directory : Separate<"--library-directory">, Alias<L>;
|
||||
def _machine__EQ : Joined<"--machine-=">, Alias<m_Joined>, Flags<[Unsupported]>;
|
||||
def _machine_ : Joined<"--machine-">, Alias<m_Joined>, Flags<[Unsupported]>;
|
||||
def _machine_EQ : Joined<"--machine=">, Alias<m_Joined>;
|
||||
def _machine : Separate<"--machine">, Alias<m_Joined>, Flags<[RenderJoined]>;
|
||||
def _no_integrated_cpp : Flag<"--no-integrated-cpp">, Alias<no_integrated_cpp>;
|
||||
def _no_line_commands : Flag<"--no-line-commands">, Alias<P>;
|
||||
def _no_standard_includes : Flag<"--no-standard-includes">, Alias<nostdinc>;
|
||||
def _no_standard_libraries : Flag<"--no-standard-libraries">, Alias<nostdlib>;
|
||||
def _no_undefined : Flag<"--no-undefined">, Flags<[LinkerInput]>;
|
||||
def _no_warnings : Flag<"--no-warnings">, Alias<w>;
|
||||
def _optimize_EQ : Joined<"--optimize=">, Alias<O>, Flags<[Unsupported]>;
|
||||
def _optimize : Flag<"--optimize">, Alias<O>, Flags<[Unsupported]>;
|
||||
def _output_class_directory_EQ : Joined<"--output-class-directory=">, Alias<foutput_class_dir_EQ>;
|
||||
def _output_class_directory : Separate<"--output-class-directory">, Alias<foutput_class_dir_EQ>, Flags<[RenderJoined]>;
|
||||
def _output_EQ : Joined<"--output=">, Alias<o>, Flags<[RenderSeparate]>;
|
||||
def _output : Separate<"--output">, Alias<o>;
|
||||
def _param : Separate<"--param">;
|
||||
def _param_EQ : Joined<"--param=">, Alias<_param>, Flags<[RenderSeparate]>;
|
||||
def _pass_exit_codes : Flag<"--pass-exit-codes">, Alias<pass_exit_codes>;
|
||||
def _pedantic_errors : Flag<"--pedantic-errors">, Alias<pedantic_errors>;
|
||||
def _pedantic : Flag<"--pedantic">, Alias<pedantic>;
|
||||
def _pipe : Flag<"--pipe">, Alias<pipe>, Flags<[DriverOption]>;
|
||||
def _prefix_EQ : Joined<"--prefix=">, Alias<B>, Flags<[RenderSeparate]>;
|
||||
def _prefix : Separate<"--prefix">, Alias<B>;
|
||||
def _preprocess : Flag<"--preprocess">, Alias<E>;
|
||||
def _print_file_name_EQ : Joined<"--print-file-name=">, Alias<print_file_name_EQ>;
|
||||
def _print_file_name : Separate<"--print-file-name">, Alias<print_file_name_EQ>;
|
||||
def _print_libgcc_file_name : Flag<"--print-libgcc-file-name">, Alias<print_libgcc_file_name>;
|
||||
def _print_missing_file_dependencies : Flag<"--print-missing-file-dependencies">, Alias<MG>;
|
||||
def _print_multi_directory : Flag<"--print-multi-directory">, Alias<print_multi_directory>;
|
||||
def _print_multi_lib : Flag<"--print-multi-lib">, Alias<print_multi_lib>;
|
||||
def _print_multi_os_directory : Flag<"--print-multi-os-directory">, Alias<print_multi_os_directory>;
|
||||
def _print_prog_name_EQ : Joined<"--print-prog-name=">, Alias<print_prog_name_EQ>;
|
||||
def _print_prog_name : Separate<"--print-prog-name">, Alias<print_prog_name_EQ>;
|
||||
def _print_search_dirs : Flag<"--print-search-dirs">, Alias<print_search_dirs>;
|
||||
def _profile_blocks : Flag<"--profile-blocks">, Alias<a>;
|
||||
def _profile : Flag<"--profile">, Alias<p>;
|
||||
def _relocatable_pch : Flag<"--relocatable-pch">,
|
||||
HelpText<"Build a relocatable precompiled header">;
|
||||
def _resource_EQ : Joined<"--resource=">, Alias<fcompile_resource_EQ>;
|
||||
def _resource : Separate<"--resource">, Alias<fcompile_resource_EQ>, Flags<[RenderJoined]>;
|
||||
def _save_temps : Flag<"--save-temps">, Alias<save_temps>;
|
||||
def _shared : Flag<"--shared">, Alias<shared>;
|
||||
def _signed_char : Flag<"--signed-char">, Alias<fsigned_char>;
|
||||
def _specs_EQ : Joined<"--specs=">, Alias<specs_EQ>, Flags<[Unsupported]>;
|
||||
def _specs : Separate<"--specs">, Alias<specs_EQ>, Flags<[RenderJoined, Unsupported]>;
|
||||
def _static : Flag<"--static">, Alias<static>;
|
||||
def _std_EQ : Joined<"--std=">, Alias<std_EQ>;
|
||||
def _std : Separate<"--std">, Alias<std_EQ>, Flags<[RenderJoined]>;
|
||||
def _sysroot_EQ : Joined<"--sysroot=">;
|
||||
def _sysroot : Separate<"--sysroot">, Alias<_sysroot_EQ>, Flags<[RenderJoined]>;
|
||||
def _target_help : Flag<"--target-help">;
|
||||
def _trace_includes : Flag<"--trace-includes">, Alias<H>;
|
||||
def _traditional_cpp : Flag<"--traditional-cpp">, Alias<traditional_cpp>;
|
||||
def _traditional : Flag<"--traditional">, Alias<traditional>;
|
||||
def _trigraphs : Flag<"--trigraphs">, Alias<trigraphs>;
|
||||
def _undefine_macro_EQ : Joined<"--undefine-macro=">, Alias<U>;
|
||||
def _undefine_macro : Separate<"--undefine-macro">, Alias<U>, Flags<[RenderJoined]>;
|
||||
def _unsigned_char : Flag<"--unsigned-char">, Alias<funsigned_char>;
|
||||
def _user_dependencies : Flag<"--user-dependencies">, Alias<MM>;
|
||||
def _verbose : Flag<"--verbose">, Alias<v>;
|
||||
def _version : Flag<"--version">;
|
||||
def _warn__EQ : Joined<"--warn-=">, Alias<W_Joined>, Flags<[Unsupported]>;
|
||||
def _warn_ : Joined<"--warn-">, Alias<W_Joined>, Flags<[Unsupported]>;
|
||||
def _write_dependencies : Flag<"--write-dependencies">, Alias<MD>;
|
||||
def _write_user_dependencies : Flag<"--write-user-dependencies">, Alias<MMD>;
|
||||
def _ : Joined<"--">, Alias<f>, Flags<[Unsupported]>;
|
@ -1,77 +0,0 @@
|
||||
//===--- CompileOptions.h ---------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// 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 CompileOptions interface.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_COMPILEOPTIONS_H
|
||||
#define LLVM_CLANG_FRONTEND_COMPILEOPTIONS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// CompileOptions - Track various options which control how the code
|
||||
/// is optimized and passed to the backend.
|
||||
class CompileOptions {
|
||||
public:
|
||||
enum InliningMethod {
|
||||
NoInlining, // Perform no inlining whatsoever.
|
||||
NormalInlining, // Use the standard function inlining pass.
|
||||
OnlyAlwaysInlining // Only run the always inlining pass.
|
||||
};
|
||||
|
||||
unsigned OptimizationLevel : 3; /// The -O[0-4] option specified.
|
||||
unsigned OptimizeSize : 1; /// If -Os is specified.
|
||||
unsigned DebugInfo : 1; /// Should generate deubg info (-g).
|
||||
unsigned UnitAtATime : 1; /// Unused. For mirroring GCC
|
||||
/// optimization selection.
|
||||
unsigned SimplifyLibCalls : 1; /// Should standard library calls be
|
||||
/// treated specially.
|
||||
unsigned UnrollLoops : 1; /// Control whether loops are unrolled.
|
||||
unsigned VerifyModule : 1; /// Control whether the module
|
||||
/// should be run through the LLVM Verifier.
|
||||
unsigned TimePasses : 1; /// Set when -ftime-report is enabled.
|
||||
unsigned NoCommon : 1; /// Set when -fno-common or C++ is enabled.
|
||||
unsigned DisableRedZone : 1; /// Set when -mno-red-zone is enabled.
|
||||
unsigned NoImplicitFloat : 1; /// Set when -mno-implicit-float is enabled.
|
||||
unsigned MergeAllConstants : 1; // Merge identical constants.
|
||||
|
||||
/// Inlining - The kind of inlining to perform.
|
||||
InliningMethod Inlining;
|
||||
|
||||
/// CPU - An optional CPU to target.
|
||||
std::string CPU;
|
||||
|
||||
/// Features - A list of subtarget features to pass to the code
|
||||
/// generator.
|
||||
std::vector<std::string> Features;
|
||||
|
||||
public:
|
||||
CompileOptions() {
|
||||
OptimizationLevel = 0;
|
||||
OptimizeSize = 0;
|
||||
DebugInfo = 0;
|
||||
UnitAtATime = 1;
|
||||
SimplifyLibCalls = UnrollLoops = 0;
|
||||
VerifyModule = 1;
|
||||
TimePasses = 0;
|
||||
NoCommon = 0;
|
||||
Inlining = NoInlining;
|
||||
DisableRedZone = 0;
|
||||
NoImplicitFloat = 0;
|
||||
MergeAllConstants = 1;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -72,8 +72,8 @@ class HeaderSearchOptions {
|
||||
unsigned Verbose : 1;
|
||||
|
||||
public:
|
||||
HeaderSearchOptions(llvm::StringRef _Sysroot = "")
|
||||
: Sysroot(_Sysroot), UseStandardIncludes(true) {}
|
||||
HeaderSearchOptions(llvm::StringRef _Sysroot = "/")
|
||||
: Sysroot(_Sysroot), UseStandardIncludes(true), Verbose(false) {}
|
||||
|
||||
/// AddPath - Add the \arg Path path to the specified \arg Group list.
|
||||
void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group,
|
||||
|
@ -1,98 +0,0 @@
|
||||
//===--- InitHeaderSearch.h - Initialize header search paths ----*- C++ -*-===//
|
||||
//
|
||||
// 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 InitHeaderSearch class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_INIT_HEADER_SEARCH_H_
|
||||
#define LLVM_CLANG_FRONTEND_INIT_HEADER_SEARCH_H_
|
||||
|
||||
#include "clang/Lex/DirectoryLookup.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class HeaderSearch;
|
||||
class LangOptions;
|
||||
|
||||
/// InitHeaderSearch - This class makes it easier to set the search paths of
|
||||
/// a HeaderSearch object. InitHeaderSearch stores several search path lists
|
||||
/// internally, which can be sent to a HeaderSearch object in one swoop.
|
||||
class InitHeaderSearch {
|
||||
std::vector<DirectoryLookup> IncludeGroup[4];
|
||||
HeaderSearch& Headers;
|
||||
bool Verbose;
|
||||
std::string isysroot;
|
||||
|
||||
public:
|
||||
/// InitHeaderSearch::IncludeDirGroup - Identifies the several search path
|
||||
/// lists stored internally.
|
||||
enum IncludeDirGroup {
|
||||
Quoted = 0, //< `#include ""` paths. Thing `gcc -iquote`.
|
||||
Angled, //< Paths for both `#include ""` and `#include <>`. (`-I`)
|
||||
System, //< Like Angled, but marks system directories.
|
||||
After //< Like System, but searched after the system directories.
|
||||
};
|
||||
|
||||
InitHeaderSearch(HeaderSearch &HS,
|
||||
bool verbose = false, const std::string &iSysroot = "")
|
||||
: Headers(HS), Verbose(verbose), isysroot(iSysroot) {}
|
||||
|
||||
/// AddPath - Add the specified path to the specified group list.
|
||||
void AddPath(const llvm::StringRef &Path, IncludeDirGroup Group,
|
||||
bool isCXXAware, bool isUserSupplied,
|
||||
bool isFramework, bool IgnoreSysRoot = false);
|
||||
|
||||
/// AddEnvVarPaths - Add a list of paths from an environment variable to a
|
||||
/// header search list.
|
||||
void AddEnvVarPaths(const char *Name);
|
||||
|
||||
/// AddGnuCPlusPlusIncludePaths - Add the necessary paths to suport a gnu
|
||||
/// libstdc++.
|
||||
void AddGnuCPlusPlusIncludePaths(const std::string &Base, const char *Dir32,
|
||||
const char *Dir64,
|
||||
const llvm::Triple &triple);
|
||||
|
||||
/// AddMinGWCPlusPlusIncludePaths - Add the necessary paths to suport a MinGW
|
||||
/// libstdc++.
|
||||
void AddMinGWCPlusPlusIncludePaths(const std::string &Base,
|
||||
const char *Arch,
|
||||
const char *Version);
|
||||
|
||||
/// AddDefaultEnvVarPaths - Adds list of paths from default environment
|
||||
/// variables such as CPATH.
|
||||
void AddDefaultEnvVarPaths(const LangOptions &Lang);
|
||||
|
||||
// AddDefaultCIncludePaths - Add paths that should always be searched.
|
||||
void AddDefaultCIncludePaths(const llvm::Triple &triple);
|
||||
|
||||
// AddDefaultCPlusPlusIncludePaths - Add paths that should be searched when
|
||||
// compiling c++.
|
||||
void AddDefaultCPlusPlusIncludePaths(const llvm::Triple &triple);
|
||||
|
||||
// AddDefaultFrameworkIncludePaths - Add the framework paths. Used on darwin.
|
||||
void AddDefaultFrameworkIncludePaths(const llvm::Triple &triple);
|
||||
|
||||
/// AddDefaultSystemIncludePaths - Adds the default system include paths so
|
||||
/// that e.g. stdio.h is found.
|
||||
void AddDefaultSystemIncludePaths(const LangOptions &Lang,
|
||||
const llvm::Triple &triple);
|
||||
|
||||
/// Realize - Merges all search path lists into one list and send it to
|
||||
/// HeaderSearch.
|
||||
void Realize();
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -1,79 +0,0 @@
|
||||
//===--- InitPreprocessor.h - InitializePreprocessor function. --*- C++ -*-===//
|
||||
//
|
||||
// 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 clang::InitializePreprocessor function.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_INIT_PREPROCESSOR_H_
|
||||
#define LLVM_CLANG_FRONTEND_INIT_PREPROCESSOR_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
||||
class Preprocessor;
|
||||
class LangOptions;
|
||||
|
||||
/// PreprocessorInitOptions - This class is used for passing the various
|
||||
/// options used in preprocessor initialization to InitializePreprocessor().
|
||||
class PreprocessorInitOptions {
|
||||
std::vector<std::pair<std::string, bool/*isUndef*/> > Macros;
|
||||
std::vector<std::pair<std::string, bool/*isPTH*/> > Includes;
|
||||
std::vector<std::string> MacroIncludes;
|
||||
|
||||
unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler
|
||||
/// and target specific predefines.
|
||||
|
||||
public:
|
||||
PreprocessorInitOptions() : UsePredefines(true) {}
|
||||
|
||||
bool getUsePredefines() const { return UsePredefines; }
|
||||
void setUsePredefines(bool Value) {
|
||||
UsePredefines = Value;
|
||||
}
|
||||
|
||||
void addMacroDef(const std::string &Name) {
|
||||
Macros.push_back(std::make_pair(Name, false));
|
||||
}
|
||||
void addMacroUndef(const std::string &Name) {
|
||||
Macros.push_back(std::make_pair(Name, true));
|
||||
}
|
||||
void addInclude(const std::string &Name, bool isPTH = false) {
|
||||
Includes.push_back(std::make_pair(Name, isPTH));
|
||||
}
|
||||
void addMacroInclude(const std::string &Name) {
|
||||
MacroIncludes.push_back(Name);
|
||||
}
|
||||
|
||||
typedef std::vector<std::pair<std::string,
|
||||
bool> >::const_iterator macro_iterator;
|
||||
macro_iterator macro_begin() const { return Macros.begin(); }
|
||||
macro_iterator macro_end() const { return Macros.end(); }
|
||||
|
||||
typedef std::vector<std::pair<std::string,
|
||||
bool> >::const_iterator include_iterator;
|
||||
include_iterator include_begin() const { return Includes.begin(); }
|
||||
include_iterator include_end() const { return Includes.end(); }
|
||||
|
||||
typedef std::vector<std::string>::const_iterator imacro_iterator;
|
||||
imacro_iterator imacro_begin() const { return MacroIncludes.begin(); }
|
||||
imacro_iterator imacro_end() const { return MacroIncludes.end(); }
|
||||
};
|
||||
|
||||
/// InitializePreprocessor - Initialize the preprocessor getting it and the
|
||||
/// environment ready to process a single file.
|
||||
///
|
||||
void InitializePreprocessor(Preprocessor &PP,
|
||||
const PreprocessorInitOptions& InitOptions);
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
//===-- ManagerRegistry.h - Pluggable analyzer module registry --*- C++ -*-===//
|
||||
//
|
||||
// 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 ManagerRegistry and Register* classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_FRONTEND_MANAGER_REGISTRY_H
|
||||
#define LLVM_CLANG_FRONTEND_MANAGER_REGISTRY_H
|
||||
|
||||
#include "clang/Analysis/PathSensitive/GRState.h"
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// ManagerRegistry - This class records manager creators registered at
|
||||
/// runtime. The information is communicated to AnalysisManager through static
|
||||
/// members. Better design is expected.
|
||||
|
||||
class ManagerRegistry {
|
||||
public:
|
||||
static StoreManagerCreator StoreMgrCreator;
|
||||
static ConstraintManagerCreator ConstraintMgrCreator;
|
||||
};
|
||||
|
||||
/// RegisterConstraintManager - This class is used to setup the constraint
|
||||
/// manager of the static analyzer. The constructor takes a creator function
|
||||
/// pointer for creating the constraint manager.
|
||||
///
|
||||
/// It is used like this:
|
||||
///
|
||||
/// class MyConstraintManager {};
|
||||
/// ConstraintManager* CreateMyConstraintManager(GRStateManager& statemgr) {
|
||||
/// return new MyConstraintManager(statemgr);
|
||||
/// }
|
||||
/// RegisterConstraintManager X(CreateMyConstraintManager);
|
||||
|
||||
class RegisterConstraintManager {
|
||||
public:
|
||||
RegisterConstraintManager(ConstraintManagerCreator CMC) {
|
||||
assert(ManagerRegistry::ConstraintMgrCreator == 0
|
||||
&& "ConstraintMgrCreator already set!");
|
||||
ManagerRegistry::ConstraintMgrCreator = CMC;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
LEVEL = ../../../..
|
||||
DIRS := Basic
|
||||
DIRS := Basic Driver
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
@ -2329,29 +2329,75 @@ class Action : public ActionBase {
|
||||
/// found after the left paren.
|
||||
///
|
||||
/// \param S the scope in which the operator keyword occurs.
|
||||
virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) { }
|
||||
|
||||
virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { }
|
||||
|
||||
/// \brief Code completion for the getter of an Objective-C property
|
||||
/// declaration.
|
||||
///
|
||||
/// This code completion action is invoked when the code-completion
|
||||
/// token is found after the "getter = " in a property declaration.
|
||||
///
|
||||
/// \param S the scope in which the property is being declared.
|
||||
///
|
||||
/// \param ClassDecl the Objective-C class or category in which the property
|
||||
/// is being defined.
|
||||
///
|
||||
/// \param Methods the set of methods declared thus far within \p ClassDecl.
|
||||
///
|
||||
/// \param NumMethods the number of methods in \p Methods
|
||||
virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for the setter of an Objective-C property
|
||||
/// declaration.
|
||||
///
|
||||
/// This code completion action is invoked when the code-completion
|
||||
/// token is found after the "setter = " in a property declaration.
|
||||
///
|
||||
/// \param S the scope in which the property is being declared.
|
||||
///
|
||||
/// \param ClassDecl the Objective-C class or category in which the property
|
||||
/// is being defined.
|
||||
///
|
||||
/// \param Methods the set of methods declared thus far within \p ClassDecl.
|
||||
///
|
||||
/// \param NumMethods the number of methods in \p Methods
|
||||
virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for an ObjC message expression that refers to
|
||||
/// a class method.
|
||||
///
|
||||
/// This code completion action is invoked when the code-completion token is
|
||||
/// found after the class name.
|
||||
/// found after the class name and after each argument.
|
||||
///
|
||||
/// \param S the scope in which the message expression occurs.
|
||||
/// \param FName the factory name.
|
||||
/// \param FNameLoc the source location of the factory name.
|
||||
/// \param SelIdents the identifiers that describe the selector (thus far).
|
||||
/// \param NumSelIdents the number of identifiers in \p SelIdents.
|
||||
virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
|
||||
SourceLocation FNameLoc){ }
|
||||
SourceLocation FNameLoc,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents){ }
|
||||
|
||||
/// \brief Code completion for an ObjC message expression that refers to
|
||||
/// an instance method.
|
||||
///
|
||||
/// This code completion action is invoked when the code-completion token is
|
||||
/// found after the receiver expression.
|
||||
/// found after the receiver expression and after each argument.
|
||||
///
|
||||
/// \param S the scope in which the operator keyword occurs.
|
||||
/// \param Receiver an expression for the receiver of the message.
|
||||
virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) { }
|
||||
/// \param SelIdents the identifiers that describe the selector (thus far).
|
||||
/// \param NumSelIdents the number of identifiers in \p SelIdents.
|
||||
virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents) { }
|
||||
|
||||
/// \brief Code completion for a list of protocol references in Objective-C,
|
||||
/// such as P1 and P2 in \c id<P1,P2>.
|
||||
@ -2371,6 +2417,61 @@ class Action : public ActionBase {
|
||||
///
|
||||
/// \param S the scope in which the protocol declaration occurs.
|
||||
virtual void CodeCompleteObjCProtocolDecl(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for an Objective-C interface, after the
|
||||
/// @interface but before any identifier.
|
||||
virtual void CodeCompleteObjCInterfaceDecl(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for the superclass of an Objective-C
|
||||
/// interface, after the ':'.
|
||||
///
|
||||
/// \param S the scope in which the interface declaration occurs.
|
||||
///
|
||||
/// \param ClassName the name of the class being defined.
|
||||
virtual void CodeCompleteObjCSuperclass(Scope *S,
|
||||
IdentifierInfo *ClassName) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for an Objective-C implementation, after the
|
||||
/// @implementation but before any identifier.
|
||||
virtual void CodeCompleteObjCImplementationDecl(Scope *S) { }
|
||||
|
||||
/// \brief Code completion for the category name in an Objective-C interface
|
||||
/// declaration.
|
||||
///
|
||||
/// This code completion action is invoked after the '(' that indicates
|
||||
/// a category name within an Objective-C interface declaration.
|
||||
virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
|
||||
IdentifierInfo *ClassName) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for the category name in an Objective-C category
|
||||
/// implementation.
|
||||
///
|
||||
/// This code completion action is invoked after the '(' that indicates
|
||||
/// the category name within an Objective-C category implementation.
|
||||
virtual void CodeCompleteObjCImplementationCategory(Scope *S,
|
||||
IdentifierInfo *ClassName) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for the property names when defining an
|
||||
/// Objective-C property.
|
||||
///
|
||||
/// This code completion action is invoked after @synthesize or @dynamic and
|
||||
/// after each "," within one of those definitions.
|
||||
virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
|
||||
DeclPtrTy ObjCImpDecl) {
|
||||
}
|
||||
|
||||
/// \brief Code completion for the instance variable name that should
|
||||
/// follow an '=' when synthesizing an Objective-C property.
|
||||
///
|
||||
/// This code completion action is invoked after each '=' that occurs within
|
||||
/// an @synthesized definition.
|
||||
virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
|
||||
IdentifierInfo *PropertyName,
|
||||
DeclPtrTy ObjCImpDecl) {
|
||||
}
|
||||
//@}
|
||||
};
|
||||
|
||||
|
@ -810,7 +810,8 @@ class Parser {
|
||||
DeclPtrTy ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType,
|
||||
DeclPtrTy classDecl,
|
||||
tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword);
|
||||
void ParseObjCPropertyAttribute(ObjCDeclSpec &DS);
|
||||
void ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods, unsigned NumMethods);
|
||||
|
||||
DeclPtrTy ParseObjCMethodDefinition();
|
||||
|
||||
|
@ -123,6 +123,9 @@ class CodeCompletionString {
|
||||
/// \brief Create a new current-parameter chunk.
|
||||
static Chunk CreateCurrentParameter(llvm::StringRef CurrentParameter);
|
||||
|
||||
/// \brief Clone the given chunk.
|
||||
Chunk Clone() const;
|
||||
|
||||
/// \brief Destroy this chunk, deallocating any memory it owns.
|
||||
void Destroy();
|
||||
};
|
||||
@ -192,15 +195,21 @@ class CodeCompletionString {
|
||||
/// \brief Add a new chunk.
|
||||
void AddChunk(Chunk C) { Chunks.push_back(C); }
|
||||
|
||||
/// \brief Returns the text in the TypedText chunk.
|
||||
const char *getTypedText() const;
|
||||
|
||||
/// \brief Retrieve a string representation of the code completion string,
|
||||
/// which is mainly useful for debugging.
|
||||
std::string getAsString() const;
|
||||
|
||||
/// \brief Clone this code-completion string.
|
||||
CodeCompletionString *Clone() const;
|
||||
|
||||
/// \brief Serialize this code-completion string to the given stream.
|
||||
void Serialize(llvm::raw_ostream &OS) const;
|
||||
|
||||
/// \brief Deserialize a code-completion string from the given string.
|
||||
static CodeCompletionString *Deserialize(llvm::StringRef &Str);
|
||||
static CodeCompletionString *Deserialize(llvm::StringRef &Str);
|
||||
};
|
||||
|
||||
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
|
||||
@ -220,7 +229,8 @@ class CodeCompleteConsumer {
|
||||
enum ResultKind {
|
||||
RK_Declaration = 0, //< Refers to a declaration
|
||||
RK_Keyword, //< Refers to a keyword or symbol.
|
||||
RK_Macro //< Refers to a macro
|
||||
RK_Macro, //< Refers to a macro
|
||||
RK_Pattern //< Refers to a precomputed pattern.
|
||||
};
|
||||
|
||||
/// \brief The kind of result stored here.
|
||||
@ -235,6 +245,10 @@ class CodeCompleteConsumer {
|
||||
/// or symbol's spelling.
|
||||
const char *Keyword;
|
||||
|
||||
/// \brief When Kind == RK_Pattern, the code-completion string that
|
||||
/// describes the completion text to insert.
|
||||
CodeCompletionString *Pattern;
|
||||
|
||||
/// \brief When Kind == RK_Macro, the identifier that refers to a macro.
|
||||
IdentifierInfo *Macro;
|
||||
};
|
||||
@ -243,6 +257,10 @@ class CodeCompleteConsumer {
|
||||
/// result and progressively higher numbers representing poorer results.
|
||||
unsigned Rank;
|
||||
|
||||
/// \brief Specifiers which parameter (of a function, Objective-C method,
|
||||
/// macro, etc.) we should start with when formatting the result.
|
||||
unsigned StartParameter;
|
||||
|
||||
/// \brief Whether this result is hidden by another name.
|
||||
bool Hidden : 1;
|
||||
|
||||
@ -252,7 +270,11 @@ class CodeCompleteConsumer {
|
||||
/// \brief Whether this declaration is the beginning of a
|
||||
/// nested-name-specifier and, therefore, should be followed by '::'.
|
||||
bool StartsNestedNameSpecifier : 1;
|
||||
|
||||
|
||||
/// \brief Whether all parameters (of a function, Objective-C
|
||||
/// method, etc.) should be considered "informative".
|
||||
bool AllParametersAreInformative : 1;
|
||||
|
||||
/// \brief If the result should have a nested-name-specifier, this is it.
|
||||
/// When \c QualifierIsInformative, the nested-name-specifier is
|
||||
/// informative rather than required.
|
||||
@ -263,20 +285,31 @@ class CodeCompleteConsumer {
|
||||
NestedNameSpecifier *Qualifier = 0,
|
||||
bool QualifierIsInformative = false)
|
||||
: Kind(RK_Declaration), Declaration(Declaration), Rank(Rank),
|
||||
Hidden(false), QualifierIsInformative(QualifierIsInformative),
|
||||
StartsNestedNameSpecifier(false), Qualifier(Qualifier) { }
|
||||
StartParameter(0), Hidden(false),
|
||||
QualifierIsInformative(QualifierIsInformative),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(Qualifier) { }
|
||||
|
||||
/// \brief Build a result that refers to a keyword or symbol.
|
||||
Result(const char *Keyword, unsigned Rank)
|
||||
: Kind(RK_Keyword), Keyword(Keyword), Rank(Rank), Hidden(false),
|
||||
QualifierIsInformative(0), StartsNestedNameSpecifier(false),
|
||||
: Kind(RK_Keyword), Keyword(Keyword), Rank(Rank), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(0),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(0) { }
|
||||
|
||||
/// \brief Build a result that refers to a macro.
|
||||
Result(IdentifierInfo *Macro, unsigned Rank)
|
||||
: Kind(RK_Macro), Macro(Macro), Rank(Rank), Hidden(false),
|
||||
QualifierIsInformative(0), StartsNestedNameSpecifier(false),
|
||||
: Kind(RK_Macro), Macro(Macro), Rank(Rank), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(0),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(0) { }
|
||||
|
||||
/// \brief Build a result that refers to a pattern.
|
||||
Result(CodeCompletionString *Pattern, unsigned Rank)
|
||||
: Kind(RK_Pattern), Pattern(Pattern), Rank(Rank), StartParameter(0),
|
||||
Hidden(false), QualifierIsInformative(0),
|
||||
StartsNestedNameSpecifier(false), AllParametersAreInformative(false),
|
||||
Qualifier(0) { }
|
||||
|
||||
/// \brief Retrieve the declaration stored in this result.
|
||||
NamedDecl *getDeclaration() const {
|
||||
@ -293,6 +326,8 @@ class CodeCompleteConsumer {
|
||||
/// \brief Create a new code-completion string that describes how to insert
|
||||
/// this result into a program.
|
||||
CodeCompletionString *CreateCodeCompletionString(Sema &S);
|
||||
|
||||
void Destroy();
|
||||
};
|
||||
|
||||
class OverloadCandidate {
|
||||
|
@ -603,8 +603,8 @@ CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
|
||||
EmitBlock(AfterFor, true);
|
||||
}
|
||||
|
||||
/// GenerateCXXAggrDestructorHelper - Generates a helper function which when invoked,
|
||||
/// calls the default destructor on array elements in reverse order of
|
||||
/// GenerateCXXAggrDestructorHelper - Generates a helper function which when
|
||||
/// invoked, calls the default destructor on array elements in reverse order of
|
||||
/// construction.
|
||||
llvm::Constant *
|
||||
CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D,
|
||||
|
@ -611,4 +611,3 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) {
|
||||
DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -345,6 +345,11 @@ static const CXXMethodDecl *GetKeyFunction(const RecordDecl *D) {
|
||||
if (MD->isPure())
|
||||
continue;
|
||||
|
||||
// FIXME: This doesn't work. If we have an out of line body, that body will
|
||||
// set the MD to have a body, what we want to know is, was the body present
|
||||
// inside the declaration of the class. For now, we just avoid the problem
|
||||
// by pretending there is no key function.
|
||||
return 0;
|
||||
if (MD->getBody())
|
||||
continue;
|
||||
|
||||
|
@ -47,21 +47,35 @@ class RttiBuilder {
|
||||
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
|
||||
}
|
||||
|
||||
llvm::Constant *BuildName(QualType Ty, bool Hidden) {
|
||||
llvm::Constant *BuildName(QualType Ty, bool Hidden, bool Extern) {
|
||||
llvm::SmallString<256> OutName;
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
mangleCXXRttiName(CGM.getMangleContext(), Ty, Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
llvm::GlobalVariable::LinkageTypes linktype;
|
||||
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||
if (!Extern)
|
||||
linktype = llvm::GlobalValue::InternalLinkage;
|
||||
|
||||
llvm::GlobalVariable *GV;
|
||||
GV = CGM.getModule().getGlobalVariable(Name);
|
||||
if (GV && !GV->isDeclaration())
|
||||
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||
|
||||
llvm::Constant *C;
|
||||
C = llvm::ConstantArray::get(VMContext, Out.str().substr(4));
|
||||
C = llvm::ConstantArray::get(VMContext, Name.substr(4));
|
||||
|
||||
llvm::GlobalVariable * GV = new llvm::GlobalVariable(CGM.getModule(),
|
||||
C->getType(),
|
||||
true, linktype, C,
|
||||
Out.str());
|
||||
llvm::GlobalVariable *OGV = GV;
|
||||
GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
|
||||
C, Name);
|
||||
if (OGV) {
|
||||
GV->takeName(OGV);
|
||||
llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
|
||||
OGV->getType());
|
||||
OGV->replaceAllUsesWith(NewPtr);
|
||||
OGV->eraseFromParent();
|
||||
}
|
||||
if (Hidden)
|
||||
GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
|
||||
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||
@ -87,8 +101,9 @@ class RttiBuilder {
|
||||
llvm::SmallString<256> OutName;
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
C = CGM.getModule().getGlobalVariable(Out.str());
|
||||
C = CGM.getModule().getGlobalVariable(Name);
|
||||
if (C)
|
||||
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
|
||||
|
||||
@ -96,7 +111,7 @@ class RttiBuilder {
|
||||
linktype = llvm::GlobalValue::ExternalLinkage;;
|
||||
|
||||
C = new llvm::GlobalVariable(CGM.getModule(), Int8PtrTy, true, linktype,
|
||||
0, Out.str());
|
||||
0, Name);
|
||||
return llvm::ConstantExpr::getBitCast(C, Int8PtrTy);
|
||||
}
|
||||
|
||||
@ -147,20 +162,19 @@ class RttiBuilder {
|
||||
|
||||
llvm::Constant *finish(std::vector<llvm::Constant *> &info,
|
||||
llvm::GlobalVariable *GV,
|
||||
llvm::StringRef Name, bool Hidden) {
|
||||
llvm::StringRef Name, bool Hidden, bool Extern) {
|
||||
llvm::GlobalVariable::LinkageTypes linktype;
|
||||
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||
if (!Extern)
|
||||
linktype = llvm::GlobalValue::InternalLinkage;
|
||||
|
||||
llvm::Constant *C;
|
||||
C = llvm::ConstantStruct::get(VMContext, &info[0], info.size(), false);
|
||||
|
||||
if (GV == 0)
|
||||
GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
|
||||
linktype, C, Name);
|
||||
else {
|
||||
llvm::GlobalVariable *OGV = GV;
|
||||
GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true,
|
||||
linktype, C, Name);
|
||||
llvm::GlobalVariable *OGV = GV;
|
||||
GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(), true, linktype,
|
||||
C, Name);
|
||||
if (OGV) {
|
||||
GV->takeName(OGV);
|
||||
llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
|
||||
OGV->getType());
|
||||
@ -183,15 +197,17 @@ class RttiBuilder {
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
mangleCXXRtti(CGM.getMangleContext(), CGM.getContext().getTagDeclType(RD),
|
||||
Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
llvm::GlobalVariable *GV;
|
||||
GV = CGM.getModule().getGlobalVariable(Out.str());
|
||||
GV = CGM.getModule().getGlobalVariable(Name);
|
||||
if (GV && !GV->isDeclaration())
|
||||
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||
|
||||
std::vector<llvm::Constant *> info;
|
||||
|
||||
bool Hidden = CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
|
||||
bool Extern = !RD->isInAnonymousNamespace();
|
||||
|
||||
bool simple = false;
|
||||
if (RD->getNumBases() == 0)
|
||||
@ -202,7 +218,8 @@ class RttiBuilder {
|
||||
} else
|
||||
C = BuildVtableRef("_ZTVN10__cxxabiv121__vmi_class_type_infoE");
|
||||
info.push_back(C);
|
||||
info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden));
|
||||
info.push_back(BuildName(CGM.getContext().getTagDeclType(RD), Hidden,
|
||||
Extern));
|
||||
|
||||
// If we have no bases, there are no more fields.
|
||||
if (RD->getNumBases()) {
|
||||
@ -235,7 +252,7 @@ class RttiBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
return finish(info, GV, Out.str(), Hidden);
|
||||
return finish(info, GV, Name, Hidden, Extern);
|
||||
}
|
||||
|
||||
/// - BuildFlags - Build a __flags value for __pbase_type_info.
|
||||
@ -250,23 +267,49 @@ class RttiBuilder {
|
||||
return BuildType(Ty);
|
||||
}
|
||||
|
||||
bool DecideExtern(QualType Ty) {
|
||||
// For this type, see if all components are never in an anonymous namespace.
|
||||
if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
|
||||
return (DecideExtern(MPT->getPointeeType())
|
||||
&& DecideExtern(QualType(MPT->getClass(), 0)));
|
||||
if (const PointerType *PT = Ty->getAs<PointerType>())
|
||||
return DecideExtern(PT->getPointeeType());
|
||||
if (const RecordType *RT = Ty->getAs<RecordType>())
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
|
||||
return !RD->isInAnonymousNamespace();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecideHidden(QualType Ty) {
|
||||
// For this type, see if all components are never hidden.
|
||||
if (const MemberPointerType *MPT = Ty->getAs<MemberPointerType>())
|
||||
return (DecideHidden(MPT->getPointeeType())
|
||||
&& DecideHidden(QualType(MPT->getClass(), 0)));
|
||||
if (const PointerType *PT = Ty->getAs<PointerType>())
|
||||
return DecideHidden(PT->getPointeeType());
|
||||
if (const RecordType *RT = Ty->getAs<RecordType>())
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
|
||||
return CGM.getDeclVisibilityMode(RD) == LangOptions::Hidden;
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::Constant *BuildPointerType(QualType Ty) {
|
||||
llvm::Constant *C;
|
||||
|
||||
llvm::SmallString<256> OutName;
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
llvm::GlobalVariable *GV;
|
||||
GV = CGM.getModule().getGlobalVariable(Out.str());
|
||||
GV = CGM.getModule().getGlobalVariable(Name);
|
||||
if (GV && !GV->isDeclaration())
|
||||
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||
|
||||
std::vector<llvm::Constant *> info;
|
||||
|
||||
// FIXME: pointer to hidden should be hidden, we should be able to
|
||||
// grab a bit off the type for this.
|
||||
bool Hidden = false;
|
||||
bool Extern = DecideExtern(Ty);
|
||||
bool Hidden = DecideHidden(Ty);
|
||||
|
||||
QualType PTy = Ty->getPointeeType();
|
||||
QualType BTy;
|
||||
@ -282,7 +325,7 @@ class RttiBuilder {
|
||||
else
|
||||
C = BuildVtableRef("_ZTVN10__cxxabiv119__pointer_type_infoE");
|
||||
info.push_back(C);
|
||||
info.push_back(BuildName(Ty, Hidden));
|
||||
info.push_back(BuildName(Ty, Hidden, Extern));
|
||||
Qualifiers Q = PTy.getQualifiers();
|
||||
PTy = CGM.getContext().getCanonicalType(PTy).getUnqualifiedType();
|
||||
int flags = 0;
|
||||
@ -300,7 +343,8 @@ class RttiBuilder {
|
||||
if (PtrMem)
|
||||
info.push_back(BuildType2(BTy));
|
||||
|
||||
return finish(info, GV, Out.str(), true);
|
||||
// We always generate these as hidden, only the name isn't hidden.
|
||||
return finish(info, GV, Name, true, Extern);
|
||||
}
|
||||
|
||||
llvm::Constant *BuildSimpleType(QualType Ty, const char *vtbl) {
|
||||
@ -309,23 +353,24 @@ class RttiBuilder {
|
||||
llvm::SmallString<256> OutName;
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
mangleCXXRtti(CGM.getMangleContext(), Ty, Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
llvm::GlobalVariable *GV;
|
||||
GV = CGM.getModule().getGlobalVariable(Out.str());
|
||||
GV = CGM.getModule().getGlobalVariable(Name);
|
||||
if (GV && !GV->isDeclaration())
|
||||
return llvm::ConstantExpr::getBitCast(GV, Int8PtrTy);
|
||||
|
||||
std::vector<llvm::Constant *> info;
|
||||
|
||||
// FIXME: pointer to hidden should be hidden, we should be able to
|
||||
// grab a bit off the type for this.
|
||||
bool Hidden = false;
|
||||
bool Extern = DecideExtern(Ty);
|
||||
bool Hidden = DecideHidden(Ty);
|
||||
|
||||
C = BuildVtableRef(vtbl);
|
||||
info.push_back(C);
|
||||
info.push_back(BuildName(Ty, Hidden));
|
||||
info.push_back(BuildName(Ty, Hidden, Extern));
|
||||
|
||||
return finish(info, GV, Out.str(), true);
|
||||
// We always generate these as hidden, only the name isn't hidden.
|
||||
return finish(info, GV, Name, true, Extern);
|
||||
}
|
||||
|
||||
llvm::Constant *BuildType(QualType Ty) {
|
||||
|
@ -69,7 +69,6 @@ class VtableBuilder {
|
||||
llvm::DenseMap<CtorVtable_t, int64_t> &AddressPoints;
|
||||
|
||||
typedef CXXRecordDecl::method_iterator method_iter;
|
||||
// FIXME: Linkage should follow vtable
|
||||
const bool Extern;
|
||||
const uint32_t LLVMPointerWidth;
|
||||
Index_t extra;
|
||||
@ -82,7 +81,7 @@ class VtableBuilder {
|
||||
BLayout(cgm.getContext().getASTRecordLayout(l)),
|
||||
rtti(cgm.GenerateRttiRef(c)), VMContext(cgm.getModule().getContext()),
|
||||
CGM(cgm), AddressPoints(*new llvm::DenseMap<CtorVtable_t, int64_t>),
|
||||
Extern(true),
|
||||
Extern(!l->isInAnonymousNamespace()),
|
||||
LLVMPointerWidth(cgm.getContext().Target.getPointerWidth(0)) {
|
||||
Ptr8Ty = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
|
||||
|
||||
@ -788,37 +787,73 @@ llvm::Constant *CodeGenModule::GenerateVtable(const CXXRecordDecl *LayoutClass,
|
||||
mangleCXXCtorVtable(getMangleContext(), LayoutClass, Offset/8, RD, Out);
|
||||
else
|
||||
mangleCXXVtable(getMangleContext(), RD, Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
llvm::GlobalVariable::LinkageTypes linktype;
|
||||
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||
std::vector<llvm::Constant *> methods;
|
||||
llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
|
||||
int64_t AddressPoint;
|
||||
|
||||
VtableBuilder b(methods, RD, LayoutClass, Offset, *this);
|
||||
llvm::GlobalVariable *GV = getModule().getGlobalVariable(Name);
|
||||
if (GV && AddressPoints[LayoutClass] && !GV->isDeclaration())
|
||||
AddressPoint=(*(*(AddressPoints[LayoutClass]))[RD])[std::make_pair(RD,
|
||||
Offset)];
|
||||
else {
|
||||
VtableBuilder b(methods, RD, LayoutClass, Offset, *this);
|
||||
|
||||
D1(printf("vtable %s\n", RD->getNameAsCString()));
|
||||
// First comes the vtables for all the non-virtual bases...
|
||||
AddressPoint = b.GenerateVtableForBase(RD, Offset);
|
||||
D1(printf("vtable %s\n", RD->getNameAsCString()));
|
||||
// First comes the vtables for all the non-virtual bases...
|
||||
AddressPoint = b.GenerateVtableForBase(RD, Offset);
|
||||
|
||||
// then the vtables for all the virtual bases.
|
||||
b.GenerateVtableForVBases(RD, Offset);
|
||||
// then the vtables for all the virtual bases.
|
||||
b.GenerateVtableForVBases(RD, Offset);
|
||||
|
||||
CodeGenModule::AddrMap_t *&ref = AddressPoints[LayoutClass];
|
||||
if (ref == 0)
|
||||
ref = new CodeGenModule::AddrMap_t;
|
||||
CodeGenModule::AddrMap_t *&ref = AddressPoints[LayoutClass];
|
||||
if (ref == 0)
|
||||
ref = new CodeGenModule::AddrMap_t;
|
||||
|
||||
(*ref)[RD] = b.getAddressPoints();
|
||||
(*ref)[RD] = b.getAddressPoints();
|
||||
|
||||
llvm::Constant *C;
|
||||
llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, methods.size());
|
||||
C = llvm::ConstantArray::get(type, methods);
|
||||
llvm::GlobalVariable *GV = new llvm::GlobalVariable(getModule(), type,
|
||||
true, linktype, C,
|
||||
Out.str());
|
||||
bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
|
||||
if (Hidden)
|
||||
GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
|
||||
bool CreateDefinition = true;
|
||||
if (LayoutClass != RD)
|
||||
CreateDefinition = true;
|
||||
else {
|
||||
// We have to convert it to have a record layout.
|
||||
Types.ConvertTagDeclType(LayoutClass);
|
||||
const CGRecordLayout &CGLayout = Types.getCGRecordLayout(LayoutClass);
|
||||
if (const CXXMethodDecl *KeyFunction = CGLayout.getKeyFunction()) {
|
||||
if (!KeyFunction->getBody()) {
|
||||
// If there is a KeyFunction, and it isn't defined, just build a
|
||||
// reference to the vtable.
|
||||
CreateDefinition = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Constant *C = 0;
|
||||
llvm::Type *type = Ptr8Ty;
|
||||
llvm::GlobalVariable::LinkageTypes linktype
|
||||
= llvm::GlobalValue::ExternalLinkage;
|
||||
if (CreateDefinition) {
|
||||
llvm::ArrayType *ntype = llvm::ArrayType::get(Ptr8Ty, methods.size());
|
||||
C = llvm::ConstantArray::get(ntype, methods);
|
||||
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||
if (LayoutClass->isInAnonymousNamespace())
|
||||
linktype = llvm::GlobalValue::InternalLinkage;
|
||||
type = ntype;
|
||||
}
|
||||
llvm::GlobalVariable *OGV = GV;
|
||||
GV = new llvm::GlobalVariable(getModule(), type, true, linktype, C, Name);
|
||||
if (OGV) {
|
||||
GV->takeName(OGV);
|
||||
llvm::Constant *NewPtr = llvm::ConstantExpr::getBitCast(GV,
|
||||
OGV->getType());
|
||||
OGV->replaceAllUsesWith(NewPtr);
|
||||
OGV->eraseFromParent();
|
||||
}
|
||||
bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
|
||||
if (Hidden)
|
||||
GV->setVisibility(llvm::GlobalVariable::HiddenVisibility);
|
||||
}
|
||||
llvm::Constant *vtable = llvm::ConstantExpr::getBitCast(GV, Ptr8Ty);
|
||||
llvm::Constant *AddressPointC;
|
||||
uint32_t LLVMPointerWidth = getContext().Target.getPointerWidth(0);
|
||||
@ -1001,9 +1036,12 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
|
||||
llvm::SmallString<256> OutName;
|
||||
llvm::raw_svector_ostream Out(OutName);
|
||||
mangleCXXVTT(getMangleContext(), RD, Out);
|
||||
llvm::StringRef Name = Out.str();
|
||||
|
||||
llvm::GlobalVariable::LinkageTypes linktype;
|
||||
linktype = llvm::GlobalValue::LinkOnceODRLinkage;
|
||||
if (RD->isInAnonymousNamespace())
|
||||
linktype = llvm::GlobalValue::InternalLinkage;
|
||||
std::vector<llvm::Constant *> inits;
|
||||
llvm::Type *Ptr8Ty=llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext),0);
|
||||
|
||||
@ -1015,20 +1053,41 @@ llvm::Constant *CodeGenModule::GenerateVTT(const CXXRecordDecl *RD) {
|
||||
llvm::ArrayType *type = llvm::ArrayType::get(Ptr8Ty, inits.size());
|
||||
C = llvm::ConstantArray::get(type, inits);
|
||||
llvm::GlobalVariable *vtt = new llvm::GlobalVariable(getModule(), type, true,
|
||||
linktype, C, Out.str());
|
||||
linktype, C, Name);
|
||||
bool Hidden = getDeclVisibilityMode(RD) == LangOptions::Hidden;
|
||||
if (Hidden)
|
||||
vtt->setVisibility(llvm::GlobalVariable::HiddenVisibility);
|
||||
return llvm::ConstantExpr::getBitCast(vtt, Ptr8Ty);
|
||||
}
|
||||
|
||||
void CGVtableInfo::GenerateClassData(const CXXRecordDecl *RD) {
|
||||
Vtables[RD] = CGM.GenerateVtable(RD, RD);
|
||||
CGM.GenerateRtti(RD);
|
||||
CGM.GenerateVTT(RD);
|
||||
}
|
||||
|
||||
llvm::Constant *CGVtableInfo::getVtable(const CXXRecordDecl *RD) {
|
||||
llvm::Constant *&vtbl = Vtables[RD];
|
||||
if (vtbl)
|
||||
return vtbl;
|
||||
vtbl = CGM.GenerateVtable(RD, RD);
|
||||
CGM.GenerateRtti(RD);
|
||||
CGM.GenerateVTT(RD);
|
||||
|
||||
bool CreateDefinition = true;
|
||||
// We have to convert it to have a record layout.
|
||||
CGM.getTypes().ConvertTagDeclType(RD);
|
||||
const CGRecordLayout &CGLayout = CGM.getTypes().getCGRecordLayout(RD);
|
||||
if (const CXXMethodDecl *KeyFunction = CGLayout.getKeyFunction()) {
|
||||
if (!KeyFunction->getBody()) {
|
||||
// If there is a KeyFunction, and it isn't defined, just build a
|
||||
// reference to the vtable.
|
||||
CreateDefinition = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (CreateDefinition) {
|
||||
CGM.GenerateRtti(RD);
|
||||
CGM.GenerateVTT(RD);
|
||||
}
|
||||
return vtbl;
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,10 @@ class CGVtableInfo {
|
||||
llvm::Constant *getVtable(const CXXRecordDecl *RD);
|
||||
llvm::Constant *getCtorVtable(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *Class, uint64_t Offset);
|
||||
/// GenerateClassData - Generate all the class data requires to be generated
|
||||
/// upon definition of a KeyFunction. This includes the vtable, the
|
||||
/// rtti data structure and the VTT.
|
||||
void GenerateClassData(const CXXRecordDecl *RD);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -616,6 +616,16 @@ void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
Context.getSourceManager(),
|
||||
"Generating code for declaration");
|
||||
|
||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
|
||||
const CXXRecordDecl *RD = MD->getParent();
|
||||
// We have to convert it to have a record layout.
|
||||
Types.ConvertTagDeclType(RD);
|
||||
const CGRecordLayout &CGLayout = Types.getCGRecordLayout(RD);
|
||||
// A definition of a KeyFunction, generates all the class data, such
|
||||
// as vtable, rtti and the VTT.
|
||||
if (CGLayout.getKeyFunction() == MD)
|
||||
getVtableInfo().GenerateClassData(RD);
|
||||
}
|
||||
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))
|
||||
EmitCXXConstructor(CD, GD.getCtorType());
|
||||
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D))
|
||||
|
@ -27,38 +27,41 @@ void ArgList::append(Arg *A) {
|
||||
Args.push_back(A);
|
||||
}
|
||||
|
||||
Arg *ArgList::getLastArg(options::ID Id, bool Claim) const {
|
||||
Arg *ArgList::getLastArgNoClaim(OptSpecifier Id) const {
|
||||
// FIXME: Make search efficient?
|
||||
for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it) {
|
||||
if ((*it)->getOption().matches(Id)) {
|
||||
if (Claim) (*it)->claim();
|
||||
for (const_reverse_iterator it = rbegin(), ie = rend(); it != ie; ++it)
|
||||
if ((*it)->getOption().matches(Id))
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, bool Claim) const {
|
||||
Arg *Res, *A0 = getLastArg(Id0, false), *A1 = getLastArg(Id1, false);
|
||||
Arg *ArgList::getLastArg(OptSpecifier Id) const {
|
||||
Arg *A = getLastArgNoClaim(Id);
|
||||
if (A)
|
||||
A->claim();
|
||||
return A;
|
||||
}
|
||||
|
||||
Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1) const {
|
||||
Arg *Res, *A0 = getLastArgNoClaim(Id0), *A1 = getLastArgNoClaim(Id1);
|
||||
|
||||
if (A0 && A1)
|
||||
Res = A0->getIndex() > A1->getIndex() ? A0 : A1;
|
||||
else
|
||||
Res = A0 ? A0 : A1;
|
||||
|
||||
if (Claim && Res)
|
||||
if (Res)
|
||||
Res->claim();
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
|
||||
bool Claim) const {
|
||||
Arg *ArgList::getLastArg(OptSpecifier Id0, OptSpecifier Id1,
|
||||
OptSpecifier Id2) const {
|
||||
Arg *Res = 0;
|
||||
Arg *A0 = getLastArg(Id0, false);
|
||||
Arg *A1 = getLastArg(Id1, false);
|
||||
Arg *A2 = getLastArg(Id2, false);
|
||||
Arg *A0 = getLastArgNoClaim(Id0);
|
||||
Arg *A1 = getLastArgNoClaim(Id1);
|
||||
Arg *A2 = getLastArgNoClaim(Id2);
|
||||
|
||||
int A0Idx = A0 ? A0->getIndex() : -1;
|
||||
int A1Idx = A1 ? A1->getIndex() : -1;
|
||||
@ -76,26 +79,26 @@ Arg *ArgList::getLastArg(options::ID Id0, options::ID Id1, options::ID Id2,
|
||||
Res = A2;
|
||||
}
|
||||
|
||||
if (Claim && Res)
|
||||
if (Res)
|
||||
Res->claim();
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
bool ArgList::hasFlag(options::ID Pos, options::ID Neg, bool Default) const {
|
||||
bool ArgList::hasFlag(OptSpecifier Pos, OptSpecifier Neg, bool Default) const {
|
||||
if (Arg *A = getLastArg(Pos, Neg))
|
||||
return A->getOption().matches(Pos);
|
||||
return Default;
|
||||
}
|
||||
|
||||
void ArgList::AddLastArg(ArgStringList &Output, options::ID Id) const {
|
||||
void ArgList::AddLastArg(ArgStringList &Output, OptSpecifier Id) const {
|
||||
if (Arg *A = getLastArg(Id)) {
|
||||
A->claim();
|
||||
A->render(*this, Output);
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
|
||||
void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0) const {
|
||||
// FIXME: Make fast.
|
||||
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
@ -106,8 +109,8 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0) const {
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
|
||||
options::ID Id1) const {
|
||||
void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
|
||||
OptSpecifier Id1) const {
|
||||
// FIXME: Make fast.
|
||||
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
@ -118,8 +121,8 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
|
||||
options::ID Id1, options::ID Id2) const {
|
||||
void ArgList::AddAllArgs(ArgStringList &Output, OptSpecifier Id0,
|
||||
OptSpecifier Id1, OptSpecifier Id2) const {
|
||||
// FIXME: Make fast.
|
||||
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
@ -131,7 +134,7 @@ void ArgList::AddAllArgs(ArgStringList &Output, options::ID Id0,
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
|
||||
void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0) const {
|
||||
// FIXME: Make fast.
|
||||
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
@ -143,8 +146,8 @@ void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0) const {
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0,
|
||||
options::ID Id1) const {
|
||||
void ArgList::AddAllArgValues(ArgStringList &Output, OptSpecifier Id0,
|
||||
OptSpecifier Id1) const {
|
||||
// FIXME: Make fast.
|
||||
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
@ -156,7 +159,7 @@ void ArgList::AddAllArgValues(ArgStringList &Output, options::ID Id0,
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
|
||||
void ArgList::AddAllArgsTranslated(ArgStringList &Output, OptSpecifier Id0,
|
||||
const char *Translation,
|
||||
bool Joined) const {
|
||||
// FIXME: Make fast.
|
||||
@ -177,7 +180,7 @@ void ArgList::AddAllArgsTranslated(ArgStringList &Output, options::ID Id0,
|
||||
}
|
||||
}
|
||||
|
||||
void ArgList::ClaimAllArgs(options::ID Id0) const {
|
||||
void ArgList::ClaimAllArgs(OptSpecifier Id0) const {
|
||||
// FIXME: Make fast.
|
||||
for (const_iterator it = begin(), ie = end(); it != ie; ++it) {
|
||||
const Arg *A = *it;
|
||||
|
43
lib/Driver/CC1Options.cpp
Normal file
43
lib/Driver/CC1Options.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
//===--- CC1Options.cpp - Clang CC1 Options Table -----------------------*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/CC1Options.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::options;
|
||||
using namespace clang::driver::cc1options;
|
||||
|
||||
static OptTable::Info CC1InfoTable[] = {
|
||||
// The InputOption info
|
||||
{ "<input>", 0, 0, Option::InputClass, DriverOption, 0, OPT_INVALID, OPT_INVALID },
|
||||
// The UnknownOption info
|
||||
{ "<unknown>", 0, 0, Option::UnknownClass, 0, 0, OPT_INVALID, OPT_INVALID },
|
||||
|
||||
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR) \
|
||||
{ NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
|
||||
OPT_##GROUP, OPT_##ALIAS },
|
||||
#include "clang/Driver/CC1Options.inc"
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
class CC1OptTable : public OptTable {
|
||||
public:
|
||||
CC1OptTable()
|
||||
: OptTable(CC1InfoTable, sizeof(CC1InfoTable) / sizeof(CC1InfoTable[0])) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OptTable *clang::driver::createCC1OptTable() {
|
||||
return new CC1OptTable();
|
||||
}
|
@ -4,8 +4,10 @@ add_clang_library(clangDriver
|
||||
Action.cpp
|
||||
Arg.cpp
|
||||
ArgList.cpp
|
||||
CC1Options.cpp
|
||||
Compilation.cpp
|
||||
Driver.cpp
|
||||
DriverOptions.cpp
|
||||
HostInfo.cpp
|
||||
Job.cpp
|
||||
OptTable.cpp
|
||||
@ -18,4 +20,4 @@ add_clang_library(clangDriver
|
||||
Types.cpp
|
||||
)
|
||||
|
||||
add_dependencies(clangDriver ClangDiagnosticDriver)
|
||||
add_dependencies(clangDriver ClangDiagnosticDriver ClangDriverOptions ClangCC1Options)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "clang/Driver/ArgList.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Driver/HostInfo.h"
|
||||
#include "clang/Driver/Job.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
@ -44,7 +45,7 @@ Driver::Driver(const char *_Name, const char *_Dir,
|
||||
const char *_DefaultHostTriple,
|
||||
const char *_DefaultImageName,
|
||||
bool IsProduction, Diagnostic &_Diags)
|
||||
: Opts(new OptTable()), Diags(_Diags),
|
||||
: Opts(createDriverOptTable()), Diags(_Diags),
|
||||
Name(_Name), Dir(_Dir), DefaultHostTriple(_DefaultHostTriple),
|
||||
DefaultImageName(_DefaultImageName),
|
||||
Host(0),
|
||||
@ -75,40 +76,23 @@ Driver::~Driver() {
|
||||
InputArgList *Driver::ParseArgStrings(const char **ArgBegin,
|
||||
const char **ArgEnd) {
|
||||
llvm::PrettyStackTraceString CrashInfo("Command line argument parsing");
|
||||
InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
|
||||
unsigned MissingArgIndex, MissingArgCount;
|
||||
InputArgList *Args = getOpts().ParseArgs(ArgBegin, ArgEnd,
|
||||
MissingArgIndex, MissingArgCount);
|
||||
|
||||
// FIXME: Handle '@' args (or at least error on them).
|
||||
|
||||
unsigned Index = 0, End = ArgEnd - ArgBegin;
|
||||
while (Index < End) {
|
||||
// gcc's handling of empty arguments doesn't make sense, but this is not a
|
||||
// common use case. :)
|
||||
//
|
||||
// We just ignore them here (note that other things may still take them as
|
||||
// arguments).
|
||||
if (Args->getArgString(Index)[0] == '\0') {
|
||||
++Index;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned Prev = Index;
|
||||
Arg *A = getOpts().ParseOneArg(*Args, Index);
|
||||
assert(Index > Prev && "Parser failed to consume argument.");
|
||||
|
||||
// Check for missing argument error.
|
||||
if (!A) {
|
||||
assert(Index >= End && "Unexpected parser error.");
|
||||
Diag(clang::diag::err_drv_missing_argument)
|
||||
<< Args->getArgString(Prev)
|
||||
<< (Index - Prev - 1);
|
||||
break;
|
||||
}
|
||||
// Check for missing argument error.
|
||||
if (MissingArgCount)
|
||||
Diag(clang::diag::err_drv_missing_argument)
|
||||
<< Args->getArgString(MissingArgIndex) << MissingArgCount;
|
||||
|
||||
// Check for unsupported options.
|
||||
for (ArgList::const_iterator it = Args->begin(), ie = Args->end();
|
||||
it != ie; ++it) {
|
||||
Arg *A = *it;
|
||||
if (A->getOption().isUnsupported()) {
|
||||
Diag(clang::diag::err_drv_unsupported_opt) << A->getAsString(*Args);
|
||||
continue;
|
||||
}
|
||||
Args->append(A);
|
||||
}
|
||||
|
||||
return Args;
|
||||
@ -340,8 +324,8 @@ void Driver::PrintHelp(bool ShowHidden) const {
|
||||
// Render help text into (option, help) pairs.
|
||||
std::vector< std::pair<std::string, const char*> > OptionHelp;
|
||||
|
||||
for (unsigned i = options::OPT_INPUT, e = options::LastOption; i != e; ++i) {
|
||||
options::ID Id = (options::ID) i;
|
||||
for (unsigned i = 0, e = getOpts().getNumOptions(); i != e; ++i) {
|
||||
options::ID Id = (options::ID) (i + 1);
|
||||
if (const char *Text = getOpts().getOptionHelpText(Id))
|
||||
OptionHelp.push_back(std::make_pair(getOptionHelpName(getOpts(), Id),
|
||||
Text));
|
||||
@ -591,7 +575,7 @@ void Driver::BuildUniversalActions(const ArgList &Args,
|
||||
it != ie; ++it) {
|
||||
Arg *A = *it;
|
||||
|
||||
if (A->getOption().getId() == options::OPT_arch) {
|
||||
if (A->getOption().matches(options::OPT_arch)) {
|
||||
// Validate the option here; we don't save the type here because its
|
||||
// particular spelling may participate in other driver choices.
|
||||
llvm::Triple::ArchType Arch =
|
||||
@ -686,7 +670,7 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
|
||||
//
|
||||
// Otherwise emit an error but still use a valid type to avoid
|
||||
// spurious errors (e.g., no inputs).
|
||||
if (!Args.hasArg(options::OPT_E, false))
|
||||
if (!Args.hasArgNoClaim(options::OPT_E))
|
||||
Diag(clang::diag::err_drv_unknown_stdin_type);
|
||||
Ty = types::TY_C;
|
||||
} else {
|
||||
@ -730,7 +714,7 @@ void Driver::BuildActions(const ArgList &Args, ActionList &Actions) const {
|
||||
// necessary.
|
||||
Inputs.push_back(std::make_pair(types::TY_Object, A));
|
||||
|
||||
} else if (A->getOption().getId() == options::OPT_x) {
|
||||
} else if (A->getOption().matches(options::OPT_x)) {
|
||||
InputTypeArg = A;
|
||||
InputType = types::lookupTypeForTypeSpecifier(A->getValue(Args));
|
||||
|
||||
@ -984,7 +968,7 @@ void Driver::BuildJobs(Compilation &C) const {
|
||||
// FIXME: Use iterator.
|
||||
for (ArgList::const_iterator it = C.getArgs().begin(),
|
||||
ie = C.getArgs().end(); it != ie; ++it) {
|
||||
if ((*it)->isClaimed() && (*it)->getOption().matches(Opt.getId())) {
|
||||
if ((*it)->isClaimed() && (*it)->getOption().matches(&Opt)) {
|
||||
DuplicateClaimed = true;
|
||||
break;
|
||||
}
|
||||
|
42
lib/Driver/DriverOptions.cpp
Normal file
42
lib/Driver/DriverOptions.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
//===--- DriverOptions.cpp - Driver Options Table -----------------------*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::options;
|
||||
|
||||
static OptTable::Info InfoTable[] = {
|
||||
// The InputOption info
|
||||
{ "<input>", 0, 0, Option::InputClass, DriverOption, 0, OPT_INVALID, OPT_INVALID },
|
||||
// The UnknownOption info
|
||||
{ "<unknown>", 0, 0, Option::UnknownClass, 0, 0, OPT_INVALID, OPT_INVALID },
|
||||
|
||||
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR) \
|
||||
{ NAME, HELPTEXT, METAVAR, Option::KIND##Class, FLAGS, PARAM, \
|
||||
OPT_##GROUP, OPT_##ALIAS },
|
||||
#include "clang/Driver/Options.inc"
|
||||
};
|
||||
|
||||
namespace {
|
||||
|
||||
class DriverOptTable : public OptTable {
|
||||
public:
|
||||
DriverOptTable()
|
||||
: OptTable(InfoTable, sizeof(InfoTable) / sizeof(InfoTable[0])) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OptTable *clang::driver::createDriverOptTable() {
|
||||
return new DriverOptTable();
|
||||
}
|
@ -122,7 +122,7 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
|
||||
//
|
||||
// FIXME: Should this information be in llvm::Triple?
|
||||
if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
|
||||
if (A->getOption().getId() == options::OPT_m32) {
|
||||
if (A->getOption().matches(options::OPT_m32)) {
|
||||
if (Arch == llvm::Triple::x86_64)
|
||||
Arch = llvm::Triple::x86;
|
||||
if (Arch == llvm::Triple::ppc64)
|
||||
@ -205,11 +205,11 @@ ToolChain *UnknownHostInfo::CreateToolChain(const ArgList &Args,
|
||||
if (Triple.getArch() == llvm::Triple::x86 ||
|
||||
Triple.getArch() == llvm::Triple::x86_64) {
|
||||
ArchName =
|
||||
(A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
|
||||
(A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
|
||||
} else if (Triple.getArch() == llvm::Triple::ppc ||
|
||||
Triple.getArch() == llvm::Triple::ppc64) {
|
||||
ArchName =
|
||||
(A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
|
||||
(A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,11 +478,11 @@ ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args,
|
||||
if (Triple.getArch() == llvm::Triple::x86 ||
|
||||
Triple.getArch() == llvm::Triple::x86_64) {
|
||||
ArchName =
|
||||
(A->getOption().getId() == options::OPT_m32) ? "i386" : "x86_64";
|
||||
(A->getOption().matches(options::OPT_m32)) ? "i386" : "x86_64";
|
||||
} else if (Triple.getArch() == llvm::Triple::ppc ||
|
||||
Triple.getArch() == llvm::Triple::ppc64) {
|
||||
ArchName =
|
||||
(A->getOption().getId() == options::OPT_m32) ? "powerpc" : "powerpc64";
|
||||
(A->getOption().matches(options::OPT_m32)) ? "powerpc" : "powerpc64";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- Options.cpp - Option info table --------------------------------*-===//
|
||||
//===--- OptTable.cpp - Option Table Implementation ---------------------*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,8 +7,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/Options.h"
|
||||
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "clang/Driver/Arg.h"
|
||||
#include "clang/Driver/ArgList.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
@ -18,18 +17,6 @@
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::options;
|
||||
|
||||
struct Info {
|
||||
const char *Name;
|
||||
const char *Flags;
|
||||
const char *HelpText;
|
||||
const char *MetaVar;
|
||||
|
||||
Option::OptionClass Kind;
|
||||
unsigned GroupID;
|
||||
unsigned AliasID;
|
||||
unsigned Param;
|
||||
};
|
||||
|
||||
// Ordering on Info. The ordering is *almost* lexicographic, with two
|
||||
// exceptions. First, '\0' comes at the end of the alphabet instead of
|
||||
// the beginning (thus options preceed any other options which prefix
|
||||
@ -56,7 +43,9 @@ static int StrCmpOptionName(const char *A, const char *B) {
|
||||
return (a < b) ? -1 : 1;
|
||||
}
|
||||
|
||||
static inline bool operator<(const Info &A, const Info &B) {
|
||||
namespace clang {
|
||||
namespace driver {
|
||||
static inline bool operator<(const OptTable::Info &A, const OptTable::Info &B) {
|
||||
if (&A == &B)
|
||||
return false;
|
||||
|
||||
@ -70,57 +59,62 @@ static inline bool operator<(const Info &A, const Info &B) {
|
||||
return B.Kind == Option::JoinedClass;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
static Info OptionInfos[] = {
|
||||
// The InputOption info
|
||||
{ "<input>", "d", 0, 0, Option::InputClass, OPT_INVALID, OPT_INVALID, 0 },
|
||||
// The UnknownOption info
|
||||
{ "<unknown>", "", 0, 0, Option::UnknownClass, OPT_INVALID, OPT_INVALID, 0 },
|
||||
|
||||
#define OPTION(NAME, ID, KIND, GROUP, ALIAS, FLAGS, PARAM, \
|
||||
HELPTEXT, METAVAR) \
|
||||
{ NAME, FLAGS, HELPTEXT, METAVAR, \
|
||||
Option::KIND##Class, OPT_##GROUP, OPT_##ALIAS, PARAM },
|
||||
#include "clang/Driver/Options.def"
|
||||
};
|
||||
static const unsigned numOptions = sizeof(OptionInfos) / sizeof(OptionInfos[0]);
|
||||
|
||||
static Info &getInfo(unsigned id) {
|
||||
assert(id > 0 && id - 1 < numOptions && "Invalid Option ID.");
|
||||
return OptionInfos[id - 1];
|
||||
// Support lower_bound between info and an option name.
|
||||
static inline bool operator<(const OptTable::Info &I, const char *Name) {
|
||||
return StrCmpOptionName(I.Name, Name) == -1;
|
||||
}
|
||||
static inline bool operator<(const char *Name, const OptTable::Info &I) {
|
||||
return StrCmpOptionName(Name, I.Name) == -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OptTable::OptTable() : Options(new Option*[numOptions]) {
|
||||
//
|
||||
|
||||
OptSpecifier::OptSpecifier(const Option *Opt) : ID(Opt->getID()) {}
|
||||
|
||||
//
|
||||
|
||||
OptTable::OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos)
|
||||
: OptionInfos(_OptionInfos), NumOptionInfos(_NumOptionInfos),
|
||||
Options(new Option*[NumOptionInfos]),
|
||||
TheInputOption(0), TheUnknownOption(0), FirstSearchableIndex(0)
|
||||
{
|
||||
// Explicitly zero initialize the error to work around a bug in array
|
||||
// value-initialization on MinGW with gcc 4.3.5.
|
||||
memset(Options, 0, sizeof(*Options) * numOptions);
|
||||
memset(Options, 0, sizeof(*Options) * NumOptionInfos);
|
||||
|
||||
// Find start of normal options.
|
||||
FirstSearchableOption = 0;
|
||||
for (unsigned i = OPT_UNKNOWN + 1; i < LastOption; ++i) {
|
||||
if (getInfo(i).Kind != Option::GroupClass) {
|
||||
FirstSearchableOption = i;
|
||||
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
|
||||
unsigned Kind = getInfo(i + 1).Kind;
|
||||
if (Kind == Option::InputClass) {
|
||||
assert(!TheInputOption && "Cannot have multiple input options!");
|
||||
TheInputOption = getOption(i + 1);
|
||||
} else if (Kind == Option::UnknownClass) {
|
||||
assert(!TheUnknownOption && "Cannot have multiple input options!");
|
||||
TheUnknownOption = getOption(i + 1);
|
||||
} else if (Kind != Option::GroupClass) {
|
||||
FirstSearchableIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(FirstSearchableOption != 0 && "No searchable options?");
|
||||
assert(FirstSearchableIndex != 0 && "No searchable options?");
|
||||
|
||||
#ifndef NDEBUG
|
||||
// Check that everything after the first searchable option is a
|
||||
// regular option class.
|
||||
for (unsigned i = FirstSearchableOption; i < LastOption; ++i) {
|
||||
Option::OptionClass Kind = getInfo(i).Kind;
|
||||
for (unsigned i = FirstSearchableIndex, e = getNumOptions(); i != e; ++i) {
|
||||
Option::OptionClass Kind = (Option::OptionClass) getInfo(i + 1).Kind;
|
||||
assert((Kind != Option::InputClass && Kind != Option::UnknownClass &&
|
||||
Kind != Option::GroupClass) &&
|
||||
"Special options should be defined first!");
|
||||
}
|
||||
|
||||
// Check that options are in order.
|
||||
for (unsigned i = FirstSearchableOption + 1; i < LastOption; ++i) {
|
||||
if (!(getInfo(i - 1) < getInfo(i))) {
|
||||
getOption((options::ID) (i - 1))->dump();
|
||||
getOption((options::ID) i)->dump();
|
||||
for (unsigned i = FirstSearchableIndex+1, e = getNumOptions(); i != e; ++i) {
|
||||
if (!(getInfo(i) < getInfo(i + 1))) {
|
||||
getOption(i)->dump();
|
||||
getOption(i + 1)->dump();
|
||||
assert(0 && "Options are not in order!");
|
||||
}
|
||||
}
|
||||
@ -128,56 +122,23 @@ OptTable::OptTable() : Options(new Option*[numOptions]) {
|
||||
}
|
||||
|
||||
OptTable::~OptTable() {
|
||||
for (unsigned i = 0; i < numOptions; ++i)
|
||||
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
|
||||
delete Options[i];
|
||||
delete[] Options;
|
||||
}
|
||||
|
||||
unsigned OptTable::getNumOptions() const {
|
||||
return numOptions;
|
||||
}
|
||||
|
||||
const char *OptTable::getOptionName(options::ID id) const {
|
||||
return getInfo(id).Name;
|
||||
}
|
||||
|
||||
unsigned OptTable::getOptionKind(options::ID id) const {
|
||||
return getInfo(id).Kind;
|
||||
}
|
||||
|
||||
const char *OptTable::getOptionHelpText(options::ID id) const {
|
||||
return getInfo(id).HelpText;
|
||||
}
|
||||
|
||||
const char *OptTable::getOptionMetaVar(options::ID id) const {
|
||||
return getInfo(id).MetaVar;
|
||||
}
|
||||
|
||||
const Option *OptTable::getOption(options::ID id) const {
|
||||
if (id == OPT_INVALID)
|
||||
return 0;
|
||||
|
||||
assert((unsigned) (id - 1) < numOptions && "Invalid ID.");
|
||||
|
||||
Option *&Entry = Options[id - 1];
|
||||
if (!Entry)
|
||||
Entry = constructOption(id);
|
||||
|
||||
return Entry;
|
||||
}
|
||||
|
||||
Option *OptTable::constructOption(options::ID id) const {
|
||||
Info &info = getInfo(id);
|
||||
Option *OptTable::CreateOption(unsigned id) const {
|
||||
const Info &info = getInfo(id);
|
||||
const OptionGroup *Group =
|
||||
cast_or_null<OptionGroup>(getOption((options::ID) info.GroupID));
|
||||
const Option *Alias = getOption((options::ID) info.AliasID);
|
||||
cast_or_null<OptionGroup>(getOption(info.GroupID));
|
||||
const Option *Alias = getOption(info.AliasID);
|
||||
|
||||
Option *Opt = 0;
|
||||
switch (info.Kind) {
|
||||
case Option::InputClass:
|
||||
Opt = new InputOption(); break;
|
||||
Opt = new InputOption(id); break;
|
||||
case Option::UnknownClass:
|
||||
Opt = new UnknownOption(); break;
|
||||
Opt = new UnknownOption(id); break;
|
||||
case Option::GroupClass:
|
||||
Opt = new OptionGroup(id, info.Name, Group); break;
|
||||
case Option::FlagClass:
|
||||
@ -196,44 +157,38 @@ Option *OptTable::constructOption(options::ID id) const {
|
||||
Opt = new JoinedAndSeparateOption(id, info.Name, Group, Alias); break;
|
||||
}
|
||||
|
||||
for (const char *s = info.Flags; *s; ++s) {
|
||||
switch (*s) {
|
||||
default: assert(0 && "Invalid option flag.");
|
||||
case 'J':
|
||||
assert(info.Kind == Option::SeparateClass && "Invalid option.");
|
||||
Opt->setForceJoinedRender(true); break;
|
||||
case 'S':
|
||||
assert(info.Kind == Option::JoinedClass && "Invalid option.");
|
||||
Opt->setForceSeparateRender(true); break;
|
||||
case 'd': Opt->setDriverOption(true); break;
|
||||
case 'i': Opt->setNoOptAsInput(true); break;
|
||||
case 'l': Opt->setLinkerInput(true); break;
|
||||
case 'q': Opt->setNoArgumentUnused(true); break;
|
||||
case 'u': Opt->setUnsupported(true); break;
|
||||
}
|
||||
if (info.Flags & DriverOption)
|
||||
Opt->setDriverOption(true);
|
||||
if (info.Flags & LinkerInput)
|
||||
Opt->setLinkerInput(true);
|
||||
if (info.Flags & NoArgumentUnused)
|
||||
Opt->setNoArgumentUnused(true);
|
||||
if (info.Flags & RenderAsInput)
|
||||
Opt->setNoOptAsInput(true);
|
||||
if (info.Flags & RenderJoined) {
|
||||
assert(info.Kind == Option::SeparateClass && "Invalid option.");
|
||||
Opt->setForceJoinedRender(true);
|
||||
}
|
||||
if (info.Flags & RenderSeparate) {
|
||||
assert(info.Kind == Option::JoinedClass && "Invalid option.");
|
||||
Opt->setForceSeparateRender(true);
|
||||
}
|
||||
if (info.Flags & Unsupported)
|
||||
Opt->setUnsupported(true);
|
||||
|
||||
return Opt;
|
||||
}
|
||||
|
||||
// Support lower_bound between info and an option name.
|
||||
static inline bool operator<(struct Info &I, const char *Name) {
|
||||
return StrCmpOptionName(I.Name, Name) == -1;
|
||||
}
|
||||
static inline bool operator<(const char *Name, struct Info &I) {
|
||||
return StrCmpOptionName(Name, I.Name) == -1;
|
||||
}
|
||||
|
||||
Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
|
||||
unsigned Prev = Index;
|
||||
const char *Str = Args.getArgString(Index);
|
||||
|
||||
// Anything that doesn't start with '-' is an input, as is '-' itself.
|
||||
if (Str[0] != '-' || Str[1] == '\0')
|
||||
return new PositionalArg(getOption(OPT_INPUT), Index++);
|
||||
return new PositionalArg(TheInputOption, Index++);
|
||||
|
||||
struct Info *Start = OptionInfos + FirstSearchableOption - 1;
|
||||
struct Info *End = OptionInfos + LastOption - 1;
|
||||
const Info *Start = OptionInfos + FirstSearchableIndex;
|
||||
const Info *End = OptionInfos + getNumOptions();
|
||||
|
||||
// Search for the first next option which could be a prefix.
|
||||
Start = std::lower_bound(Start, End, Str);
|
||||
@ -255,8 +210,7 @@ Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
|
||||
break;
|
||||
|
||||
// See if this option matches.
|
||||
options::ID id = (options::ID) (Start - OptionInfos + 1);
|
||||
if (Arg *A = getOption(id)->accept(Args, Index))
|
||||
if (Arg *A = getOption(Start - OptionInfos + 1)->accept(Args, Index))
|
||||
return A;
|
||||
|
||||
// Otherwise, see if this argument was missing values.
|
||||
@ -264,6 +218,40 @@ Arg *OptTable::ParseOneArg(const InputArgList &Args, unsigned &Index) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new PositionalArg(getOption(OPT_UNKNOWN), Index++);
|
||||
return new PositionalArg(TheUnknownOption, Index++);
|
||||
}
|
||||
|
||||
InputArgList *OptTable::ParseArgs(const char **ArgBegin, const char **ArgEnd,
|
||||
unsigned &MissingArgIndex,
|
||||
unsigned &MissingArgCount) const {
|
||||
InputArgList *Args = new InputArgList(ArgBegin, ArgEnd);
|
||||
|
||||
// FIXME: Handle '@' args (or at least error on them).
|
||||
|
||||
MissingArgIndex = MissingArgCount = 0;
|
||||
unsigned Index = 0, End = ArgEnd - ArgBegin;
|
||||
while (Index < End) {
|
||||
// Ignore empty arguments (other things may still take them as arguments).
|
||||
if (Args->getArgString(Index)[0] == '\0') {
|
||||
++Index;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned Prev = Index;
|
||||
Arg *A = ParseOneArg(*Args, Index);
|
||||
assert(Index > Prev && "Parser failed to consume argument.");
|
||||
|
||||
// Check for missing argument error.
|
||||
if (!A) {
|
||||
assert(Index >= End && "Unexpected parser error.");
|
||||
assert(Index - Prev - 1 && "No missing arguments!");
|
||||
MissingArgIndex = Prev;
|
||||
MissingArgCount = Index - Prev - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
Args->append(A);
|
||||
}
|
||||
|
||||
return Args;
|
||||
}
|
||||
|
@ -16,9 +16,9 @@
|
||||
#include <algorithm>
|
||||
using namespace clang::driver;
|
||||
|
||||
Option::Option(OptionClass _Kind, options::ID _ID, const char *_Name,
|
||||
Option::Option(OptionClass _Kind, OptSpecifier _ID, const char *_Name,
|
||||
const OptionGroup *_Group, const Option *_Alias)
|
||||
: Kind(_Kind), ID(_ID), Name(_Name), Group(_Group), Alias(_Alias),
|
||||
: Kind(_Kind), ID(_ID.getID()), Name(_Name), Group(_Group), Alias(_Alias),
|
||||
Unsupported(false), LinkerInput(false), NoOptAsInput(false),
|
||||
ForceSeparateRender(false), ForceJoinedRender(false),
|
||||
DriverOption(false), NoArgumentUnused(false) {
|
||||
@ -70,14 +70,13 @@ void Option::dump() const {
|
||||
llvm::errs() << ">\n";
|
||||
}
|
||||
|
||||
bool Option::matches(const Option *Opt) const {
|
||||
// Aliases are never considered in matching.
|
||||
if (Opt->getAlias())
|
||||
return matches(Opt->getAlias());
|
||||
bool Option::matches(OptSpecifier Opt) const {
|
||||
// Aliases are never considered in matching, look through them.
|
||||
if (Alias)
|
||||
return Alias->matches(Opt);
|
||||
|
||||
if (this == Opt)
|
||||
// Check exact match.
|
||||
if (ID == Opt)
|
||||
return true;
|
||||
|
||||
if (Group)
|
||||
@ -85,23 +84,7 @@ bool Option::matches(const Option *Opt) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Option::matches(options::ID Id) const {
|
||||
// FIXME: Decide what to do here; we should either pull out the
|
||||
// handling of alias on the option for Id from the other matches, or
|
||||
// find some other solution (which hopefully doesn't require using
|
||||
// the option table).
|
||||
if (Alias)
|
||||
return Alias->matches(Id);
|
||||
|
||||
if (ID == Id)
|
||||
return true;
|
||||
|
||||
if (Group)
|
||||
return Group->matches(Id);
|
||||
return false;
|
||||
}
|
||||
|
||||
OptionGroup::OptionGroup(options::ID ID, const char *Name,
|
||||
OptionGroup::OptionGroup(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group)
|
||||
: Option(Option::GroupClass, ID, Name, Group, 0) {
|
||||
}
|
||||
@ -111,8 +94,8 @@ Arg *OptionGroup::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
InputOption::InputOption()
|
||||
: Option(Option::InputClass, options::OPT_INPUT, "<input>", 0, 0) {
|
||||
InputOption::InputOption(OptSpecifier ID)
|
||||
: Option(Option::InputClass, ID, "<input>", 0, 0) {
|
||||
}
|
||||
|
||||
Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
@ -120,8 +103,8 @@ Arg *InputOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
UnknownOption::UnknownOption()
|
||||
: Option(Option::UnknownClass, options::OPT_UNKNOWN, "<unknown>", 0, 0) {
|
||||
UnknownOption::UnknownOption(OptSpecifier ID)
|
||||
: Option(Option::UnknownClass, ID, "<unknown>", 0, 0) {
|
||||
}
|
||||
|
||||
Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
@ -129,7 +112,7 @@ Arg *UnknownOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FlagOption::FlagOption(options::ID ID, const char *Name,
|
||||
FlagOption::FlagOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias)
|
||||
: Option(Option::FlagClass, ID, Name, Group, Alias) {
|
||||
}
|
||||
@ -143,7 +126,7 @@ Arg *FlagOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return new FlagArg(this, Index++);
|
||||
}
|
||||
|
||||
JoinedOption::JoinedOption(options::ID ID, const char *Name,
|
||||
JoinedOption::JoinedOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias)
|
||||
: Option(Option::JoinedClass, ID, Name, Group, Alias) {
|
||||
}
|
||||
@ -153,7 +136,7 @@ Arg *JoinedOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return new JoinedArg(this, Index++);
|
||||
}
|
||||
|
||||
CommaJoinedOption::CommaJoinedOption(options::ID ID, const char *Name,
|
||||
CommaJoinedOption::CommaJoinedOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group,
|
||||
const Option *Alias)
|
||||
: Option(Option::CommaJoinedClass, ID, Name, Group, Alias) {
|
||||
@ -170,7 +153,7 @@ Arg *CommaJoinedOption::accept(const InputArgList &Args,
|
||||
return new CommaJoinedArg(this, Index++, Suffix);
|
||||
}
|
||||
|
||||
SeparateOption::SeparateOption(options::ID ID, const char *Name,
|
||||
SeparateOption::SeparateOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias)
|
||||
: Option(Option::SeparateClass, ID, Name, Group, Alias) {
|
||||
}
|
||||
@ -188,7 +171,7 @@ Arg *SeparateOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return new SeparateArg(this, Index - 2, 1);
|
||||
}
|
||||
|
||||
MultiArgOption::MultiArgOption(options::ID ID, const char *Name,
|
||||
MultiArgOption::MultiArgOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group, const Option *Alias,
|
||||
unsigned _NumArgs)
|
||||
: Option(Option::MultiArgClass, ID, Name, Group, Alias), NumArgs(_NumArgs) {
|
||||
@ -208,7 +191,7 @@ Arg *MultiArgOption::accept(const InputArgList &Args, unsigned &Index) const {
|
||||
return new SeparateArg(this, Index - 1 - NumArgs, NumArgs);
|
||||
}
|
||||
|
||||
JoinedOrSeparateOption::JoinedOrSeparateOption(options::ID ID, const char *Name,
|
||||
JoinedOrSeparateOption::JoinedOrSeparateOption(OptSpecifier ID, const char *Name,
|
||||
const OptionGroup *Group,
|
||||
const Option *Alias)
|
||||
: Option(Option::JoinedOrSeparateClass, ID, Name, Group, Alias) {
|
||||
@ -229,7 +212,7 @@ Arg *JoinedOrSeparateOption::accept(const InputArgList &Args,
|
||||
return new SeparateArg(this, Index - 2, 1);
|
||||
}
|
||||
|
||||
JoinedAndSeparateOption::JoinedAndSeparateOption(options::ID ID,
|
||||
JoinedAndSeparateOption::JoinedAndSeparateOption(OptSpecifier ID,
|
||||
const char *Name,
|
||||
const OptionGroup *Group,
|
||||
const Option *Alias)
|
||||
|
@ -14,7 +14,9 @@
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/DriverDiagnostic.h"
|
||||
#include "clang/Driver/HostInfo.h"
|
||||
#include "clang/Driver/OptTable.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
@ -303,9 +305,9 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
|
||||
// and try to push it down into tool specific logic.
|
||||
|
||||
Arg *OSXVersion =
|
||||
Args.getLastArg(options::OPT_mmacosx_version_min_EQ, false);
|
||||
Args.getLastArgNoClaim(options::OPT_mmacosx_version_min_EQ);
|
||||
Arg *iPhoneVersion =
|
||||
Args.getLastArg(options::OPT_miphoneos_version_min_EQ, false);
|
||||
Args.getLastArgNoClaim(options::OPT_miphoneos_version_min_EQ);
|
||||
if (OSXVersion && iPhoneVersion) {
|
||||
getHost().getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
|
||||
<< OSXVersion->getAsString(Args)
|
||||
@ -365,8 +367,7 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
|
||||
// Sob. These is strictly gcc compatible for the time being. Apple
|
||||
// gcc translates options twice, which means that self-expanding
|
||||
// options add duplicates.
|
||||
options::ID id = A->getOption().getId();
|
||||
switch (id) {
|
||||
switch ((options::ID) A->getOption().getID()) {
|
||||
default:
|
||||
DAL->append(A);
|
||||
break;
|
||||
@ -440,7 +441,7 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
|
||||
|
||||
if (getTriple().getArch() == llvm::Triple::x86 ||
|
||||
getTriple().getArch() == llvm::Triple::x86_64)
|
||||
if (!Args.hasArg(options::OPT_mtune_EQ, false))
|
||||
if (!Args.hasArgNoClaim(options::OPT_mtune_EQ))
|
||||
DAL->append(DAL->MakeJoinedArg(0, Opts.getOption(options::OPT_mtune_EQ),
|
||||
"core2"));
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "clang/Driver/Job.h"
|
||||
#include "clang/Driver/HostInfo.h"
|
||||
#include "clang/Driver/Option.h"
|
||||
#include "clang/Driver/Options.h"
|
||||
#include "clang/Driver/ToolChain.h"
|
||||
#include "clang/Driver/Util.h"
|
||||
|
||||
@ -81,8 +82,8 @@ void Clang::AddPreprocessingOptions(const Driver &D,
|
||||
DepFile = Output.getFilename();
|
||||
} else if (Arg *MF = Args.getLastArg(options::OPT_MF)) {
|
||||
DepFile = MF->getValue(Args);
|
||||
} else if (A->getOption().getId() == options::OPT_M ||
|
||||
A->getOption().getId() == options::OPT_MM) {
|
||||
} else if (A->getOption().matches(options::OPT_M) ||
|
||||
A->getOption().matches(options::OPT_MM)) {
|
||||
DepFile = "-";
|
||||
} else {
|
||||
DepFile = darwin::CC1::getDependencyFileName(Args, Inputs);
|
||||
@ -116,8 +117,8 @@ void Clang::AddPreprocessingOptions(const Driver &D,
|
||||
CmdArgs.push_back(DepTarget);
|
||||
}
|
||||
|
||||
if (A->getOption().getId() == options::OPT_M ||
|
||||
A->getOption().getId() == options::OPT_MD)
|
||||
if (A->getOption().matches(options::OPT_M) ||
|
||||
A->getOption().matches(options::OPT_MD))
|
||||
CmdArgs.push_back("-sys-header-deps");
|
||||
}
|
||||
|
||||
@ -778,12 +779,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
break;
|
||||
}
|
||||
|
||||
if (Args.hasFlag(options::OPT_fmath_errno,
|
||||
// -fmath-errno is default.
|
||||
if (!Args.hasFlag(options::OPT_fmath_errno,
|
||||
options::OPT_fno_math_errno,
|
||||
getToolChain().IsMathErrnoDefault()))
|
||||
CmdArgs.push_back("--fmath-errno=1");
|
||||
else
|
||||
CmdArgs.push_back("--fmath-errno=0");
|
||||
CmdArgs.push_back("-fno-math-errno");
|
||||
|
||||
if (Arg *A = Args.getLastArg(options::OPT_flimited_precision_EQ)) {
|
||||
CmdArgs.push_back("--limit-float-precision");
|
||||
@ -822,7 +822,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
// Manually translate -O to -O2 and -O4 to -O3; let clang reject
|
||||
// others.
|
||||
if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
|
||||
if (A->getOption().getId() == options::OPT_O4)
|
||||
if (A->getOption().matches(options::OPT_O4))
|
||||
CmdArgs.push_back("-O3");
|
||||
else if (A->getValue(Args)[0] == '\0')
|
||||
CmdArgs.push_back("-O2");
|
||||
@ -864,7 +864,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
CmdArgs.push_back(A->getValue(Args));
|
||||
}
|
||||
|
||||
if (Args.hasArg(options::OPT__relocatable_pch, true))
|
||||
if (Args.hasArg(options::OPT__relocatable_pch))
|
||||
CmdArgs.push_back("--relocatable-pch");
|
||||
|
||||
if (Arg *A = Args.getLastArg(options::OPT_fconstant_string_class_EQ)) {
|
||||
@ -922,7 +922,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
|
||||
// -fbuiltin is default.
|
||||
if (!Args.hasFlag(options::OPT_fbuiltin, options::OPT_fno_builtin))
|
||||
CmdArgs.push_back("-fbuiltin=0");
|
||||
CmdArgs.push_back("-fno-builtin");
|
||||
|
||||
// -fblocks=0 is default.
|
||||
if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
|
||||
@ -938,7 +938,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
|
||||
// -frtti is default.
|
||||
if (!Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti))
|
||||
CmdArgs.push_back("-frtti=0");
|
||||
CmdArgs.push_back("-fno-rtti");
|
||||
|
||||
// -fsigned-char is default.
|
||||
if (!Args.hasFlag(options::OPT_fsigned_char,
|
||||
@ -2609,6 +2609,8 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
// FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
|
||||
// the default system libraries. Just mimic this for now.
|
||||
CmdArgs.push_back("-lgcc");
|
||||
if (D.CCCIsCXX)
|
||||
CmdArgs.push_back("-lstdc++");
|
||||
if (Args.hasArg(options::OPT_static)) {
|
||||
CmdArgs.push_back("-lgcc_eh");
|
||||
} else {
|
||||
@ -2638,10 +2640,6 @@ void freebsd::Link::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
else
|
||||
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtendS.o")));
|
||||
CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(C, "crtn.o")));
|
||||
// FIXME: g++ is more complicated here, it tries to put -lstdc++
|
||||
// before -lm, for example.
|
||||
if (D.CCCIsCXX)
|
||||
CmdArgs.push_back("-lstdc++");
|
||||
}
|
||||
|
||||
const char *Exec =
|
||||
|
@ -16,14 +16,14 @@
|
||||
using namespace clang::driver;
|
||||
using namespace clang::driver::types;
|
||||
|
||||
struct Info {
|
||||
struct TypeInfo {
|
||||
const char *Name;
|
||||
const char *Flags;
|
||||
const char *TempSuffix;
|
||||
ID PreprocessedType;
|
||||
};
|
||||
|
||||
static Info TypeInfos[] = {
|
||||
static TypeInfo TypeInfos[] = {
|
||||
#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, FLAGS) \
|
||||
{ NAME, FLAGS, TEMP_SUFFIX, TY_##PP_TYPE, },
|
||||
#include "clang/Driver/Types.def"
|
||||
@ -31,7 +31,7 @@ static Info TypeInfos[] = {
|
||||
};
|
||||
static const unsigned numTypes = sizeof(TypeInfos) / sizeof(TypeInfos[0]);
|
||||
|
||||
static Info &getInfo(unsigned id) {
|
||||
static TypeInfo &getInfo(unsigned id) {
|
||||
assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");
|
||||
return TypeInfos[id - 1];
|
||||
}
|
||||
|
@ -14,7 +14,6 @@ using namespace clang;
|
||||
|
||||
void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
|
||||
const llvm::SmallVectorImpl<llvm::StringRef> &Args) {
|
||||
llvm::llvm_report_error("FIXME: Not yet implemented!");
|
||||
}
|
||||
|
||||
static const char *getAnalysisName(Analyses Kind) {
|
||||
@ -83,8 +82,8 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
|
||||
Res.push_back("-analyzer-display-progress");
|
||||
if (Opts.EagerlyAssume)
|
||||
Res.push_back("-analyzer-eagerly-assume");
|
||||
if (Opts.PurgeDead)
|
||||
Res.push_back("-analyzer-purge-dead");
|
||||
if (!Opts.PurgeDead)
|
||||
Res.push_back("-analyzer-no-purge-dead");
|
||||
if (Opts.TrimGraph)
|
||||
Res.push_back("-trim-egraph");
|
||||
if (Opts.VisualizeEGDot)
|
||||
@ -238,7 +237,7 @@ static const char *getActionName(frontend::ActionKind Kind) {
|
||||
static void FrontendOptsToArgs(const FrontendOptions &Opts,
|
||||
std::vector<std::string> &Res) {
|
||||
if (!Opts.DebugCodeCompletionPrinter)
|
||||
Res.push_back("-code-completion-debug-printer=0");
|
||||
Res.push_back("-no-code-completion-debug-printer");
|
||||
if (Opts.DisableFree)
|
||||
Res.push_back("-disable-free");
|
||||
if (Opts.EmptyInputOnly)
|
||||
@ -298,7 +297,7 @@ static void FrontendOptsToArgs(const FrontendOptions &Opts,
|
||||
|
||||
static void HeaderSearchOptsToArgs(const HeaderSearchOptions &Opts,
|
||||
std::vector<std::string> &Res) {
|
||||
if (Opts.Sysroot.empty()) {
|
||||
if (Opts.Sysroot != "/") {
|
||||
Res.push_back("-isysroot");
|
||||
Res.push_back(Opts.Sysroot);
|
||||
}
|
||||
@ -394,8 +393,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
|
||||
Res.push_back("-faltivec");
|
||||
Res.push_back("-fexceptions");
|
||||
Res.push_back(Opts.Exceptions ? "1" : "0");
|
||||
Res.push_back("-frtti");
|
||||
Res.push_back(Opts.Rtti ? "1" : "0");
|
||||
if (!Opts.Rtti)
|
||||
Res.push_back("-fno-rtti");
|
||||
if (!Opts.NeXTRuntime)
|
||||
Res.push_back("-fgnu-runtime");
|
||||
if (Opts.Freestanding)
|
||||
@ -411,7 +410,7 @@ static void LangOptsToArgs(const LangOptions &Opts,
|
||||
if (Opts.EmitAllDecls)
|
||||
Res.push_back("-femit-all-decls");
|
||||
if (!Opts.MathErrno)
|
||||
Res.push_back("-fmath-errno=0");
|
||||
Res.push_back("-fno-math-errno");
|
||||
if (Opts.OverflowChecking)
|
||||
Res.push_back("-ftrapv");
|
||||
if (Opts.HeinousExtensions)
|
||||
|
@ -237,6 +237,13 @@ static void DefineType(const char *MacroName, TargetInfo::IntType Ty,
|
||||
DefineBuiltinMacro(Buf, MacroBuf);
|
||||
}
|
||||
|
||||
static void DefineTypeWidth(const char *MacroName, TargetInfo::IntType Ty,
|
||||
const TargetInfo &TI, std::vector<char> &Buf) {
|
||||
char MacroBuf[60];
|
||||
sprintf(MacroBuf, "%s=%d", MacroName, TI.getTypeWidth(Ty));
|
||||
DefineBuiltinMacro(Buf, MacroBuf);
|
||||
}
|
||||
|
||||
static void DefineExactWidthIntType(TargetInfo::IntType Ty,
|
||||
const TargetInfo &TI, std::vector<char> &Buf) {
|
||||
char MacroBuf[60];
|
||||
@ -381,10 +388,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
||||
DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Buf);
|
||||
DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Buf);
|
||||
|
||||
DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Buf);
|
||||
DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Buf);
|
||||
DefineTypeWidth("__INTMAX_WIDTH__", TI.getIntMaxType(), TI, Buf);
|
||||
DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Buf);
|
||||
DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Buf);
|
||||
DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Buf);
|
||||
DefineType("__SIZE_TYPE__", TI.getSizeType(), Buf);
|
||||
DefineType("__WCHAR_TYPE__", TI.getWCharType(), Buf);
|
||||
DefineType("__WINT_TYPE__", TI.getWIntType(), Buf);
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/System/Path.h"
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <cstdio>
|
||||
@ -1086,11 +1087,9 @@ void PCHReader::MaybeAddSystemRootToFilename(std::string &Filename) {
|
||||
if (!RelocatablePCH)
|
||||
return;
|
||||
|
||||
if (Filename.empty() || Filename[0] == '/' || Filename[0] == '<')
|
||||
if (Filename.empty() || llvm::sys::Path(Filename).isAbsolute())
|
||||
return;
|
||||
|
||||
std::string FIXME = Filename;
|
||||
|
||||
if (isysroot == 0) {
|
||||
// If no system root was given, default to '/'
|
||||
Filename.insert(Filename.begin(), '/');
|
||||
|
@ -213,16 +213,19 @@ typedef __uint_least8_t uint_fast8_t;
|
||||
|
||||
/* C99 7.18.1.4 Integer types capable of holding object pointers.
|
||||
*/
|
||||
#define __stdint_join3(a,b,c) a ## b ## c
|
||||
#define __stdint_exjoin3(a,b,c) __stdint_join3(a,b,c)
|
||||
|
||||
#ifndef __intptr_t_defined
|
||||
typedef __INTPTR_TYPE__ intptr_t;
|
||||
typedef __stdint_exjoin3( int, __INTPTR_WIDTH__, _t) intptr_t;
|
||||
#define __intptr_t_defined
|
||||
#endif
|
||||
typedef unsigned __INTPTR_TYPE__ uintptr_t;
|
||||
typedef __stdint_exjoin3(uint, __INTPTR_WIDTH__, _t) uintptr_t;
|
||||
|
||||
/* C99 7.18.1.5 Greatest-width integer types.
|
||||
*/
|
||||
typedef __INTMAX_TYPE__ intmax_t;
|
||||
typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
typedef __stdint_exjoin3( int, __INTMAX_WIDTH__, _t) intmax_t;
|
||||
typedef __stdint_exjoin3(uint, __INTMAX_WIDTH__, _t) uintmax_t;
|
||||
|
||||
/* C99 7.18.4 Macros for minimum-width integer constants.
|
||||
*
|
||||
@ -600,29 +603,24 @@ typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
/* C99 7.18.2.4 Limits of integer types capable of holding object pointers. */
|
||||
/* C99 7.18.3 Limits of other integer types. */
|
||||
|
||||
#define INTPTR_MIN __stdint_exjoin3( INT, __INTPTR_WIDTH__, _MIN)
|
||||
#define INTPTR_MAX __stdint_exjoin3( INT, __INTPTR_WIDTH__, _MAX)
|
||||
#define UINTPTR_MAX __stdint_exjoin3(UINT, __INTPTR_WIDTH__, _MAX)
|
||||
|
||||
#if __POINTER_WIDTH__ == 64
|
||||
|
||||
#define INTPTR_MIN INT64_MIN
|
||||
#define INTPTR_MAX INT64_MAX
|
||||
#define UINTPTR_MAX UINT64_MAX
|
||||
#define PTRDIFF_MIN INT64_MIN
|
||||
#define PTRDIFF_MAX INT64_MAX
|
||||
#define SIZE_MAX UINT64_MAX
|
||||
|
||||
#elif __POINTER_WIDTH__ == 32
|
||||
|
||||
#define INTPTR_MIN INT32_MIN
|
||||
#define INTPTR_MAX INT32_MAX
|
||||
#define UINTPTR_MAX UINT32_MAX
|
||||
#define PTRDIFF_MIN INT32_MIN
|
||||
#define PTRDIFF_MAX INT32_MAX
|
||||
#define SIZE_MAX UINT32_MAX
|
||||
|
||||
#elif __POINTER_WIDTH__ == 16
|
||||
|
||||
#define INTPTR_MIN INT16_MIN
|
||||
#define INTPTR_MAX INT16_MAX
|
||||
#define UINTPTR_MAX UINT16_MAX
|
||||
#define PTRDIFF_MIN INT16_MIN
|
||||
#define PTRDIFF_MAX INT16_MAX
|
||||
#define SIZE_MAX UINT16_MAX
|
||||
@ -632,9 +630,9 @@ typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
#endif
|
||||
|
||||
/* C99 7.18.2.5 Limits of greatest-width integer types. */
|
||||
#define INTMAX_MIN (-__INTMAX_MAX__-1)
|
||||
#define INTMAX_MAX __INTMAX_MAX__
|
||||
#define UINTMAX_MAX (__INTMAX_MAX__*2ULL+1ULL)
|
||||
#define INTMAX_MIN __stdint_exjoin3( INT, __INTMAX_WIDTH__, _MIN)
|
||||
#define INTMAX_MAX __stdint_exjoin3( INT, __INTMAX_WIDTH__, _MAX)
|
||||
#define UINTMAX_MAX __stdint_exjoin3(UINT, __INTMAX_WIDTH__, _MAX)
|
||||
|
||||
/* C99 7.18.3 Limits of other integer types. */
|
||||
#define SIG_ATOMIC_MIN INT32_MIN
|
||||
@ -653,8 +651,8 @@ typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
#endif
|
||||
|
||||
/* 7.18.4.2 Macros for greatest-width integer constants. */
|
||||
#define INTMAX_C(v) v##LL
|
||||
#define UINTMAX_C(v) v##ULL
|
||||
#define INTMAX_C(v) __stdint_exjoin3( INT, __INTMAX_WIDTH__, _C(v))
|
||||
#define UINTMAX_C(v) __stdint_exjoin3(UINT, __INTMAX_WIDTH__, _C(v))
|
||||
|
||||
#endif /* __STDC_HOSTED__ */
|
||||
#endif /* __CLANG_STDINT_H */
|
||||
|
@ -341,17 +341,6 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec) {
|
||||
ColonLoc = ConsumeToken();
|
||||
}
|
||||
|
||||
if ((OpToken.is(tok::periodstar) || OpToken.is(tok::arrowstar))
|
||||
&& Tok.is(tok::identifier)) {
|
||||
CXXScopeSpec SS;
|
||||
if (Actions.getTypeName(*Tok.getIdentifierInfo(),
|
||||
Tok.getLocation(), CurScope, &SS)) {
|
||||
const char *Opc = OpToken.is(tok::periodstar) ? "'.*'" : "'->*'";
|
||||
Diag(OpToken, diag::err_pointer_to_member_type) << Opc;
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
}
|
||||
// Parse another leaf here for the RHS of the operator.
|
||||
// ParseCastExpression works here because all RHS expressions in C have it
|
||||
// as a prefix, at least. However, in C++, an assignment-expression could
|
||||
|
@ -123,6 +123,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
||||
"ParseObjCAtInterfaceDeclaration(): Expected @interface");
|
||||
ConsumeToken(); // the "interface" identifier
|
||||
|
||||
// Code completion after '@interface'.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCInterfaceDecl(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing class or category name.
|
||||
return DeclPtrTy();
|
||||
@ -137,6 +143,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
||||
SourceLocation categoryLoc, rparenLoc;
|
||||
IdentifierInfo *categoryId = 0;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
// For ObjC2, the category name is optional (not an error).
|
||||
if (Tok.is(tok::identifier)) {
|
||||
categoryId = Tok.getIdentifierInfo();
|
||||
@ -181,6 +192,13 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
||||
|
||||
if (Tok.is(tok::colon)) { // a super class is specified.
|
||||
ConsumeToken();
|
||||
|
||||
// Code completion of superclass names.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCSuperclass(CurScope, nameId);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing super class name.
|
||||
return DeclPtrTy();
|
||||
@ -308,7 +326,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
||||
ObjCDeclSpec OCDS;
|
||||
// Parse property attribute list, if any.
|
||||
if (Tok.is(tok::l_paren))
|
||||
ParseObjCPropertyAttribute(OCDS);
|
||||
ParseObjCPropertyAttribute(OCDS, interfaceDecl,
|
||||
allMethods.data(), allMethods.size());
|
||||
|
||||
struct ObjCPropertyCallback : FieldCallback {
|
||||
Parser &P;
|
||||
@ -407,13 +426,15 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
||||
/// copy
|
||||
/// nonatomic
|
||||
///
|
||||
void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||
void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods) {
|
||||
assert(Tok.getKind() == tok::l_paren);
|
||||
SourceLocation LHSLoc = ConsumeParen(); // consume '('
|
||||
|
||||
while (1) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCProperty(CurScope, DS);
|
||||
Actions.CodeCompleteObjCPropertyFlags(CurScope, DS);
|
||||
ConsumeToken();
|
||||
}
|
||||
const IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
@ -444,6 +465,16 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) {
|
||||
tok::r_paren))
|
||||
return;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
if (II->getNameStart()[0] == 's')
|
||||
Actions.CodeCompleteObjCPropertySetter(CurScope, ClassDecl,
|
||||
Methods, NumMethods);
|
||||
else
|
||||
Actions.CodeCompleteObjCPropertyGetter(CurScope, ClassDecl,
|
||||
Methods, NumMethods);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident);
|
||||
SkipUntil(tok::r_paren);
|
||||
@ -1078,6 +1109,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
|
||||
"ParseObjCAtImplementationDeclaration(): Expected @implementation");
|
||||
ConsumeToken(); // the "implementation" identifier
|
||||
|
||||
// Code completion after '@implementation'.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCImplementationDecl(CurScope);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing class or category name.
|
||||
return DeclPtrTy();
|
||||
@ -1092,6 +1129,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration(
|
||||
SourceLocation categoryLoc, rparenLoc;
|
||||
IdentifierInfo *categoryId = 0;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.is(tok::identifier)) {
|
||||
categoryId = Tok.getIdentifierInfo();
|
||||
categoryLoc = ConsumeToken();
|
||||
@ -1202,18 +1244,32 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
||||
assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
|
||||
"ParseObjCPropertyDynamic(): Expected '@synthesize'");
|
||||
SourceLocation loc = ConsumeToken(); // consume synthesize
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
while (Tok.is(tok::identifier)) {
|
||||
while (true) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_synthesized_property_name);
|
||||
SkipUntil(tok::semi);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
IdentifierInfo *propertyIvar = 0;
|
||||
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
|
||||
SourceLocation propertyLoc = ConsumeToken(); // consume property name
|
||||
if (Tok.is(tok::equal)) {
|
||||
// property '=' ivar-name
|
||||
ConsumeToken(); // consume '='
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId,
|
||||
ObjCImpDecl);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident);
|
||||
break;
|
||||
@ -1227,8 +1283,10 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
||||
break;
|
||||
ConsumeToken(); // consume ','
|
||||
}
|
||||
if (Tok.isNot(tok::semi))
|
||||
if (Tok.isNot(tok::semi)) {
|
||||
Diag(Tok, diag::err_expected_semi_after) << "@synthesize";
|
||||
SkipUntil(tok::semi);
|
||||
}
|
||||
else
|
||||
ConsumeToken(); // consume ';'
|
||||
return DeclPtrTy();
|
||||
@ -1245,11 +1303,18 @@ Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
|
||||
assert(Tok.isObjCAtKeyword(tok::objc_dynamic) &&
|
||||
"ParseObjCPropertyDynamic(): Expected '@dynamic'");
|
||||
SourceLocation loc = ConsumeToken(); // consume dynamic
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
while (Tok.is(tok::identifier)) {
|
||||
while (true) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident);
|
||||
SkipUntil(tok::semi);
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
|
||||
SourceLocation propertyLoc = ConsumeToken(); // consume property name
|
||||
Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
|
||||
@ -1580,11 +1645,14 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||
ExprArg ReceiverExpr) {
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
if (ReceiverName)
|
||||
Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc);
|
||||
Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc,
|
||||
0, 0);
|
||||
else
|
||||
Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get());
|
||||
Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
|
||||
0, 0);
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
// Parse objc-selector
|
||||
SourceLocation Loc;
|
||||
IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc);
|
||||
@ -1622,6 +1690,19 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc,
|
||||
// We have a valid expression.
|
||||
KeyExprs.push_back(Res.release());
|
||||
|
||||
// Code completion after each argument.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
if (ReceiverName)
|
||||
Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc,
|
||||
KeyIdents.data(),
|
||||
KeyIdents.size());
|
||||
else
|
||||
Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(),
|
||||
KeyIdents.data(),
|
||||
KeyIdents.size());
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
// Check for another keyword selector.
|
||||
selIdent = ParseObjCSelectorPiece(Loc);
|
||||
if (!selIdent && Tok.isNot(tok::colon))
|
||||
|
@ -117,6 +117,33 @@ CodeCompletionString::Chunk::CreateCurrentParameter(
|
||||
return Chunk(CK_CurrentParameter, CurrentParameter);
|
||||
}
|
||||
|
||||
CodeCompletionString::Chunk CodeCompletionString::Chunk::Clone() const {
|
||||
switch (Kind) {
|
||||
case CK_TypedText:
|
||||
case CK_Text:
|
||||
case CK_Placeholder:
|
||||
case CK_Informative:
|
||||
case CK_CurrentParameter:
|
||||
case CK_LeftParen:
|
||||
case CK_RightParen:
|
||||
case CK_LeftBracket:
|
||||
case CK_RightBracket:
|
||||
case CK_LeftBrace:
|
||||
case CK_RightBrace:
|
||||
case CK_LeftAngle:
|
||||
case CK_RightAngle:
|
||||
case CK_Comma:
|
||||
return Chunk(Kind, Text);
|
||||
|
||||
case CK_Optional: {
|
||||
std::auto_ptr<CodeCompletionString> Opt(Optional->Clone());
|
||||
return CreateOptional(Opt);
|
||||
}
|
||||
}
|
||||
|
||||
// Silence GCC warning.
|
||||
return Chunk();
|
||||
}
|
||||
|
||||
void
|
||||
CodeCompletionString::Chunk::Destroy() {
|
||||
@ -168,6 +195,20 @@ std::string CodeCompletionString::getAsString() const {
|
||||
return Result;
|
||||
}
|
||||
|
||||
const char *CodeCompletionString::getTypedText() const {
|
||||
for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
|
||||
if (C->Kind == CK_TypedText)
|
||||
return C->Text;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CodeCompletionString *CodeCompletionString::Clone() const {
|
||||
CodeCompletionString *Result = new CodeCompletionString;
|
||||
for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
|
||||
Result->AddChunk(C->Clone());
|
||||
return Result;
|
||||
}
|
||||
|
||||
namespace {
|
||||
// Escape a string for XML-like formatting.
|
||||
@ -473,6 +514,13 @@ CodeCompletionString *CodeCompletionString::Deserialize(llvm::StringRef &Str) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
void CodeCompleteConsumer::Result::Destroy() {
|
||||
if (Kind == RK_Pattern) {
|
||||
delete Pattern;
|
||||
Pattern = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Code completion overload candidate implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -545,6 +593,12 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
|
||||
OS << '\n';
|
||||
break;
|
||||
}
|
||||
|
||||
case Result::RK_Pattern: {
|
||||
OS << "Pattern : " << Results[I].Rank << " : "
|
||||
<< Results[I].Pattern->getAsString() << '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -627,6 +681,13 @@ CIndexCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
|
||||
OS << '\n';
|
||||
break;
|
||||
}
|
||||
|
||||
case Result::RK_Pattern: {
|
||||
OS << "Pattern:";
|
||||
Results[I].Pattern->Serialize(OS);
|
||||
OS << '\n';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,6 +201,13 @@ class LookupResult {
|
||||
return getResultKind() == Ambiguous;
|
||||
}
|
||||
|
||||
/// Determines if this names a single result which is not an
|
||||
/// unresolved value using decl. If so, it is safe to call
|
||||
/// getFoundDecl().
|
||||
bool isSingleResult() const {
|
||||
return getResultKind() == Found;
|
||||
}
|
||||
|
||||
LookupResultKind getResultKind() const {
|
||||
sanity();
|
||||
return ResultKind;
|
||||
@ -248,12 +255,24 @@ class LookupResult {
|
||||
Decls.set_size(N);
|
||||
}
|
||||
|
||||
/// \brief Resolves the kind of the lookup, possibly hiding decls.
|
||||
/// \brief Resolves the result kind of the lookup, possibly hiding
|
||||
/// decls.
|
||||
///
|
||||
/// This should be called in any environment where lookup might
|
||||
/// generate multiple lookup results.
|
||||
void resolveKind();
|
||||
|
||||
/// \brief Re-resolves the result kind of the lookup after a set of
|
||||
/// removals has been performed.
|
||||
void resolveKindAfterFilter() {
|
||||
if (Decls.empty())
|
||||
ResultKind = NotFound;
|
||||
else {
|
||||
ResultKind = Found;
|
||||
resolveKind();
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Fetch this as an unambiguous single declaration
|
||||
/// (possibly an overloaded one).
|
||||
///
|
||||
@ -272,6 +291,12 @@ class LookupResult {
|
||||
return Decls[0]->getUnderlyingDecl();
|
||||
}
|
||||
|
||||
/// Fetches a representative decl. Useful for lazy diagnostics.
|
||||
NamedDecl *getRepresentativeDecl() const {
|
||||
assert(!Decls.empty() && "cannot get representative of empty set");
|
||||
return Decls[0];
|
||||
}
|
||||
|
||||
/// \brief Asks if the result is a single tag decl.
|
||||
bool isSingleTagDecl() const {
|
||||
return getResultKind() == Found && isa<TagDecl>(getFoundDecl());
|
||||
@ -337,6 +362,65 @@ class LookupResult {
|
||||
return NameLoc;
|
||||
}
|
||||
|
||||
/// A class for iterating through a result set and possibly
|
||||
/// filtering out results. The results returned are possibly
|
||||
/// sugared.
|
||||
class Filter {
|
||||
LookupResult &Results;
|
||||
unsigned I;
|
||||
bool ErasedAny;
|
||||
#ifndef NDEBUG
|
||||
bool CalledDone;
|
||||
#endif
|
||||
|
||||
friend class LookupResult;
|
||||
Filter(LookupResult &Results)
|
||||
: Results(Results), I(0), ErasedAny(false)
|
||||
#ifndef NDEBUG
|
||||
, CalledDone(false)
|
||||
#endif
|
||||
{}
|
||||
|
||||
public:
|
||||
#ifndef NDEBUG
|
||||
~Filter() {
|
||||
assert(CalledDone &&
|
||||
"LookupResult::Filter destroyed without done() call");
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hasNext() const {
|
||||
return I != Results.Decls.size();
|
||||
}
|
||||
|
||||
NamedDecl *next() {
|
||||
assert(I < Results.Decls.size() && "next() called on empty filter");
|
||||
return Results.Decls[I++];
|
||||
}
|
||||
|
||||
/// Erase the last element returned from this iterator.
|
||||
void erase() {
|
||||
Results.Decls[--I] = Results.Decls.back();
|
||||
Results.Decls.pop_back();
|
||||
ErasedAny = true;
|
||||
}
|
||||
|
||||
void done() {
|
||||
#ifndef NDEBUG
|
||||
assert(!CalledDone && "done() called twice");
|
||||
CalledDone = true;
|
||||
#endif
|
||||
|
||||
if (ErasedAny)
|
||||
Results.resolveKindAfterFilter();
|
||||
}
|
||||
};
|
||||
|
||||
/// Create a filter for this result set.
|
||||
Filter makeFilter() {
|
||||
return Filter(*this);
|
||||
}
|
||||
|
||||
private:
|
||||
void diagnose() {
|
||||
if (isAmbiguous())
|
||||
|
@ -319,7 +319,7 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
|
||||
&Context.Idents.get("Protocol"),
|
||||
SourceLocation(), true);
|
||||
Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
|
||||
PushOnScopeChains(ProtocolDecl, TUScope);
|
||||
PushOnScopeChains(ProtocolDecl, TUScope, false);
|
||||
}
|
||||
// Create the built-in typedef for 'id'.
|
||||
if (Context.getObjCIdType().isNull()) {
|
||||
|
@ -548,26 +548,32 @@ class Sema : public Action {
|
||||
DeclPtrTy HandleDeclarator(Scope *S, Declarator &D,
|
||||
MultiTemplateParamsArg TemplateParameterLists,
|
||||
bool IsFunctionDefinition);
|
||||
void RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
|
||||
void RegisterLocallyScopedExternCDecl(NamedDecl *ND,
|
||||
const LookupResult &Previous,
|
||||
Scope *S);
|
||||
void DiagnoseFunctionSpecifiers(Declarator& D);
|
||||
bool CheckRedeclaration(DeclContext *DC,
|
||||
DeclarationName Name,
|
||||
SourceLocation NameLoc,
|
||||
unsigned Diagnostic);
|
||||
NamedDecl* ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, DeclaratorInfo *DInfo,
|
||||
NamedDecl* PrevDecl, bool &Redeclaration);
|
||||
LookupResult &Previous, bool &Redeclaration);
|
||||
NamedDecl* ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, DeclaratorInfo *DInfo,
|
||||
NamedDecl* PrevDecl,
|
||||
LookupResult &Previous,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool &Redeclaration);
|
||||
void CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
||||
void CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous,
|
||||
bool &Redeclaration);
|
||||
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, DeclaratorInfo *DInfo,
|
||||
NamedDecl* PrevDecl,
|
||||
LookupResult &Previous,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool IsFunctionDefinition,
|
||||
bool &Redeclaration);
|
||||
void CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
|
||||
void AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD);
|
||||
void CheckFunctionDeclaration(FunctionDecl *NewFD, LookupResult &Previous,
|
||||
bool IsExplicitSpecialization,
|
||||
bool &Redeclaration,
|
||||
bool &OverloadableAttrRequired);
|
||||
@ -779,15 +785,17 @@ class Sema : public Action {
|
||||
/// Subroutines of ActOnDeclarator().
|
||||
TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D, QualType T,
|
||||
DeclaratorInfo *DInfo);
|
||||
void MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
|
||||
void MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls);
|
||||
bool MergeFunctionDecl(FunctionDecl *New, Decl *Old);
|
||||
bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old);
|
||||
void MergeVarDecl(VarDecl *New, Decl *Old);
|
||||
void MergeVarDecl(VarDecl *New, LookupResult &OldDecls);
|
||||
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old);
|
||||
|
||||
/// C++ Overloading.
|
||||
bool IsOverload(FunctionDecl *New, Decl* OldD,
|
||||
OverloadedFunctionDecl::function_iterator &MatchedDecl);
|
||||
bool IsOverload(FunctionDecl *New, LookupResult &OldDecls,
|
||||
NamedDecl *&OldDecl);
|
||||
bool IsOverload(FunctionDecl *New, FunctionDecl *Old);
|
||||
|
||||
ImplicitConversionSequence
|
||||
TryImplicitConversion(Expr* From, QualType ToType,
|
||||
bool SuppressUserConversions,
|
||||
@ -822,7 +830,7 @@ class Sema : public Action {
|
||||
bool AllowConversionFunctions,
|
||||
bool AllowExplicit, bool ForceRValue,
|
||||
bool UserCast = false);
|
||||
bool DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType);
|
||||
bool DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType);
|
||||
|
||||
|
||||
ImplicitConversionSequence::CompareKind
|
||||
@ -2324,8 +2332,8 @@ class Sema : public Action {
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs,
|
||||
unsigned NumExplicitTemplateArgs,
|
||||
SourceLocation RAngleLoc,
|
||||
NamedDecl *&PrevDecl);
|
||||
bool CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl);
|
||||
LookupResult &Previous);
|
||||
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
|
||||
|
||||
virtual DeclResult
|
||||
ActOnExplicitInstantiation(Scope *S,
|
||||
@ -3638,14 +3646,38 @@ class Sema : public Action {
|
||||
virtual void CodeCompleteNamespaceAliasDecl(Scope *S);
|
||||
virtual void CodeCompleteOperatorName(Scope *S);
|
||||
|
||||
virtual void CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS);
|
||||
virtual void CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS);
|
||||
virtual void CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods);
|
||||
virtual void CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods);
|
||||
|
||||
virtual void CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
|
||||
SourceLocation FNameLoc);
|
||||
virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver);
|
||||
SourceLocation FNameLoc,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents);
|
||||
virtual void CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents);
|
||||
virtual void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
|
||||
unsigned NumProtocols);
|
||||
virtual void CodeCompleteObjCProtocolDecl(Scope *S);
|
||||
//@}
|
||||
virtual void CodeCompleteObjCInterfaceDecl(Scope *S);
|
||||
virtual void CodeCompleteObjCSuperclass(Scope *S,
|
||||
IdentifierInfo *ClassName);
|
||||
virtual void CodeCompleteObjCImplementationDecl(Scope *S);
|
||||
virtual void CodeCompleteObjCInterfaceCategory(Scope *S,
|
||||
IdentifierInfo *ClassName);
|
||||
virtual void CodeCompleteObjCImplementationCategory(Scope *S,
|
||||
IdentifierInfo *ClassName);
|
||||
virtual void CodeCompleteObjCPropertyDefinition(Scope *S,
|
||||
DeclPtrTy ObjCImpDecl);
|
||||
virtual void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
|
||||
IdentifierInfo *PropertyName,
|
||||
DeclPtrTy ObjCImpDecl);
|
||||
//@}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Extra semantic analysis beyond the C type system
|
||||
|
@ -175,6 +175,30 @@ Sema::ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind,
|
||||
return ExprError();
|
||||
}
|
||||
|
||||
/// UnwrapDissimilarPointerTypes - Like Sema::UnwrapSimilarPointerTypes,
|
||||
/// this removes one level of indirection from both types, provided that they're
|
||||
/// the same kind of pointer (plain or to-member). Unlike the Sema function,
|
||||
/// this one doesn't care if the two pointers-to-member don't point into the
|
||||
/// same class. This is because CastsAwayConstness doesn't care.
|
||||
bool UnwrapDissimilarPointerTypes(QualType& T1, QualType& T2) {
|
||||
const PointerType *T1PtrType = T1->getAs<PointerType>(),
|
||||
*T2PtrType = T2->getAs<PointerType>();
|
||||
if (T1PtrType && T2PtrType) {
|
||||
T1 = T1PtrType->getPointeeType();
|
||||
T2 = T2PtrType->getPointeeType();
|
||||
return true;
|
||||
}
|
||||
|
||||
const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
|
||||
*T2MPType = T2->getAs<MemberPointerType>();
|
||||
if (T1MPType && T2MPType) {
|
||||
T1 = T1MPType->getPointeeType();
|
||||
T2 = T2MPType->getPointeeType();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// CastsAwayConstness - Check if the pointer conversion from SrcType to
|
||||
/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by
|
||||
/// the cast checkers. Both arguments must denote pointer (possibly to member)
|
||||
@ -195,7 +219,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) {
|
||||
llvm::SmallVector<Qualifiers, 8> cv1, cv2;
|
||||
|
||||
// Find the qualifications.
|
||||
while (Self.UnwrapSimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
|
||||
while (UnwrapDissimilarPointerTypes(UnwrappedSrcType, UnwrappedDestType)) {
|
||||
cv1.push_back(UnwrappedSrcType.getQualifiers());
|
||||
cv2.push_back(UnwrappedDestType.getQualifiers());
|
||||
}
|
||||
|
@ -944,26 +944,50 @@ CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
|
||||
return Result;
|
||||
}
|
||||
|
||||
Result->AddTypedTextChunk(
|
||||
Sel.getIdentifierInfoForSlot(0)->getName().str() + std::string(":"));
|
||||
std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
|
||||
SelName += ':';
|
||||
if (StartParameter == 0)
|
||||
Result->AddTypedTextChunk(SelName);
|
||||
else {
|
||||
Result->AddInformativeChunk(SelName);
|
||||
|
||||
// If there is only one parameter, and we're past it, add an empty
|
||||
// typed-text chunk since there is nothing to type.
|
||||
if (Method->param_size() == 1)
|
||||
Result->AddTypedTextChunk("");
|
||||
}
|
||||
unsigned Idx = 0;
|
||||
for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
|
||||
PEnd = Method->param_end();
|
||||
P != PEnd; (void)++P, ++Idx) {
|
||||
if (Idx > 0) {
|
||||
std::string Keyword = " ";
|
||||
std::string Keyword;
|
||||
if (Idx > StartParameter)
|
||||
Keyword = " ";
|
||||
if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
|
||||
Keyword += II->getName().str();
|
||||
Keyword += ":";
|
||||
Result->AddTextChunk(Keyword);
|
||||
if (Idx < StartParameter || AllParametersAreInformative) {
|
||||
Result->AddInformativeChunk(Keyword);
|
||||
} else if (Idx == StartParameter)
|
||||
Result->AddTypedTextChunk(Keyword);
|
||||
else
|
||||
Result->AddTextChunk(Keyword);
|
||||
}
|
||||
|
||||
// If we're before the starting parameter, skip the placeholder.
|
||||
if (Idx < StartParameter)
|
||||
continue;
|
||||
|
||||
std::string Arg;
|
||||
(*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
|
||||
Arg = "(" + Arg + ")";
|
||||
if (IdentifierInfo *II = (*P)->getIdentifier())
|
||||
Arg += II->getName().str();
|
||||
Result->AddPlaceholderChunk(Arg);
|
||||
if (AllParametersAreInformative)
|
||||
Result->AddInformativeChunk(Arg);
|
||||
else
|
||||
Result->AddPlaceholderChunk(Arg);
|
||||
}
|
||||
|
||||
return Result;
|
||||
@ -1066,6 +1090,17 @@ namespace {
|
||||
else if (X.Rank > Y.Rank)
|
||||
return false;
|
||||
|
||||
// We use a special ordering for keywords and patterns, based on the
|
||||
// typed text.
|
||||
if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
|
||||
(Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
|
||||
const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
|
||||
: X.Pattern->getTypedText();
|
||||
const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
|
||||
: Y.Pattern->getTypedText();
|
||||
return strcmp(XStr, YStr) < 0;
|
||||
}
|
||||
|
||||
// Result kinds are ordered by decreasing importance.
|
||||
if (X.Kind < Y.Kind)
|
||||
return true;
|
||||
@ -1087,12 +1122,14 @@ namespace {
|
||||
return isEarlierDeclarationName(X.Declaration->getDeclName(),
|
||||
Y.Declaration->getDeclName());
|
||||
|
||||
case Result::RK_Keyword:
|
||||
return strcmp(X.Keyword, Y.Keyword) < 0;
|
||||
|
||||
case Result::RK_Macro:
|
||||
return llvm::LowercaseString(X.Macro->getName()) <
|
||||
llvm::LowercaseString(Y.Macro->getName());
|
||||
|
||||
case Result::RK_Keyword:
|
||||
case Result::RK_Pattern:
|
||||
llvm::llvm_unreachable("Result kinds handled above");
|
||||
break;
|
||||
}
|
||||
|
||||
// Silence GCC warning.
|
||||
@ -1120,6 +1157,9 @@ static void HandleCodeCompleteResults(Sema *S,
|
||||
|
||||
if (CodeCompleter)
|
||||
CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
|
||||
|
||||
for (unsigned I = 0; I != NumResults; ++I)
|
||||
Results[I].Destroy();
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteOrdinaryName(Scope *S) {
|
||||
@ -1132,6 +1172,7 @@ void Sema::CodeCompleteOrdinaryName(Scope *S) {
|
||||
}
|
||||
|
||||
static void AddObjCProperties(ObjCContainerDecl *Container,
|
||||
bool AllowCategories,
|
||||
DeclContext *CurContext,
|
||||
ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
@ -1148,29 +1189,32 @@ static void AddObjCProperties(ObjCContainerDecl *Container,
|
||||
for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
|
||||
PEnd = Protocol->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
AddObjCProperties(*P, CurContext, Results);
|
||||
AddObjCProperties(*P, AllowCategories, CurContext, Results);
|
||||
} else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
|
||||
// Look through categories.
|
||||
for (ObjCCategoryDecl *Category = IFace->getCategoryList();
|
||||
Category; Category = Category->getNextClassCategory())
|
||||
AddObjCProperties(Category, CurContext, Results);
|
||||
if (AllowCategories) {
|
||||
// Look through categories.
|
||||
for (ObjCCategoryDecl *Category = IFace->getCategoryList();
|
||||
Category; Category = Category->getNextClassCategory())
|
||||
AddObjCProperties(Category, AllowCategories, CurContext, Results);
|
||||
}
|
||||
|
||||
// Look through protocols.
|
||||
for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
|
||||
E = IFace->protocol_end();
|
||||
I != E; ++I)
|
||||
AddObjCProperties(*I, CurContext, Results);
|
||||
AddObjCProperties(*I, AllowCategories, CurContext, Results);
|
||||
|
||||
// Look in the superclass.
|
||||
if (IFace->getSuperClass())
|
||||
AddObjCProperties(IFace->getSuperClass(), CurContext, Results);
|
||||
AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
|
||||
Results);
|
||||
} else if (const ObjCCategoryDecl *Category
|
||||
= dyn_cast<ObjCCategoryDecl>(Container)) {
|
||||
// Look through protocols.
|
||||
for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
|
||||
PEnd = Category->protocol_end();
|
||||
P != PEnd; ++P)
|
||||
AddObjCProperties(*P, CurContext, Results);
|
||||
AddObjCProperties(*P, AllowCategories, CurContext, Results);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1234,13 +1278,13 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
|
||||
const ObjCObjectPointerType *ObjCPtr
|
||||
= BaseType->getAsObjCInterfacePointerType();
|
||||
assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
|
||||
AddObjCProperties(ObjCPtr->getInterfaceDecl(), CurContext, Results);
|
||||
AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
|
||||
|
||||
// Add properties from the protocols in a qualified interface.
|
||||
for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
|
||||
E = ObjCPtr->qual_end();
|
||||
I != E; ++I)
|
||||
AddObjCProperties(*I, CurContext, Results);
|
||||
AddObjCProperties(*I, true, CurContext, Results);
|
||||
|
||||
// FIXME: We could (should?) also look for "implicit" properties, identified
|
||||
// only by the presence of nullary and unary selectors.
|
||||
@ -1611,34 +1655,104 @@ void Sema::CodeCompleteOperatorName(Scope *S) {
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) {
|
||||
/// \brief Determine whether the addition of the given flag to an Objective-C
|
||||
/// property's attributes will cause a conflict.
|
||||
static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
|
||||
// Check if we've already added this flag.
|
||||
if (Attributes & NewFlag)
|
||||
return true;
|
||||
|
||||
Attributes |= NewFlag;
|
||||
|
||||
// Check for collisions with "readonly".
|
||||
if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
|
||||
(Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
|
||||
ObjCDeclSpec::DQ_PR_assign |
|
||||
ObjCDeclSpec::DQ_PR_copy |
|
||||
ObjCDeclSpec::DQ_PR_retain)))
|
||||
return true;
|
||||
|
||||
// Check for more than one of { assign, copy, retain }.
|
||||
unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
|
||||
ObjCDeclSpec::DQ_PR_copy |
|
||||
ObjCDeclSpec::DQ_PR_retain);
|
||||
if (AssignCopyRetMask &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
|
||||
AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
|
||||
if (!CodeCompleter)
|
||||
return;
|
||||
|
||||
unsigned Attributes = ODS.getPropertyAttributes();
|
||||
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_readonly))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_assign))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_readwrite))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_retain))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_copy))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_nonatomic))
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_setter))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("setter", 0));
|
||||
if (!(Attributes & ObjCDeclSpec::DQ_PR_getter))
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result("getter", 0));
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
|
||||
CodeCompletionString *Setter = new CodeCompletionString;
|
||||
Setter->AddTypedTextChunk("setter");
|
||||
Setter->AddTextChunk(" = ");
|
||||
Setter->AddPlaceholderChunk("method");
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
|
||||
}
|
||||
if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
|
||||
CodeCompletionString *Getter = new CodeCompletionString;
|
||||
Getter->AddTypedTextChunk("getter");
|
||||
Getter->AddTextChunk(" = ");
|
||||
Getter->AddPlaceholderChunk("method");
|
||||
Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
|
||||
}
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
/// \brief Descripts the kind of Objective-C method that we want to find
|
||||
/// via code completion.
|
||||
enum ObjCMethodKind {
|
||||
MK_Any, //< Any kind of method, provided it means other specified criteria.
|
||||
MK_ZeroArgSelector, //< Zero-argument (unary) selector.
|
||||
MK_OneArgSelector //< One-argument selector.
|
||||
};
|
||||
|
||||
static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
|
||||
ObjCMethodKind WantKind,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents) {
|
||||
Selector Sel = Method->getSelector();
|
||||
if (NumSelIdents > Sel.getNumArgs())
|
||||
return false;
|
||||
|
||||
switch (WantKind) {
|
||||
case MK_Any: break;
|
||||
case MK_ZeroArgSelector: return Sel.isUnarySelector();
|
||||
case MK_OneArgSelector: return Sel.getNumArgs() == 1;
|
||||
}
|
||||
|
||||
for (unsigned I = 0; I != NumSelIdents; ++I)
|
||||
if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Add all of the Objective-C methods in the given Objective-C
|
||||
/// container to the set of results.
|
||||
///
|
||||
@ -1658,14 +1772,26 @@ void Sema::CodeCompleteObjCProperty(Scope *S, ObjCDeclSpec &ODS) {
|
||||
/// \param Results the structure into which we'll add results.
|
||||
static void AddObjCMethods(ObjCContainerDecl *Container,
|
||||
bool WantInstanceMethods,
|
||||
ObjCMethodKind WantKind,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents,
|
||||
DeclContext *CurContext,
|
||||
ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
|
||||
MEnd = Container->meth_end();
|
||||
M != MEnd; ++M) {
|
||||
if ((*M)->isInstanceMethod() == WantInstanceMethods)
|
||||
Results.MaybeAddResult(Result(*M, 0), CurContext);
|
||||
if ((*M)->isInstanceMethod() == WantInstanceMethods) {
|
||||
// Check whether the selector identifiers we've been given are a
|
||||
// subset of the identifiers for this particular method.
|
||||
if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
|
||||
continue;
|
||||
|
||||
Result R = Result(*M, 0);
|
||||
R.StartParameter = NumSelIdents;
|
||||
R.AllParametersAreInformative = (WantKind != MK_Any);
|
||||
Results.MaybeAddResult(R, CurContext);
|
||||
}
|
||||
}
|
||||
|
||||
ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
|
||||
@ -1677,12 +1803,14 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
|
||||
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
|
||||
E = Protocols.end();
|
||||
I != E; ++I)
|
||||
AddObjCMethods(*I, WantInstanceMethods, CurContext, Results);
|
||||
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
|
||||
CurContext, Results);
|
||||
|
||||
// Add methods in categories.
|
||||
for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
|
||||
CatDecl = CatDecl->getNextClassCategory()) {
|
||||
AddObjCMethods(CatDecl, WantInstanceMethods, CurContext, Results);
|
||||
AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
|
||||
NumSelIdents, CurContext, Results);
|
||||
|
||||
// Add a categories protocol methods.
|
||||
const ObjCList<ObjCProtocolDecl> &Protocols
|
||||
@ -1690,25 +1818,110 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
|
||||
for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
|
||||
E = Protocols.end();
|
||||
I != E; ++I)
|
||||
AddObjCMethods(*I, WantInstanceMethods, CurContext, Results);
|
||||
AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
|
||||
NumSelIdents, CurContext, Results);
|
||||
|
||||
// Add methods in category implementations.
|
||||
if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
|
||||
AddObjCMethods(Impl, WantInstanceMethods, CurContext, Results);
|
||||
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
|
||||
NumSelIdents, CurContext, Results);
|
||||
}
|
||||
|
||||
// Add methods in superclass.
|
||||
if (IFace->getSuperClass())
|
||||
AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, CurContext,
|
||||
Results);
|
||||
AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
|
||||
SelIdents, NumSelIdents, CurContext, Results);
|
||||
|
||||
// Add methods in our implementation, if any.
|
||||
if (ObjCImplementationDecl *Impl = IFace->getImplementation())
|
||||
AddObjCMethods(Impl, WantInstanceMethods, CurContext, Results);
|
||||
AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
|
||||
NumSelIdents, CurContext, Results);
|
||||
}
|
||||
|
||||
|
||||
void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
// Try to find the interface where getters might live.
|
||||
ObjCInterfaceDecl *Class
|
||||
= dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
|
||||
if (!Class) {
|
||||
if (ObjCCategoryDecl *Category
|
||||
= dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
|
||||
Class = Category->getClassInterface();
|
||||
|
||||
if (!Class)
|
||||
return;
|
||||
}
|
||||
|
||||
// Find all of the potential getters.
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// FIXME: We need to do this because Objective-C methods don't get
|
||||
// pushed into DeclContexts early enough. Argh!
|
||||
for (unsigned I = 0; I != NumMethods; ++I) {
|
||||
if (ObjCMethodDecl *Method
|
||||
= dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
|
||||
if (Method->isInstanceMethod() &&
|
||||
isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
|
||||
Result R = Result(Method, 0);
|
||||
R.AllParametersAreInformative = true;
|
||||
Results.MaybeAddResult(R, CurContext);
|
||||
}
|
||||
}
|
||||
|
||||
AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
|
||||
DeclPtrTy *Methods,
|
||||
unsigned NumMethods) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
// Try to find the interface where setters might live.
|
||||
ObjCInterfaceDecl *Class
|
||||
= dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
|
||||
if (!Class) {
|
||||
if (ObjCCategoryDecl *Category
|
||||
= dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
|
||||
Class = Category->getClassInterface();
|
||||
|
||||
if (!Class)
|
||||
return;
|
||||
}
|
||||
|
||||
// Find all of the potential getters.
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// FIXME: We need to do this because Objective-C methods don't get
|
||||
// pushed into DeclContexts early enough. Argh!
|
||||
for (unsigned I = 0; I != NumMethods; ++I) {
|
||||
if (ObjCMethodDecl *Method
|
||||
= dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
|
||||
if (Method->isInstanceMethod() &&
|
||||
isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
|
||||
Result R = Result(Method, 0);
|
||||
R.AllParametersAreInformative = true;
|
||||
Results.MaybeAddResult(R, CurContext);
|
||||
}
|
||||
}
|
||||
|
||||
AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
|
||||
SourceLocation FNameLoc) {
|
||||
SourceLocation FNameLoc,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
ObjCInterfaceDecl *CDecl = 0;
|
||||
|
||||
@ -1734,7 +1947,8 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
|
||||
SuperTy = Context.getObjCObjectPointerType(SuperTy);
|
||||
OwningExprResult Super
|
||||
= Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
|
||||
return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get());
|
||||
return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
|
||||
SelIdents, NumSelIdents);
|
||||
}
|
||||
|
||||
// Okay, we're calling a factory method in our superclass.
|
||||
@ -1756,21 +1970,25 @@ void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
|
||||
// probably calling an instance method.
|
||||
OwningExprResult Super = ActOnDeclarationNameExpr(S, FNameLoc, FName,
|
||||
false, 0, false);
|
||||
return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get());
|
||||
return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
|
||||
SelIdents, NumSelIdents);
|
||||
}
|
||||
|
||||
// Add all of the factory methods in this Objective-C class, its protocols,
|
||||
// superclasses, categories, implementation, etc.
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
AddObjCMethods(CDecl, false, CurContext, Results);
|
||||
AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
|
||||
Results);
|
||||
Results.ExitScope();
|
||||
|
||||
// This also suppresses remaining diagnostics.
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) {
|
||||
void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
|
||||
IdentifierInfo **SelIdents,
|
||||
unsigned NumSelIdents) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
Expr *RecExpr = static_cast<Expr *>(Receiver);
|
||||
@ -1798,7 +2016,8 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) {
|
||||
ReceiverType->isObjCQualifiedClassType()) {
|
||||
if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
|
||||
if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
|
||||
AddObjCMethods(ClassDecl, false, CurContext, Results);
|
||||
AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
|
||||
CurContext, Results);
|
||||
}
|
||||
}
|
||||
// Handle messages to a qualified ID ("id<foo>").
|
||||
@ -1808,19 +2027,22 @@ void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver) {
|
||||
for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
|
||||
E = QualID->qual_end();
|
||||
I != E; ++I)
|
||||
AddObjCMethods(*I, true, CurContext, Results);
|
||||
AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
|
||||
Results);
|
||||
}
|
||||
// Handle messages to a pointer to interface type.
|
||||
else if (const ObjCObjectPointerType *IFacePtr
|
||||
= ReceiverType->getAsObjCInterfacePointerType()) {
|
||||
// Search the class, its superclasses, etc., for instance methods.
|
||||
AddObjCMethods(IFacePtr->getInterfaceDecl(), true, CurContext, Results);
|
||||
AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
|
||||
NumSelIdents, CurContext, Results);
|
||||
|
||||
// Search protocols for instance methods.
|
||||
for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
|
||||
E = IFacePtr->qual_end();
|
||||
I != E; ++I)
|
||||
AddObjCMethods(*I, true, CurContext, Results);
|
||||
AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
|
||||
Results);
|
||||
}
|
||||
|
||||
Results.ExitScope();
|
||||
@ -1885,3 +2107,210 @@ void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
/// \brief Add all of the Objective-C interface declarations that we find in
|
||||
/// the given (translation unit) context.
|
||||
static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
|
||||
bool OnlyForwardDeclarations,
|
||||
bool OnlyUnimplemented,
|
||||
ResultBuilder &Results) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
for (DeclContext::decl_iterator D = Ctx->decls_begin(),
|
||||
DEnd = Ctx->decls_end();
|
||||
D != DEnd; ++D) {
|
||||
// Record any interfaces we find.
|
||||
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
|
||||
if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
|
||||
(!OnlyUnimplemented || !Class->getImplementation()))
|
||||
Results.MaybeAddResult(Result(Class, 0), CurContext);
|
||||
|
||||
// Record any forward-declared interfaces we find.
|
||||
if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
|
||||
for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
|
||||
C != CEnd; ++C)
|
||||
if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
|
||||
(!OnlyUnimplemented || !C->getInterface()->getImplementation()))
|
||||
Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// Add all classes.
|
||||
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
|
||||
false, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// Make sure that we ignore the class we're currently defining.
|
||||
NamedDecl *CurClass
|
||||
= LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
|
||||
if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
|
||||
Results.Ignore(CurClass);
|
||||
|
||||
// Add all classes.
|
||||
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
|
||||
false, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
|
||||
ResultBuilder Results(*this);
|
||||
Results.EnterNewScope();
|
||||
|
||||
// Add all unimplemented classes.
|
||||
AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
|
||||
true, Results);
|
||||
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
|
||||
IdentifierInfo *ClassName) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
ResultBuilder Results(*this);
|
||||
|
||||
// Ignore any categories we find that have already been implemented by this
|
||||
// interface.
|
||||
llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
|
||||
NamedDecl *CurClass
|
||||
= LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
|
||||
if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
|
||||
for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
|
||||
Category = Category->getNextClassCategory())
|
||||
CategoryNames.insert(Category->getIdentifier());
|
||||
|
||||
// Add all of the categories we know about.
|
||||
Results.EnterNewScope();
|
||||
TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
|
||||
for (DeclContext::decl_iterator D = TU->decls_begin(),
|
||||
DEnd = TU->decls_end();
|
||||
D != DEnd; ++D)
|
||||
if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
|
||||
if (CategoryNames.insert(Category->getIdentifier()))
|
||||
Results.MaybeAddResult(Result(Category, 0), CurContext);
|
||||
Results.ExitScope();
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
|
||||
IdentifierInfo *ClassName) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
|
||||
// Find the corresponding interface. If we couldn't find the interface, the
|
||||
// program itself is ill-formed. However, we'll try to be helpful still by
|
||||
// providing the list of all of the categories we know about.
|
||||
NamedDecl *CurClass
|
||||
= LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
|
||||
ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
|
||||
if (!Class)
|
||||
return CodeCompleteObjCInterfaceCategory(S, ClassName);
|
||||
|
||||
ResultBuilder Results(*this);
|
||||
|
||||
// Add all of the categories that have have corresponding interface
|
||||
// declarations in this class and any of its superclasses, except for
|
||||
// already-implemented categories in the class itself.
|
||||
llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
|
||||
Results.EnterNewScope();
|
||||
bool IgnoreImplemented = true;
|
||||
while (Class) {
|
||||
for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
|
||||
Category = Category->getNextClassCategory())
|
||||
if ((!IgnoreImplemented || !Category->getImplementation()) &&
|
||||
CategoryNames.insert(Category->getIdentifier()))
|
||||
Results.MaybeAddResult(Result(Category, 0), CurContext);
|
||||
|
||||
Class = Class->getSuperClass();
|
||||
IgnoreImplemented = false;
|
||||
}
|
||||
Results.ExitScope();
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
ResultBuilder Results(*this);
|
||||
|
||||
// Figure out where this @synthesize lives.
|
||||
ObjCContainerDecl *Container
|
||||
= dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
|
||||
if (!Container ||
|
||||
(!isa<ObjCImplementationDecl>(Container) &&
|
||||
!isa<ObjCCategoryImplDecl>(Container)))
|
||||
return;
|
||||
|
||||
// Ignore any properties that have already been implemented.
|
||||
for (DeclContext::decl_iterator D = Container->decls_begin(),
|
||||
DEnd = Container->decls_end();
|
||||
D != DEnd; ++D)
|
||||
if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
|
||||
Results.Ignore(PropertyImpl->getPropertyDecl());
|
||||
|
||||
// Add any properties that we find.
|
||||
Results.EnterNewScope();
|
||||
if (ObjCImplementationDecl *ClassImpl
|
||||
= dyn_cast<ObjCImplementationDecl>(Container))
|
||||
AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
|
||||
Results);
|
||||
else
|
||||
AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
|
||||
false, CurContext, Results);
|
||||
Results.ExitScope();
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
|
||||
IdentifierInfo *PropertyName,
|
||||
DeclPtrTy ObjCImpDecl) {
|
||||
typedef CodeCompleteConsumer::Result Result;
|
||||
ResultBuilder Results(*this);
|
||||
|
||||
// Figure out where this @synthesize lives.
|
||||
ObjCContainerDecl *Container
|
||||
= dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
|
||||
if (!Container ||
|
||||
(!isa<ObjCImplementationDecl>(Container) &&
|
||||
!isa<ObjCCategoryImplDecl>(Container)))
|
||||
return;
|
||||
|
||||
// Figure out which interface we're looking into.
|
||||
ObjCInterfaceDecl *Class = 0;
|
||||
if (ObjCImplementationDecl *ClassImpl
|
||||
= dyn_cast<ObjCImplementationDecl>(Container))
|
||||
Class = ClassImpl->getClassInterface();
|
||||
else
|
||||
Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
|
||||
->getClassInterface();
|
||||
|
||||
// Add all of the instance variables in this class and its superclasses.
|
||||
Results.EnterNewScope();
|
||||
for(; Class; Class = Class->getSuperClass()) {
|
||||
// FIXME: We could screen the type of each ivar for compatibility with
|
||||
// the property, but is that being too paternal?
|
||||
for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
|
||||
IVarEnd = Class->ivar_end();
|
||||
IVar != IVarEnd; ++IVar)
|
||||
Results.MaybeAddResult(Result(*IVar, 0), CurContext);
|
||||
}
|
||||
Results.ExitScope();
|
||||
|
||||
HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
|
||||
}
|
||||
|
@ -311,14 +311,16 @@ void Sema::ExitDeclaratorContext(Scope *S) {
|
||||
/// extension, in C when the previous function is already an
|
||||
/// overloaded function declaration or has the "overloadable"
|
||||
/// attribute.
|
||||
static bool AllowOverloadingOfFunction(Decl *PrevDecl, ASTContext &Context) {
|
||||
static bool AllowOverloadingOfFunction(LookupResult &Previous,
|
||||
ASTContext &Context) {
|
||||
if (Context.getLangOptions().CPlusPlus)
|
||||
return true;
|
||||
|
||||
if (isa<OverloadedFunctionDecl>(PrevDecl))
|
||||
if (Previous.getResultKind() == LookupResult::FoundOverloaded)
|
||||
return true;
|
||||
|
||||
return PrevDecl->getAttr<OverloadableAttr>() != 0;
|
||||
return (Previous.getResultKind() == LookupResult::Found
|
||||
&& Previous.getFoundDecl()->hasAttr<OverloadableAttr>());
|
||||
}
|
||||
|
||||
/// Add this decl to the scope shadowed decl chains.
|
||||
@ -396,6 +398,48 @@ bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S) {
|
||||
return IdResolver.isDeclInScope(D, Ctx, Context, S);
|
||||
}
|
||||
|
||||
static bool isOutOfScopePreviousDeclaration(NamedDecl *,
|
||||
DeclContext*,
|
||||
ASTContext&);
|
||||
|
||||
/// Filters out lookup results that don't fall within the given scope
|
||||
/// as determined by isDeclInScope.
|
||||
static void FilterLookupForScope(Sema &SemaRef, LookupResult &R,
|
||||
DeclContext *Ctx, Scope *S,
|
||||
bool ConsiderLinkage) {
|
||||
LookupResult::Filter F = R.makeFilter();
|
||||
while (F.hasNext()) {
|
||||
NamedDecl *D = F.next();
|
||||
|
||||
if (SemaRef.isDeclInScope(D, Ctx, S))
|
||||
continue;
|
||||
|
||||
if (ConsiderLinkage &&
|
||||
isOutOfScopePreviousDeclaration(D, Ctx, SemaRef.Context))
|
||||
continue;
|
||||
|
||||
F.erase();
|
||||
}
|
||||
|
||||
F.done();
|
||||
}
|
||||
|
||||
static bool isUsingDecl(NamedDecl *D) {
|
||||
return isa<UsingShadowDecl>(D) ||
|
||||
isa<UnresolvedUsingTypenameDecl>(D) ||
|
||||
isa<UnresolvedUsingValueDecl>(D);
|
||||
}
|
||||
|
||||
/// Removes using shadow declarations from the lookup results.
|
||||
static void RemoveUsingDecls(LookupResult &R) {
|
||||
LookupResult::Filter F = R.makeFilter();
|
||||
while (F.hasNext())
|
||||
if (isUsingDecl(F.next()))
|
||||
F.erase();
|
||||
|
||||
F.done();
|
||||
}
|
||||
|
||||
static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) {
|
||||
if (D->isUsed() || D->hasAttr<UnusedAttr>())
|
||||
return false;
|
||||
@ -572,11 +616,10 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid,
|
||||
/// how to resolve this situation, merging decls or emitting
|
||||
/// diagnostics as appropriate. If there was an error, set New to be invalid.
|
||||
///
|
||||
void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
|
||||
// If either decl is known invalid already, set the new one to be invalid and
|
||||
// don't bother doing any merging checks.
|
||||
if (New->isInvalidDecl() || OldD->isInvalidDecl())
|
||||
return New->setInvalidDecl();
|
||||
void Sema::MergeTypeDefDecl(TypedefDecl *New, LookupResult &OldDecls) {
|
||||
// If the new decl is known invalid already, don't bother doing any
|
||||
// merging checks.
|
||||
if (New->isInvalidDecl()) return;
|
||||
|
||||
// Allow multiple definitions for ObjC built-in typedefs.
|
||||
// FIXME: Verify the underlying types are equivalent!
|
||||
@ -611,16 +654,25 @@ void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
|
||||
}
|
||||
// Fall through - the typedef name was not a builtin type.
|
||||
}
|
||||
|
||||
// Verify the old decl was also a type.
|
||||
TypeDecl *Old = dyn_cast<TypeDecl>(OldD);
|
||||
if (!Old) {
|
||||
TypeDecl *Old = 0;
|
||||
if (!OldDecls.isSingleResult() ||
|
||||
!(Old = dyn_cast<TypeDecl>(OldDecls.getFoundDecl()))) {
|
||||
Diag(New->getLocation(), diag::err_redefinition_different_kind)
|
||||
<< New->getDeclName();
|
||||
|
||||
NamedDecl *OldD = OldDecls.getRepresentativeDecl();
|
||||
if (OldD->getLocation().isValid())
|
||||
Diag(OldD->getLocation(), diag::note_previous_definition);
|
||||
|
||||
return New->setInvalidDecl();
|
||||
}
|
||||
|
||||
// If the old declaration is invalid, just give up here.
|
||||
if (Old->isInvalidDecl())
|
||||
return New->setInvalidDecl();
|
||||
|
||||
// Determine the "old" type we'll use for checking and diagnostics.
|
||||
QualType OldType;
|
||||
if (TypedefDecl *OldTypedef = dyn_cast<TypedefDecl>(Old))
|
||||
@ -977,18 +1029,19 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
|
||||
/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
|
||||
/// definitions here, since the initializer hasn't been attached.
|
||||
///
|
||||
void Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
|
||||
// If either decl is invalid, make sure the new one is marked invalid and
|
||||
// don't do any other checking.
|
||||
if (New->isInvalidDecl() || OldD->isInvalidDecl())
|
||||
return New->setInvalidDecl();
|
||||
void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
||||
// If the new decl is already invalid, don't do any other checking.
|
||||
if (New->isInvalidDecl())
|
||||
return;
|
||||
|
||||
// Verify the old decl was also a variable.
|
||||
VarDecl *Old = dyn_cast<VarDecl>(OldD);
|
||||
if (!Old) {
|
||||
VarDecl *Old = 0;
|
||||
if (!Previous.isSingleResult() ||
|
||||
!(Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
|
||||
Diag(New->getLocation(), diag::err_redefinition_different_kind)
|
||||
<< New->getDeclName();
|
||||
Diag(OldD->getLocation(), diag::note_previous_definition);
|
||||
Diag(Previous.getRepresentativeDecl()->getLocation(),
|
||||
diag::note_previous_definition);
|
||||
return New->setInvalidDecl();
|
||||
}
|
||||
|
||||
@ -1403,6 +1456,33 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
|
||||
return DeclPtrTy::make(Tag);
|
||||
}
|
||||
|
||||
/// We are trying to introduce the given name into the given context;
|
||||
/// check if there's an existing declaration that can't be overloaded.
|
||||
///
|
||||
/// \return true if this is a forbidden redeclaration
|
||||
bool Sema::CheckRedeclaration(DeclContext *DC,
|
||||
DeclarationName Name,
|
||||
SourceLocation NameLoc,
|
||||
unsigned diagnostic) {
|
||||
LookupResult R(*this, Name, NameLoc, LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
LookupQualifiedName(R, DC);
|
||||
|
||||
if (R.empty()) return false;
|
||||
|
||||
if (R.getResultKind() == LookupResult::Found &&
|
||||
isa<TagDecl>(R.getFoundDecl()))
|
||||
return false;
|
||||
|
||||
// Pick a representative declaration.
|
||||
NamedDecl *PrevDecl = (*R.begin())->getUnderlyingDecl();
|
||||
|
||||
Diag(NameLoc, diagnostic) << Name;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// InjectAnonymousStructOrUnionMembers - Inject the members of the
|
||||
/// anonymous struct or union AnonRecord into the owning context Owner
|
||||
/// and scope S. This routine will be invoked just after we realize
|
||||
@ -1421,26 +1501,21 @@ Sema::DeclPtrTy Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) {
|
||||
/// structs/unions into the owning context and scope as well.
|
||||
bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
|
||||
RecordDecl *AnonRecord) {
|
||||
unsigned diagKind
|
||||
= AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl
|
||||
: diag::err_anonymous_struct_member_redecl;
|
||||
|
||||
bool Invalid = false;
|
||||
for (RecordDecl::field_iterator F = AnonRecord->field_begin(),
|
||||
FEnd = AnonRecord->field_end();
|
||||
F != FEnd; ++F) {
|
||||
if ((*F)->getDeclName()) {
|
||||
LookupResult R(*this, (*F)->getDeclName(), SourceLocation(),
|
||||
LookupOrdinaryName, ForRedeclaration);
|
||||
LookupQualifiedName(R, Owner);
|
||||
NamedDecl *PrevDecl = R.getAsSingleDecl(Context);
|
||||
if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
|
||||
if (CheckRedeclaration(Owner, (*F)->getDeclName(),
|
||||
(*F)->getLocation(), diagKind)) {
|
||||
// C++ [class.union]p2:
|
||||
// The names of the members of an anonymous union shall be
|
||||
// distinct from the names of any other entity in the
|
||||
// scope in which the anonymous union is declared.
|
||||
unsigned diagKind
|
||||
= AnonRecord->isUnion()? diag::err_anonymous_union_member_redecl
|
||||
: diag::err_anonymous_struct_member_redecl;
|
||||
Diag((*F)->getLocation(), diagKind)
|
||||
<< (*F)->getDeclName();
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_declaration);
|
||||
Invalid = true;
|
||||
} else {
|
||||
// C++ [class.union]p2:
|
||||
@ -1765,19 +1840,20 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
|
||||
}
|
||||
|
||||
DeclContext *DC;
|
||||
NamedDecl *PrevDecl;
|
||||
NamedDecl *New;
|
||||
|
||||
DeclaratorInfo *DInfo = 0;
|
||||
QualType R = GetTypeForDeclarator(D, S, &DInfo);
|
||||
|
||||
LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
|
||||
// See if this is a redefinition of a variable in the same scope.
|
||||
if (D.getCXXScopeSpec().isInvalid()) {
|
||||
DC = CurContext;
|
||||
PrevDecl = 0;
|
||||
D.setInvalidType();
|
||||
} else if (!D.getCXXScopeSpec().isSet()) {
|
||||
LookupNameKind NameKind = LookupOrdinaryName;
|
||||
bool IsLinkageLookup = false;
|
||||
|
||||
// If the declaration we're planning to build will be a function
|
||||
// or object with linkage, then look for another declaration with
|
||||
@ -1787,19 +1863,18 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
|
||||
else if (R->isFunctionType()) {
|
||||
if (CurContext->isFunctionOrMethod() ||
|
||||
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
|
||||
NameKind = LookupRedeclarationWithLinkage;
|
||||
IsLinkageLookup = true;
|
||||
} else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern)
|
||||
NameKind = LookupRedeclarationWithLinkage;
|
||||
IsLinkageLookup = true;
|
||||
else if (CurContext->getLookupContext()->isTranslationUnit() &&
|
||||
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static)
|
||||
NameKind = LookupRedeclarationWithLinkage;
|
||||
IsLinkageLookup = true;
|
||||
|
||||
if (IsLinkageLookup)
|
||||
Previous.clear(LookupRedeclarationWithLinkage);
|
||||
|
||||
DC = CurContext;
|
||||
LookupResult R(*this, Name, D.getIdentifierLoc(), NameKind,
|
||||
ForRedeclaration);
|
||||
|
||||
LookupName(R, S, NameKind == LookupRedeclarationWithLinkage);
|
||||
PrevDecl = R.getAsSingleDecl(Context);
|
||||
LookupName(Previous, S, /* CreateBuiltins = */ IsLinkageLookup);
|
||||
} else { // Something like "int foo::x;"
|
||||
DC = computeDeclContext(D.getCXXScopeSpec(), true);
|
||||
|
||||
@ -1819,10 +1894,11 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
|
||||
RequireCompleteDeclContext(D.getCXXScopeSpec()))
|
||||
return DeclPtrTy();
|
||||
|
||||
LookupResult Res(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
LookupQualifiedName(Res, DC);
|
||||
PrevDecl = Res.getAsSingleDecl(Context);
|
||||
LookupQualifiedName(Previous, DC);
|
||||
|
||||
// Don't consider using declarations as previous declarations for
|
||||
// out-of-line members.
|
||||
RemoveUsingDecls(Previous);
|
||||
|
||||
// C++ 7.3.1.2p2:
|
||||
// Members (including explicit specializations of templates) of a named
|
||||
@ -1870,23 +1946,25 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
|
||||
}
|
||||
}
|
||||
|
||||
if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
||||
if (Previous.isSingleResult() &&
|
||||
Previous.getFoundDecl()->isTemplateParameter()) {
|
||||
// Maybe we will complain about the shadowed template parameter.
|
||||
if (!D.isInvalidType())
|
||||
if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl))
|
||||
if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
|
||||
Previous.getFoundDecl()))
|
||||
D.setInvalidType();
|
||||
|
||||
// Just pretend that we didn't see the previous declaration.
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
}
|
||||
|
||||
// In C++, the previous declaration we find might be a tag type
|
||||
// (class or enum). In this case, the new declaration will hide the
|
||||
// tag type. Note that this does does not apply if we're declaring a
|
||||
// typedef (C++ [dcl.typedef]p4).
|
||||
if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag &&
|
||||
if (Previous.isSingleTagDecl() &&
|
||||
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef)
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
|
||||
bool Redeclaration = false;
|
||||
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
||||
@ -1895,13 +1973,13 @@ Sema::HandleDeclarator(Scope *S, Declarator &D,
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
||||
New = ActOnTypedefDeclarator(S, D, DC, R, DInfo, PrevDecl, Redeclaration);
|
||||
New = ActOnTypedefDeclarator(S, D, DC, R, DInfo, Previous, Redeclaration);
|
||||
} else if (R->isFunctionType()) {
|
||||
New = ActOnFunctionDeclarator(S, D, DC, R, DInfo, PrevDecl,
|
||||
New = ActOnFunctionDeclarator(S, D, DC, R, DInfo, Previous,
|
||||
move(TemplateParamLists),
|
||||
IsFunctionDefinition, Redeclaration);
|
||||
} else {
|
||||
New = ActOnVariableDeclarator(S, D, DC, R, DInfo, PrevDecl,
|
||||
New = ActOnVariableDeclarator(S, D, DC, R, DInfo, Previous,
|
||||
move(TemplateParamLists),
|
||||
Redeclaration);
|
||||
}
|
||||
@ -1970,16 +2048,19 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T,
|
||||
/// \brief Register the given locally-scoped external C declaration so
|
||||
/// that it can be found later for redeclarations
|
||||
void
|
||||
Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, NamedDecl *PrevDecl,
|
||||
Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND,
|
||||
const LookupResult &Previous,
|
||||
Scope *S) {
|
||||
assert(ND->getLexicalDeclContext()->isFunctionOrMethod() &&
|
||||
"Decl is not a locally-scoped decl!");
|
||||
// Note that we have a locally-scoped external with this name.
|
||||
LocallyScopedExternalDecls[ND->getDeclName()] = ND;
|
||||
|
||||
if (!PrevDecl)
|
||||
if (!Previous.isSingleResult())
|
||||
return;
|
||||
|
||||
NamedDecl *PrevDecl = Previous.getFoundDecl();
|
||||
|
||||
// If there was a previous declaration of this variable, it may be
|
||||
// in our identifier chain. Update the identifier chain with the new
|
||||
// declaration.
|
||||
@ -2015,7 +2096,7 @@ void Sema::DiagnoseFunctionSpecifiers(Declarator& D) {
|
||||
NamedDecl*
|
||||
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, DeclaratorInfo *DInfo,
|
||||
NamedDecl* PrevDecl, bool &Redeclaration) {
|
||||
LookupResult &Previous, bool &Redeclaration) {
|
||||
// Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
|
||||
if (D.getCXXScopeSpec().isSet()) {
|
||||
Diag(D.getIdentifierLoc(), diag::err_qualified_typedef_declarator)
|
||||
@ -2040,11 +2121,13 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
|
||||
// Handle attributes prior to checking for duplicates in MergeVarDecl
|
||||
ProcessDeclAttributes(S, NewTD, D);
|
||||
|
||||
// Merge the decl with the existing one if appropriate. If the decl is
|
||||
// in an outer scope, it isn't the same thing.
|
||||
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
|
||||
FilterLookupForScope(*this, Previous, DC, S, /*ConsiderLinkage*/ false);
|
||||
if (!Previous.empty()) {
|
||||
Redeclaration = true;
|
||||
MergeTypeDefDecl(NewTD, PrevDecl);
|
||||
MergeTypeDefDecl(NewTD, Previous);
|
||||
}
|
||||
|
||||
// C99 6.7.7p2: If a typedef name specifies a variably modified type
|
||||
@ -2155,7 +2238,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
|
||||
NamedDecl*
|
||||
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, DeclaratorInfo *DInfo,
|
||||
NamedDecl* PrevDecl,
|
||||
LookupResult &Previous,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool &Redeclaration) {
|
||||
DeclarationName Name = GetNameForDeclarator(D);
|
||||
@ -2285,22 +2368,21 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
SE->getByteLength())));
|
||||
}
|
||||
|
||||
// If name lookup finds a previous declaration that is not in the
|
||||
// same scope as the new declaration, this may still be an
|
||||
// acceptable redeclaration.
|
||||
if (PrevDecl && !isDeclInScope(PrevDecl, DC, S) &&
|
||||
!(NewVD->hasLinkage() &&
|
||||
isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
|
||||
PrevDecl = 0;
|
||||
// Don't consider existing declarations that are in a different
|
||||
// scope and are out-of-semantic-context declarations (if the new
|
||||
// declaration has linkage).
|
||||
FilterLookupForScope(*this, Previous, DC, S, NewVD->hasLinkage());
|
||||
|
||||
// Merge the decl with the existing one if appropriate.
|
||||
if (PrevDecl) {
|
||||
if (isa<FieldDecl>(PrevDecl) && D.getCXXScopeSpec().isSet()) {
|
||||
if (!Previous.empty()) {
|
||||
if (Previous.isSingleResult() &&
|
||||
isa<FieldDecl>(Previous.getFoundDecl()) &&
|
||||
D.getCXXScopeSpec().isSet()) {
|
||||
// The user tried to define a non-static data member
|
||||
// out-of-line (C++ [dcl.meaning]p1).
|
||||
Diag(NewVD->getLocation(), diag::err_nonstatic_member_out_of_line)
|
||||
<< D.getCXXScopeSpec().getRange();
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
NewVD->setInvalidDecl();
|
||||
}
|
||||
} else if (D.getCXXScopeSpec().isSet()) {
|
||||
@ -2311,17 +2393,18 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
NewVD->setInvalidDecl();
|
||||
}
|
||||
|
||||
CheckVariableDeclaration(NewVD, PrevDecl, Redeclaration);
|
||||
CheckVariableDeclaration(NewVD, Previous, Redeclaration);
|
||||
|
||||
// This is an explicit specialization of a static data member. Check it.
|
||||
if (isExplicitSpecialization && !NewVD->isInvalidDecl() &&
|
||||
CheckMemberSpecialization(NewVD, PrevDecl))
|
||||
CheckMemberSpecialization(NewVD, Previous))
|
||||
NewVD->setInvalidDecl();
|
||||
|
||||
|
||||
// attributes declared post-definition are currently ignored
|
||||
if (PrevDecl) {
|
||||
const VarDecl *Def = 0, *PrevVD = dyn_cast<VarDecl>(PrevDecl);
|
||||
if (PrevVD->getDefinition(Def) && D.hasAttributes()) {
|
||||
if (Previous.isSingleResult()) {
|
||||
const VarDecl *Def = 0;
|
||||
VarDecl *PrevDecl = dyn_cast<VarDecl>(Previous.getFoundDecl());
|
||||
if (PrevDecl && PrevDecl->getDefinition(Def) && D.hasAttributes()) {
|
||||
Diag(NewVD->getLocation(), diag::warn_attribute_precede_definition);
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
}
|
||||
@ -2331,7 +2414,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
// such variables.
|
||||
if (CurContext->isFunctionOrMethod() && NewVD->isExternC() &&
|
||||
!NewVD->isInvalidDecl())
|
||||
RegisterLocallyScopedExternCDecl(NewVD, PrevDecl, S);
|
||||
RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
|
||||
|
||||
return NewVD;
|
||||
}
|
||||
@ -2346,7 +2429,8 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
/// that have been instantiated from a template.
|
||||
///
|
||||
/// Sets NewVD->isInvalidDecl() if an error was encountered.
|
||||
void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
||||
void Sema::CheckVariableDeclaration(VarDecl *NewVD,
|
||||
LookupResult &Previous,
|
||||
bool &Redeclaration) {
|
||||
// If the decl is already known invalid, don't check it.
|
||||
if (NewVD->isInvalidDecl())
|
||||
@ -2419,14 +2503,14 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
||||
NewVD->setType(FixedTy);
|
||||
}
|
||||
|
||||
if (!PrevDecl && NewVD->isExternC()) {
|
||||
if (Previous.empty() && NewVD->isExternC()) {
|
||||
// Since we did not find anything by this name and we're declaring
|
||||
// an extern "C" variable, look for a non-visible extern "C"
|
||||
// declaration with the same name.
|
||||
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
|
||||
= LocallyScopedExternalDecls.find(NewVD->getDeclName());
|
||||
if (Pos != LocallyScopedExternalDecls.end())
|
||||
PrevDecl = Pos->second;
|
||||
Previous.addDecl(Pos->second);
|
||||
}
|
||||
|
||||
if (T->isVoidType() && !NewVD->hasExternalStorage()) {
|
||||
@ -2445,18 +2529,12 @@ void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
|
||||
return NewVD->setInvalidDecl();
|
||||
}
|
||||
|
||||
if (PrevDecl) {
|
||||
if (!Previous.empty()) {
|
||||
Redeclaration = true;
|
||||
MergeVarDecl(NewVD, PrevDecl);
|
||||
MergeVarDecl(NewVD, Previous);
|
||||
}
|
||||
}
|
||||
|
||||
static bool isUsingDecl(Decl *D) {
|
||||
return isa<UsingDecl>(D) ||
|
||||
isa<UnresolvedUsingTypenameDecl>(D) ||
|
||||
isa<UnresolvedUsingValueDecl>(D);
|
||||
}
|
||||
|
||||
/// \brief Data used with FindOverriddenMethod
|
||||
struct FindOverriddenMethodData {
|
||||
Sema *S;
|
||||
@ -2477,8 +2555,7 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier,
|
||||
Path.Decls.first != Path.Decls.second;
|
||||
++Path.Decls.first) {
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*Path.Decls.first)) {
|
||||
OverloadedFunctionDecl::function_iterator MatchedDecl;
|
||||
if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD, MatchedDecl))
|
||||
if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2486,10 +2563,30 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// AddOverriddenMethods - See if a method overrides any in the base classes,
|
||||
/// and if so, check that it's a valid override and remember it.
|
||||
void Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
|
||||
// Look for virtual methods in base classes that this method might override.
|
||||
CXXBasePaths Paths;
|
||||
FindOverriddenMethodData Data;
|
||||
Data.Method = MD;
|
||||
Data.S = this;
|
||||
if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) {
|
||||
for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
|
||||
E = Paths.found_decls_end(); I != E; ++I) {
|
||||
if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
|
||||
if (!CheckOverridingFunctionReturnType(MD, OldMD) &&
|
||||
!CheckOverridingFunctionExceptionSpec(MD, OldMD))
|
||||
MD->addOverriddenMethod(OldMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NamedDecl*
|
||||
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
QualType R, DeclaratorInfo *DInfo,
|
||||
NamedDecl* PrevDecl,
|
||||
LookupResult &Previous,
|
||||
MultiTemplateParamsArg TemplateParamLists,
|
||||
bool IsFunctionDefinition, bool &Redeclaration) {
|
||||
assert(R.getTypePtr()->isFunctionType());
|
||||
@ -2554,10 +2651,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
FunctionDecl *NewFD;
|
||||
|
||||
if (isFriend) {
|
||||
// DC is the namespace in which the function is being declared.
|
||||
assert((DC->isFileContext() || PrevDecl) && "previously-undeclared "
|
||||
"friend function being created in a non-namespace context");
|
||||
|
||||
// C++ [class.friend]p5
|
||||
// A function can be defined in a friend declaration of a
|
||||
// class . . . . Such a function is implicitly inline.
|
||||
@ -2733,37 +2826,29 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
}
|
||||
}
|
||||
|
||||
// Filter out previous declarations that don't match the scope.
|
||||
FilterLookupForScope(*this, Previous, DC, S, NewFD->hasLinkage());
|
||||
|
||||
if (isFriend) {
|
||||
// DC is the namespace in which the function is being declared.
|
||||
assert((DC->isFileContext() || !Previous.empty()) &&
|
||||
"previously-undeclared friend function being created "
|
||||
"in a non-namespace context");
|
||||
|
||||
if (FunctionTemplate) {
|
||||
FunctionTemplate->setObjectOfFriendDecl(
|
||||
/* PreviouslyDeclared= */ PrevDecl != NULL);
|
||||
/* PreviouslyDeclared= */ !Previous.empty());
|
||||
FunctionTemplate->setAccess(AS_public);
|
||||
}
|
||||
else
|
||||
NewFD->setObjectOfFriendDecl(/* PreviouslyDeclared= */ PrevDecl != NULL);
|
||||
NewFD->setObjectOfFriendDecl(/* PreviouslyDeclared= */ !Previous.empty());
|
||||
|
||||
NewFD->setAccess(AS_public);
|
||||
}
|
||||
|
||||
|
||||
if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) {
|
||||
// Look for virtual methods in base classes that this method might override.
|
||||
CXXBasePaths Paths;
|
||||
FindOverriddenMethodData Data;
|
||||
Data.Method = NewMD;
|
||||
Data.S = this;
|
||||
if (cast<CXXRecordDecl>(DC)->lookupInBases(&FindOverriddenMethod, &Data,
|
||||
Paths)) {
|
||||
for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(),
|
||||
E = Paths.found_decls_end(); I != E; ++I) {
|
||||
if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
|
||||
if (!CheckOverridingFunctionReturnType(NewMD, OldMD) &&
|
||||
!CheckOverridingFunctionExceptionSpec(NewMD, OldMD))
|
||||
NewMD->addOverriddenMethod(OldMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD))
|
||||
AddOverriddenMethods(cast<CXXRecordDecl>(DC), NewMD);
|
||||
|
||||
if (SC == FunctionDecl::Static && isa<CXXMethodDecl>(NewFD) &&
|
||||
!CurContext->isRecord()) {
|
||||
@ -2847,14 +2932,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
// Finally, we know we have the right number of parameters, install them.
|
||||
NewFD->setParams(Context, Params.data(), Params.size());
|
||||
|
||||
// If name lookup finds a previous declaration that is not in the
|
||||
// same scope as the new declaration, this may still be an
|
||||
// acceptable redeclaration.
|
||||
if (PrevDecl && !isDeclInScope(PrevDecl, DC, S) &&
|
||||
!(NewFD->hasLinkage() &&
|
||||
isOutOfScopePreviousDeclaration(PrevDecl, DC, Context)))
|
||||
PrevDecl = 0;
|
||||
|
||||
// If the declarator is a template-id, translate the parser's template
|
||||
// argument list into our AST format.
|
||||
bool HasExplicitTemplateArgs = false;
|
||||
@ -2891,22 +2968,26 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
isFunctionTemplateSpecialization = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (isFunctionTemplateSpecialization) {
|
||||
if (CheckFunctionTemplateSpecialization(NewFD, HasExplicitTemplateArgs,
|
||||
LAngleLoc, TemplateArgs.data(),
|
||||
TemplateArgs.size(), RAngleLoc,
|
||||
PrevDecl))
|
||||
Previous))
|
||||
NewFD->setInvalidDecl();
|
||||
} else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD) &&
|
||||
CheckMemberSpecialization(NewFD, PrevDecl))
|
||||
CheckMemberSpecialization(NewFD, Previous))
|
||||
NewFD->setInvalidDecl();
|
||||
|
||||
// Perform semantic checking on the function declaration.
|
||||
bool OverloadableAttrRequired = false; // FIXME: HACK!
|
||||
CheckFunctionDeclaration(NewFD, PrevDecl, isExplicitSpecialization,
|
||||
CheckFunctionDeclaration(NewFD, Previous, isExplicitSpecialization,
|
||||
Redeclaration, /*FIXME:*/OverloadableAttrRequired);
|
||||
|
||||
assert((NewFD->isInvalidDecl() || !Redeclaration ||
|
||||
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
|
||||
"previous declaration set still overloaded");
|
||||
|
||||
if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
|
||||
// An out-of-line member function declaration must also be a
|
||||
// definition (C++ [dcl.meaning]p1).
|
||||
@ -2918,7 +2999,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
|
||||
<< D.getCXXScopeSpec().getRange();
|
||||
NewFD->setInvalidDecl();
|
||||
} else if (!Redeclaration && (!PrevDecl || !isUsingDecl(PrevDecl))) {
|
||||
} else if (!Redeclaration) {
|
||||
// The user tried to provide an out-of-line definition for a
|
||||
// function that is a member of a class or namespace, but there
|
||||
// was no such member function declared (C++ [class.mfct]p2,
|
||||
@ -2948,8 +3029,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
isNearlyMatchingFunction(Context, cast<FunctionDecl>(*Func), NewFD))
|
||||
Diag((*Func)->getLocation(), diag::note_member_def_close_match);
|
||||
}
|
||||
|
||||
PrevDecl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2960,8 +3039,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
ProcessDeclAttributes(S, NewFD, D);
|
||||
|
||||
// attributes declared post-definition are currently ignored
|
||||
if (Redeclaration && PrevDecl) {
|
||||
const FunctionDecl *Def, *PrevFD = dyn_cast<FunctionDecl>(PrevDecl);
|
||||
if (Redeclaration && Previous.isSingleResult()) {
|
||||
const FunctionDecl *Def;
|
||||
FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
|
||||
if (PrevFD && PrevFD->getBody(Def) && D.hasAttributes()) {
|
||||
Diag(NewFD->getLocation(), diag::warn_attribute_precede_definition);
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
@ -2975,8 +3055,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
// with that name must be marked "overloadable".
|
||||
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
|
||||
<< Redeclaration << NewFD;
|
||||
if (PrevDecl)
|
||||
Diag(PrevDecl->getLocation(),
|
||||
if (!Previous.empty())
|
||||
Diag(Previous.getRepresentativeDecl()->getLocation(),
|
||||
diag::note_attribute_overloadable_prev_overload);
|
||||
NewFD->addAttr(::new (Context) OverloadableAttr());
|
||||
}
|
||||
@ -2985,7 +3065,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
// map of such names.
|
||||
if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
|
||||
&& !NewFD->isInvalidDecl())
|
||||
RegisterLocallyScopedExternCDecl(NewFD, PrevDecl, S);
|
||||
RegisterLocallyScopedExternCDecl(NewFD, Previous, S);
|
||||
|
||||
// Set this FunctionDecl's range up to the right paren.
|
||||
NewFD->setLocEnd(D.getSourceRange().getEnd());
|
||||
@ -3013,7 +3093,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
||||
/// an explicit specialization of the previous declaration.
|
||||
///
|
||||
/// This sets NewFD->isInvalidDecl() to true if there was an error.
|
||||
void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
|
||||
void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD,
|
||||
LookupResult &Previous,
|
||||
bool IsExplicitSpecialization,
|
||||
bool &Redeclaration,
|
||||
bool &OverloadableAttrRequired) {
|
||||
@ -3032,27 +3113,26 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
|
||||
CheckMain(NewFD);
|
||||
|
||||
// Check for a previous declaration of this name.
|
||||
if (!PrevDecl && NewFD->isExternC()) {
|
||||
if (Previous.empty() && NewFD->isExternC()) {
|
||||
// Since we did not find anything by this name and we're declaring
|
||||
// an extern "C" function, look for a non-visible extern "C"
|
||||
// declaration with the same name.
|
||||
llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos
|
||||
= LocallyScopedExternalDecls.find(NewFD->getDeclName());
|
||||
if (Pos != LocallyScopedExternalDecls.end())
|
||||
PrevDecl = Pos->second;
|
||||
Previous.addDecl(Pos->second);
|
||||
}
|
||||
|
||||
// Merge or overload the declaration with an existing declaration of
|
||||
// the same name, if appropriate.
|
||||
if (PrevDecl) {
|
||||
if (!Previous.empty()) {
|
||||
// Determine whether NewFD is an overload of PrevDecl or
|
||||
// a declaration that requires merging. If it's an overload,
|
||||
// there's no more work to do here; we'll just add the new
|
||||
// function to the scope.
|
||||
OverloadedFunctionDecl::function_iterator MatchedDecl;
|
||||
|
||||
if (!getLangOptions().CPlusPlus &&
|
||||
AllowOverloadingOfFunction(PrevDecl, Context)) {
|
||||
AllowOverloadingOfFunction(Previous, Context)) {
|
||||
OverloadableAttrRequired = true;
|
||||
|
||||
// Functions marked "overloadable" must have a prototype (that
|
||||
@ -3071,22 +3151,26 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
|
||||
}
|
||||
}
|
||||
|
||||
if (PrevDecl &&
|
||||
(!AllowOverloadingOfFunction(PrevDecl, Context) ||
|
||||
!IsOverload(NewFD, PrevDecl, MatchedDecl)) && !isUsingDecl(PrevDecl)) {
|
||||
Redeclaration = true;
|
||||
Decl *OldDecl = PrevDecl;
|
||||
|
||||
// If PrevDecl was an overloaded function, extract the
|
||||
// FunctionDecl that matched.
|
||||
if (isa<OverloadedFunctionDecl>(PrevDecl))
|
||||
OldDecl = *MatchedDecl;
|
||||
NamedDecl *OldDecl = 0;
|
||||
if (!Previous.empty()) {
|
||||
if (!AllowOverloadingOfFunction(Previous, Context)) {
|
||||
Redeclaration = true;
|
||||
OldDecl = Previous.getFoundDecl();
|
||||
} else if (!IsOverload(NewFD, Previous, OldDecl)) {
|
||||
if (!isUsingDecl(OldDecl))
|
||||
Redeclaration = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Redeclaration) {
|
||||
// NewFD and OldDecl represent declarations that need to be
|
||||
// merged.
|
||||
if (MergeFunctionDecl(NewFD, OldDecl))
|
||||
return NewFD->setInvalidDecl();
|
||||
|
||||
Previous.clear();
|
||||
Previous.addDecl(OldDecl);
|
||||
|
||||
if (FunctionTemplateDecl *OldTemplateDecl
|
||||
= dyn_cast<FunctionTemplateDecl>(OldDecl)) {
|
||||
NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl());
|
||||
@ -4313,11 +4397,13 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
|
||||
DeclContext *SearchDC = CurContext;
|
||||
DeclContext *DC = CurContext;
|
||||
NamedDecl *PrevDecl = 0;
|
||||
bool isStdBadAlloc = false;
|
||||
bool Invalid = false;
|
||||
|
||||
RedeclarationKind Redecl = (RedeclarationKind) (TUK != TUK_Reference);
|
||||
RedeclarationKind Redecl = (TUK != TUK_Reference ? ForRedeclaration
|
||||
: NotForRedeclaration);
|
||||
|
||||
LookupResult Previous(*this, Name, NameLoc, LookupTagName, Redecl);
|
||||
|
||||
if (Name && SS.isNotEmpty()) {
|
||||
// We have a nested-name tag ('struct foo::bar').
|
||||
@ -4344,17 +4430,13 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
DC = computeDeclContext(SS, true);
|
||||
SearchDC = DC;
|
||||
// Look-up name inside 'foo::'.
|
||||
LookupResult R(*this, Name, NameLoc, LookupTagName, Redecl);
|
||||
LookupQualifiedName(R, DC);
|
||||
LookupQualifiedName(Previous, DC);
|
||||
|
||||
if (R.isAmbiguous())
|
||||
if (Previous.isAmbiguous())
|
||||
return DeclPtrTy();
|
||||
|
||||
if (R.getResultKind() == LookupResult::Found)
|
||||
PrevDecl = dyn_cast<TagDecl>(R.getFoundDecl());
|
||||
|
||||
// A tag 'foo::bar' must already exist.
|
||||
if (!PrevDecl) {
|
||||
if (Previous.empty()) {
|
||||
Diag(NameLoc, diag::err_not_tag_in_scope) << Name << SS.getRange();
|
||||
Name = 0;
|
||||
Invalid = true;
|
||||
@ -4366,19 +4448,11 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// FIXME: We're looking into outer scopes here, even when we
|
||||
// shouldn't be. Doing so can result in ambiguities that we
|
||||
// shouldn't be diagnosing.
|
||||
LookupResult R(*this, Name, NameLoc, LookupTagName, Redecl);
|
||||
LookupName(R, S);
|
||||
if (R.isAmbiguous()) {
|
||||
// FIXME: This is not best way to recover from case like:
|
||||
//
|
||||
// struct S s;
|
||||
//
|
||||
// causes needless "incomplete type" error later.
|
||||
Name = 0;
|
||||
PrevDecl = 0;
|
||||
Invalid = true;
|
||||
} else
|
||||
PrevDecl = R.getAsSingleDecl(Context);
|
||||
LookupName(Previous, S);
|
||||
|
||||
// Note: there used to be some attempt at recovery here.
|
||||
if (Previous.isAmbiguous())
|
||||
return DeclPtrTy();
|
||||
|
||||
if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) {
|
||||
// FIXME: This makes sure that we ignore the contexts associated
|
||||
@ -4390,11 +4464,12 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
}
|
||||
}
|
||||
|
||||
if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
||||
if (Previous.isSingleResult() &&
|
||||
Previous.getFoundDecl()->isTemplateParameter()) {
|
||||
// Maybe we will complain about the shadowed template parameter.
|
||||
DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
|
||||
DiagnoseTemplateParameterShadow(NameLoc, Previous.getFoundDecl());
|
||||
// Just pretend that we didn't see the previous declaration.
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
}
|
||||
|
||||
if (getLangOptions().CPlusPlus && Name && DC && StdNamespace &&
|
||||
@ -4402,15 +4477,17 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// This is a declaration of or a reference to "std::bad_alloc".
|
||||
isStdBadAlloc = true;
|
||||
|
||||
if (!PrevDecl && StdBadAlloc) {
|
||||
if (Previous.empty() && StdBadAlloc) {
|
||||
// std::bad_alloc has been implicitly declared (but made invisible to
|
||||
// name lookup). Fill in this implicit declaration as the previous
|
||||
// declaration, so that the declarations get chained appropriately.
|
||||
PrevDecl = StdBadAlloc;
|
||||
Previous.addDecl(StdBadAlloc);
|
||||
}
|
||||
}
|
||||
|
||||
if (PrevDecl) {
|
||||
|
||||
if (!Previous.empty()) {
|
||||
assert(Previous.isSingleResult());
|
||||
NamedDecl *PrevDecl = Previous.getFoundDecl();
|
||||
if (TagDecl *PrevTagDecl = dyn_cast<TagDecl>(PrevDecl)) {
|
||||
// If this is a use of a previous tag, or if the tag is already declared
|
||||
// in the same scope (so that the definition/declaration completes or
|
||||
@ -4430,14 +4507,14 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
PrevTagDecl->getKindName());
|
||||
else
|
||||
Diag(KWLoc, diag::err_use_with_wrong_tag) << Name;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_use);
|
||||
Diag(PrevTagDecl->getLocation(), diag::note_previous_use);
|
||||
|
||||
if (SafeToContinue)
|
||||
Kind = PrevTagDecl->getTagKind();
|
||||
else {
|
||||
// Recover by making this an anonymous redefinition.
|
||||
Name = 0;
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
Invalid = true;
|
||||
}
|
||||
}
|
||||
@ -4450,7 +4527,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// For our current ASTs this shouldn't be a problem, but will
|
||||
// need to be changed with DeclGroups.
|
||||
if (TUK == TUK_Reference || TUK == TUK_Friend)
|
||||
return DeclPtrTy::make(PrevDecl);
|
||||
return DeclPtrTy::make(PrevTagDecl);
|
||||
|
||||
// Diagnose attempts to redefine a tag.
|
||||
if (TUK == TUK_Definition) {
|
||||
@ -4468,7 +4545,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// struct be anonymous, which will make any later
|
||||
// references get the previous definition.
|
||||
Name = 0;
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
Invalid = true;
|
||||
}
|
||||
} else {
|
||||
@ -4480,7 +4557,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
Diag(PrevTagDecl->getLocation(),
|
||||
diag::note_previous_definition);
|
||||
Name = 0;
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
Invalid = true;
|
||||
}
|
||||
}
|
||||
@ -4497,7 +4574,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// scope, e.g. "struct foo; void bar() { struct foo; }", just create a
|
||||
// new decl/type. We set PrevDecl to NULL so that the entities
|
||||
// have distinct types.
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
}
|
||||
// If we get here, we're going to create a new Decl. If PrevDecl
|
||||
// is non-NULL, it's a definition of the tag declared by
|
||||
@ -4511,12 +4588,12 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
Name = 0;
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
Invalid = true;
|
||||
} else {
|
||||
// The existing declaration isn't relevant to us; we're in a
|
||||
// new scope, so clear out the previous declaration.
|
||||
PrevDecl = 0;
|
||||
Previous.clear();
|
||||
}
|
||||
}
|
||||
} else if (TUK == TUK_Reference && SS.isEmpty() && Name &&
|
||||
@ -4570,6 +4647,10 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
|
||||
CreateNewDecl:
|
||||
|
||||
TagDecl *PrevDecl = 0;
|
||||
if (Previous.isSingleResult())
|
||||
PrevDecl = cast<TagDecl>(Previous.getFoundDecl());
|
||||
|
||||
// If there is an identifier, use the location of the identifier as the
|
||||
// location of the decl, otherwise use the location of the struct/union
|
||||
// keyword.
|
||||
@ -4651,7 +4732,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
|
||||
// If this is a specialization of a member class (of a class template),
|
||||
// check the specialization.
|
||||
if (isExplicitSpecialization && CheckMemberSpecialization(New, PrevDecl))
|
||||
if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
|
||||
Invalid = true;
|
||||
|
||||
if (Invalid)
|
||||
@ -4671,7 +4752,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
|
||||
// Mark this as a friend decl if applicable.
|
||||
if (TUK == TUK_Friend)
|
||||
New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ PrevDecl != NULL);
|
||||
New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty());
|
||||
|
||||
// Set the access specifier.
|
||||
if (!Invalid && TUK != TUK_Friend)
|
||||
|
@ -4668,7 +4668,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
|
||||
// FIXME: handle local classes
|
||||
|
||||
// Recover from invalid scope qualifiers as if they just weren't there.
|
||||
NamedDecl *PrevDecl = 0;
|
||||
LookupResult Previous(*this, Name, D.getIdentifierLoc(), LookupOrdinaryName,
|
||||
ForRedeclaration);
|
||||
if (!ScopeQual.isInvalid() && ScopeQual.isSet()) {
|
||||
// FIXME: RequireCompleteDeclContext
|
||||
DC = computeDeclContext(ScopeQual);
|
||||
@ -4676,15 +4677,15 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
|
||||
// FIXME: handle dependent contexts
|
||||
if (!DC) return DeclPtrTy();
|
||||
|
||||
LookupResult R(*this, Name, Loc, LookupOrdinaryName, ForRedeclaration);
|
||||
LookupQualifiedName(R, DC);
|
||||
PrevDecl = R.getAsSingleDecl(Context);
|
||||
LookupQualifiedName(Previous, DC);
|
||||
|
||||
// If searching in that context implicitly found a declaration in
|
||||
// a different context, treat it like it wasn't found at all.
|
||||
// TODO: better diagnostics for this case. Suggesting the right
|
||||
// qualified scope would be nice...
|
||||
if (!PrevDecl || !PrevDecl->getDeclContext()->Equals(DC)) {
|
||||
// FIXME: getRepresentativeDecl() is not right here at all
|
||||
if (Previous.empty() ||
|
||||
!Previous.getRepresentativeDecl()->getDeclContext()->Equals(DC)) {
|
||||
D.setInvalidType();
|
||||
Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
|
||||
return DeclPtrTy();
|
||||
@ -4711,12 +4712,10 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
|
||||
while (DC->isRecord())
|
||||
DC = DC->getParent();
|
||||
|
||||
LookupResult R(*this, Name, Loc, LookupOrdinaryName, ForRedeclaration);
|
||||
LookupQualifiedName(R, DC);
|
||||
PrevDecl = R.getAsSingleDecl(Context);
|
||||
LookupQualifiedName(Previous, DC);
|
||||
|
||||
// TODO: decide what we think about using declarations.
|
||||
if (PrevDecl)
|
||||
if (!Previous.empty())
|
||||
break;
|
||||
|
||||
if (DC->isFileContext()) break;
|
||||
@ -4728,7 +4727,8 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
|
||||
// C++0x changes this for both friend types and functions.
|
||||
// Most C++ 98 compilers do seem to give an error here, so
|
||||
// we do, too.
|
||||
if (PrevDecl && DC->Equals(CurContext) && !getLangOptions().CPlusPlus0x)
|
||||
if (!Previous.empty() && DC->Equals(CurContext)
|
||||
&& !getLangOptions().CPlusPlus0x)
|
||||
Diag(DS.getFriendSpecLoc(), diag::err_friend_is_member);
|
||||
}
|
||||
|
||||
@ -4745,7 +4745,7 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
|
||||
}
|
||||
|
||||
bool Redeclaration = false;
|
||||
NamedDecl *ND = ActOnFunctionDeclarator(S, D, DC, T, DInfo, PrevDecl,
|
||||
NamedDecl *ND = ActOnFunctionDeclarator(S, D, DC, T, DInfo, Previous,
|
||||
move(TemplateParams),
|
||||
IsDefinition,
|
||||
Redeclaration);
|
||||
|
@ -828,9 +828,10 @@ void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
|
||||
for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
|
||||
IF = IntfMethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
|
||||
IM != EM; ++IM, ++IF) {
|
||||
if (Context.typesAreCompatible((*IF)->getType(), (*IM)->getType()) ||
|
||||
Context.QualifiedIdConformsQualifiedId((*IF)->getType(),
|
||||
(*IM)->getType()))
|
||||
QualType ParmDeclTy = (*IF)->getType().getUnqualifiedType();
|
||||
QualType ParmImpTy = (*IM)->getType().getUnqualifiedType();
|
||||
if (Context.typesAreCompatible(ParmDeclTy, ParmImpTy) ||
|
||||
Context.QualifiedIdConformsQualifiedId(ParmDeclTy, ParmImpTy))
|
||||
continue;
|
||||
|
||||
Diag((*IM)->getLocation(), diag::warn_conflicting_param_types)
|
||||
|
@ -1445,6 +1445,12 @@ QualType Sema::CheckPointerToMemberOperands(
|
||||
}
|
||||
}
|
||||
|
||||
if (isa<CXXZeroInitValueExpr>(rex->IgnoreParens())) {
|
||||
// Diagnose use of pointer-to-member type which when used as
|
||||
// the functional cast in a pointer-to-member expression.
|
||||
Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
|
||||
return QualType();
|
||||
}
|
||||
// C++ 5.5p2
|
||||
// The result is an object or a function of the type specified by the
|
||||
// second operand.
|
||||
|
@ -246,7 +246,11 @@ void LookupResult::resolveKind() {
|
||||
unsigned N = Decls.size();
|
||||
|
||||
// Fast case: no possible ambiguity.
|
||||
if (N == 0) return;
|
||||
if (N == 0) {
|
||||
assert(ResultKind == NotFound);
|
||||
return;
|
||||
}
|
||||
|
||||
if (N == 1) {
|
||||
if (isa<UnresolvedUsingValueDecl>(Decls[0]))
|
||||
ResultKind = FoundUnresolvedValue;
|
||||
|
@ -284,100 +284,102 @@ void ImplicitConversionSequence::DebugPrint() const {
|
||||
// signature), IsOverload returns false and MatchedDecl will be set to
|
||||
// point to the FunctionDecl for #2.
|
||||
bool
|
||||
Sema::IsOverload(FunctionDecl *New, Decl* OldD,
|
||||
OverloadedFunctionDecl::function_iterator& MatchedDecl) {
|
||||
if (OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(OldD)) {
|
||||
// Is this new function an overload of every function in the
|
||||
// overload set?
|
||||
OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
|
||||
FuncEnd = Ovl->function_end();
|
||||
for (; Func != FuncEnd; ++Func) {
|
||||
if (!IsOverload(New, *Func, MatchedDecl)) {
|
||||
MatchedDecl = Func;
|
||||
Sema::IsOverload(FunctionDecl *New, LookupResult &Previous, NamedDecl *&Match) {
|
||||
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
||||
I != E; ++I) {
|
||||
NamedDecl *Old = (*I)->getUnderlyingDecl();
|
||||
if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(Old)) {
|
||||
if (!IsOverload(New, OldT->getTemplatedDecl())) {
|
||||
Match = Old;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// This function overloads every function in the overload set.
|
||||
return true;
|
||||
} else if (FunctionTemplateDecl *Old = dyn_cast<FunctionTemplateDecl>(OldD))
|
||||
return IsOverload(New, Old->getTemplatedDecl(), MatchedDecl);
|
||||
else if (FunctionDecl* Old = dyn_cast<FunctionDecl>(OldD)) {
|
||||
FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
|
||||
FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
|
||||
|
||||
// C++ [temp.fct]p2:
|
||||
// A function template can be overloaded with other function templates
|
||||
// and with normal (non-template) functions.
|
||||
if ((OldTemplate == 0) != (NewTemplate == 0))
|
||||
return true;
|
||||
|
||||
// Is the function New an overload of the function Old?
|
||||
QualType OldQType = Context.getCanonicalType(Old->getType());
|
||||
QualType NewQType = Context.getCanonicalType(New->getType());
|
||||
|
||||
// Compare the signatures (C++ 1.3.10) of the two functions to
|
||||
// determine whether they are overloads. If we find any mismatch
|
||||
// in the signature, they are overloads.
|
||||
|
||||
// If either of these functions is a K&R-style function (no
|
||||
// prototype), then we consider them to have matching signatures.
|
||||
if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
|
||||
isa<FunctionNoProtoType>(NewQType.getTypePtr()))
|
||||
} else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(Old)) {
|
||||
if (!IsOverload(New, OldF)) {
|
||||
Match = Old;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// (C++ 13p1):
|
||||
// Only function declarations can be overloaded; object and type
|
||||
// declarations cannot be overloaded.
|
||||
Match = Old;
|
||||
return false;
|
||||
|
||||
FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
|
||||
FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
|
||||
|
||||
// The signature of a function includes the types of its
|
||||
// parameters (C++ 1.3.10), which includes the presence or absence
|
||||
// of the ellipsis; see C++ DR 357).
|
||||
if (OldQType != NewQType &&
|
||||
(OldType->getNumArgs() != NewType->getNumArgs() ||
|
||||
OldType->isVariadic() != NewType->isVariadic() ||
|
||||
!std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
|
||||
NewType->arg_type_begin())))
|
||||
return true;
|
||||
|
||||
// C++ [temp.over.link]p4:
|
||||
// The signature of a function template consists of its function
|
||||
// signature, its return type and its template parameter list. The names
|
||||
// of the template parameters are significant only for establishing the
|
||||
// relationship between the template parameters and the rest of the
|
||||
// signature.
|
||||
//
|
||||
// We check the return type and template parameter lists for function
|
||||
// templates first; the remaining checks follow.
|
||||
if (NewTemplate &&
|
||||
(!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
|
||||
OldTemplate->getTemplateParameters(),
|
||||
false, TPL_TemplateMatch) ||
|
||||
OldType->getResultType() != NewType->getResultType()))
|
||||
return true;
|
||||
|
||||
// If the function is a class member, its signature includes the
|
||||
// cv-qualifiers (if any) on the function itself.
|
||||
//
|
||||
// As part of this, also check whether one of the member functions
|
||||
// is static, in which case they are not overloads (C++
|
||||
// 13.1p2). While not part of the definition of the signature,
|
||||
// this check is important to determine whether these functions
|
||||
// can be overloaded.
|
||||
CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
|
||||
CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
|
||||
if (OldMethod && NewMethod &&
|
||||
!OldMethod->isStatic() && !NewMethod->isStatic() &&
|
||||
OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
|
||||
return true;
|
||||
|
||||
// The signatures match; this is not an overload.
|
||||
return false;
|
||||
} else {
|
||||
// (C++ 13p1):
|
||||
// Only function declarations can be overloaded; object and type
|
||||
// declarations cannot be overloaded.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {
|
||||
FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
|
||||
FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
|
||||
|
||||
// C++ [temp.fct]p2:
|
||||
// A function template can be overloaded with other function templates
|
||||
// and with normal (non-template) functions.
|
||||
if ((OldTemplate == 0) != (NewTemplate == 0))
|
||||
return true;
|
||||
|
||||
// Is the function New an overload of the function Old?
|
||||
QualType OldQType = Context.getCanonicalType(Old->getType());
|
||||
QualType NewQType = Context.getCanonicalType(New->getType());
|
||||
|
||||
// Compare the signatures (C++ 1.3.10) of the two functions to
|
||||
// determine whether they are overloads. If we find any mismatch
|
||||
// in the signature, they are overloads.
|
||||
|
||||
// If either of these functions is a K&R-style function (no
|
||||
// prototype), then we consider them to have matching signatures.
|
||||
if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
|
||||
isa<FunctionNoProtoType>(NewQType.getTypePtr()))
|
||||
return false;
|
||||
|
||||
FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
|
||||
FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
|
||||
|
||||
// The signature of a function includes the types of its
|
||||
// parameters (C++ 1.3.10), which includes the presence or absence
|
||||
// of the ellipsis; see C++ DR 357).
|
||||
if (OldQType != NewQType &&
|
||||
(OldType->getNumArgs() != NewType->getNumArgs() ||
|
||||
OldType->isVariadic() != NewType->isVariadic() ||
|
||||
!std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
|
||||
NewType->arg_type_begin())))
|
||||
return true;
|
||||
|
||||
// C++ [temp.over.link]p4:
|
||||
// The signature of a function template consists of its function
|
||||
// signature, its return type and its template parameter list. The names
|
||||
// of the template parameters are significant only for establishing the
|
||||
// relationship between the template parameters and the rest of the
|
||||
// signature.
|
||||
//
|
||||
// We check the return type and template parameter lists for function
|
||||
// templates first; the remaining checks follow.
|
||||
if (NewTemplate &&
|
||||
(!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
|
||||
OldTemplate->getTemplateParameters(),
|
||||
false, TPL_TemplateMatch) ||
|
||||
OldType->getResultType() != NewType->getResultType()))
|
||||
return true;
|
||||
|
||||
// If the function is a class member, its signature includes the
|
||||
// cv-qualifiers (if any) on the function itself.
|
||||
//
|
||||
// As part of this, also check whether one of the member functions
|
||||
// is static, in which case they are not overloads (C++
|
||||
// 13.1p2). While not part of the definition of the signature,
|
||||
// this check is important to determine whether these functions
|
||||
// can be overloaded.
|
||||
CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
|
||||
CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
|
||||
if (OldMethod && NewMethod &&
|
||||
!OldMethod->isStatic() && !NewMethod->isStatic() &&
|
||||
OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
|
||||
return true;
|
||||
|
||||
// The signatures match; this is not an overload.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// TryImplicitConversion - Attempt to perform an implicit conversion
|
||||
@ -1545,18 +1547,23 @@ Sema::OverloadingResult Sema::IsUserDefinedConversion(
|
||||
}
|
||||
|
||||
bool
|
||||
Sema::DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType) {
|
||||
Sema::DiagnoseMultipleUserDefinedConversion(Expr *From, QualType ToType) {
|
||||
ImplicitConversionSequence ICS;
|
||||
OverloadCandidateSet CandidateSet;
|
||||
OverloadingResult OvResult =
|
||||
IsUserDefinedConversion(From, ToType, ICS.UserDefined,
|
||||
CandidateSet, true, false, false);
|
||||
if (OvResult != OR_Ambiguous)
|
||||
if (OvResult == OR_Ambiguous)
|
||||
Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_ambiguous_condition)
|
||||
<< From->getType() << ToType << From->getSourceRange();
|
||||
else if (OvResult == OR_No_Viable_Function && !CandidateSet.empty())
|
||||
Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_nonviable_condition)
|
||||
<< From->getType() << ToType << From->getSourceRange();
|
||||
else
|
||||
return false;
|
||||
Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_ambiguous_condition)
|
||||
<< From->getType() << ToType << From->getSourceRange();
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2072,7 +2079,7 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
|
||||
if (!PerformImplicitConversion(From, ToType, Flavor,
|
||||
/*AllowExplicit=*/false, Elidable))
|
||||
return false;
|
||||
if (!DiagnoseAmbiguousUserDefinedConversion(From, ToType))
|
||||
if (!DiagnoseMultipleUserDefinedConversion(From, ToType))
|
||||
return Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_convert_incompatible)
|
||||
<< ToType << From->getType() << Flavor << From->getSourceRange();
|
||||
@ -2085,8 +2092,11 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
|
||||
ImplicitConversionSequence
|
||||
Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
|
||||
QualType ClassType = Context.getTypeDeclType(Method->getParent());
|
||||
QualType ImplicitParamType
|
||||
= Context.getCVRQualifiedType(ClassType, Method->getTypeQualifiers());
|
||||
// [class.dtor]p2: A destructor can be invoked for a const, volatile or
|
||||
// const volatile object.
|
||||
unsigned Quals = isa<CXXDestructorDecl>(Method) ?
|
||||
Qualifiers::Const | Qualifiers::Volatile : Method->getTypeQualifiers();
|
||||
QualType ImplicitParamType = Context.getCVRQualifiedType(ClassType, Quals);
|
||||
|
||||
// Set up the conversion sequence as a "bad" conversion, to allow us
|
||||
// to exit early.
|
||||
@ -2101,7 +2111,7 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
|
||||
|
||||
assert(FromType->isRecordType());
|
||||
|
||||
// The implicit object parmeter is has the type "reference to cv X",
|
||||
// The implicit object parameter is has the type "reference to cv X",
|
||||
// where X is the class of which the function is a member
|
||||
// (C++ [over.match.funcs]p4). However, when finding an implicit
|
||||
// conversion sequence for the argument, we are not allowed to
|
||||
@ -2192,7 +2202,7 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
|
||||
if (!PerformImplicitConversion(From, Context.BoolTy, ICS, "converting"))
|
||||
return false;
|
||||
|
||||
if (!DiagnoseAmbiguousUserDefinedConversion(From, Context.BoolTy))
|
||||
if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
|
||||
return Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_bool_condition)
|
||||
<< From->getType() << From->getSourceRange();
|
||||
@ -3017,6 +3027,12 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty,
|
||||
assert(PointerTy && "type was not a pointer type!");
|
||||
|
||||
QualType PointeeTy = PointerTy->getPointeeType();
|
||||
// Don't add qualified variants of arrays. For one, they're not allowed
|
||||
// (the qualifier would sink to the element type), and for another, the
|
||||
// only overload situation where it matters is subscript or pointer +- int,
|
||||
// and those shouldn't have qualifier variants anyway.
|
||||
if (PointeeTy->isArrayType())
|
||||
return true;
|
||||
unsigned BaseCVR = PointeeTy.getCVRQualifiers();
|
||||
if (const ConstantArrayType *Array =Context.getAsConstantArrayType(PointeeTy))
|
||||
BaseCVR = Array->getElementType().getCVRQualifiers();
|
||||
@ -3057,6 +3073,12 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
|
||||
assert(PointerTy && "type was not a member pointer type!");
|
||||
|
||||
QualType PointeeTy = PointerTy->getPointeeType();
|
||||
// Don't add qualified variants of arrays. For one, they're not allowed
|
||||
// (the qualifier would sink to the element type), and for another, the
|
||||
// only overload situation where it matters is subscript or pointer +- int,
|
||||
// and those shouldn't have qualifier variants anyway.
|
||||
if (PointeeTy->isArrayType())
|
||||
return true;
|
||||
const Type *ClassTy = PointerTy->getClass();
|
||||
|
||||
// Iterate through all strict supersets of the pointee type's CVR
|
||||
@ -4873,11 +4895,13 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
|
||||
if (Opc == BinaryOperator::PtrMemD)
|
||||
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
|
||||
|
||||
// If this is one of the assignment operators, we only perform
|
||||
// overload resolution if the left-hand side is a class or
|
||||
// enumeration type (C++ [expr.ass]p3).
|
||||
if (Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign &&
|
||||
!Args[0]->getType()->isOverloadableType())
|
||||
// If this is the assignment operator, we only perform overload resolution
|
||||
// if the left-hand side is a class or enumeration type. This is actually
|
||||
// a hack. The standard requires that we do overload resolution between the
|
||||
// various built-in candidates, but as DR507 points out, this can lead to
|
||||
// problems. So we do it this way, which pretty much follows what GCC does.
|
||||
// Note that we go the traditional code path for compound assignment forms.
|
||||
if (Opc==BinaryOperator::Assign && !Args[0]->getType()->isOverloadableType())
|
||||
return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
|
||||
|
||||
// Build an empty overload set.
|
||||
|
@ -3538,15 +3538,17 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
|
||||
const TemplateArgumentLoc *ExplicitTemplateArgs,
|
||||
unsigned NumExplicitTemplateArgs,
|
||||
SourceLocation RAngleLoc,
|
||||
NamedDecl *&PrevDecl) {
|
||||
LookupResult &Previous) {
|
||||
// The set of function template specializations that could match this
|
||||
// explicit function template specialization.
|
||||
typedef llvm::SmallVector<FunctionDecl *, 8> CandidateSet;
|
||||
CandidateSet Candidates;
|
||||
|
||||
DeclContext *FDLookupContext = FD->getDeclContext()->getLookupContext();
|
||||
for (OverloadIterator Ovl(PrevDecl), OvlEnd; Ovl != OvlEnd; ++Ovl) {
|
||||
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(*Ovl)) {
|
||||
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
||||
I != E; ++I) {
|
||||
NamedDecl *Ovl = (*I)->getUnderlyingDecl();
|
||||
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
|
||||
// Only consider templates found within the same semantic lookup scope as
|
||||
// FD.
|
||||
if (!FDLookupContext->Equals(Ovl->getDeclContext()->getLookupContext()))
|
||||
@ -3637,7 +3639,8 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
|
||||
|
||||
// The "previous declaration" for this function template specialization is
|
||||
// the prior function template specialization.
|
||||
PrevDecl = Specialization;
|
||||
Previous.clear();
|
||||
Previous.addDecl(Specialization);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -3652,10 +3655,11 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
|
||||
/// \param Member the member declaration, which will be updated to become a
|
||||
/// specialization.
|
||||
///
|
||||
/// \param PrevDecl the set of declarations, one of which may be specialized
|
||||
/// by this function specialization.
|
||||
/// \param Previous the set of declarations, one of which may be specialized
|
||||
/// by this function specialization; the set will be modified to contain the
|
||||
/// redeclared member.
|
||||
bool
|
||||
Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
|
||||
Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
|
||||
assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
|
||||
|
||||
// Try to find the member we are instantiating.
|
||||
@ -3663,11 +3667,13 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
|
||||
NamedDecl *InstantiatedFrom = 0;
|
||||
MemberSpecializationInfo *MSInfo = 0;
|
||||
|
||||
if (!PrevDecl) {
|
||||
if (Previous.empty()) {
|
||||
// Nowhere to look anyway.
|
||||
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) {
|
||||
for (OverloadIterator Ovl(PrevDecl), OvlEnd; Ovl != OvlEnd; ++Ovl) {
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Ovl)) {
|
||||
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
||||
I != E; ++I) {
|
||||
NamedDecl *D = (*I)->getUnderlyingDecl();
|
||||
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
|
||||
if (Context.hasSameType(Function->getType(), Method->getType())) {
|
||||
Instantiation = Method;
|
||||
InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
|
||||
@ -3677,15 +3683,19 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
|
||||
}
|
||||
}
|
||||
} else if (isa<VarDecl>(Member)) {
|
||||
if (VarDecl *PrevVar = dyn_cast<VarDecl>(PrevDecl))
|
||||
VarDecl *PrevVar;
|
||||
if (Previous.isSingleResult() &&
|
||||
(PrevVar = dyn_cast<VarDecl>(Previous.getFoundDecl())))
|
||||
if (PrevVar->isStaticDataMember()) {
|
||||
Instantiation = PrevDecl;
|
||||
Instantiation = PrevVar;
|
||||
InstantiatedFrom = PrevVar->getInstantiatedFromStaticDataMember();
|
||||
MSInfo = PrevVar->getMemberSpecializationInfo();
|
||||
}
|
||||
} else if (isa<RecordDecl>(Member)) {
|
||||
if (CXXRecordDecl *PrevRecord = dyn_cast<CXXRecordDecl>(PrevDecl)) {
|
||||
Instantiation = PrevDecl;
|
||||
CXXRecordDecl *PrevRecord;
|
||||
if (Previous.isSingleResult() &&
|
||||
(PrevRecord = dyn_cast<CXXRecordDecl>(Previous.getFoundDecl()))) {
|
||||
Instantiation = PrevRecord;
|
||||
InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass();
|
||||
MSInfo = PrevRecord->getMemberSpecializationInfo();
|
||||
}
|
||||
@ -3774,7 +3784,8 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
|
||||
|
||||
// Save the caller the trouble of having to figure out which declaration
|
||||
// this specialization matches.
|
||||
PrevDecl = Instantiation;
|
||||
Previous.clear();
|
||||
Previous.addDecl(Instantiation);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,10 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||
// FIXME: In theory, we could have a previous declaration for variables that
|
||||
// are not static data members.
|
||||
bool Redeclaration = false;
|
||||
SemaRef.CheckVariableDeclaration(Var, 0, Redeclaration);
|
||||
// FIXME: having to fake up a LookupResult is dumb.
|
||||
LookupResult Previous(SemaRef, Var->getDeclName(), Var->getLocation(),
|
||||
Sema::LookupOrdinaryName);
|
||||
SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration);
|
||||
|
||||
if (D->isOutOfLine()) {
|
||||
D->getLexicalDeclContext()->addDecl(Var);
|
||||
@ -680,27 +683,24 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
||||
bool Redeclaration = false;
|
||||
bool OverloadableAttrRequired = false;
|
||||
|
||||
NamedDecl *PrevDecl = 0;
|
||||
LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(),
|
||||
Sema::LookupOrdinaryName, Sema::ForRedeclaration);
|
||||
|
||||
if (TemplateParams || !FunctionTemplate) {
|
||||
// Look only into the namespace where the friend would be declared to
|
||||
// find a previous declaration. This is the innermost enclosing namespace,
|
||||
// as described in ActOnFriendFunctionDecl.
|
||||
LookupResult R(SemaRef, Function->getDeclName(), SourceLocation(),
|
||||
Sema::LookupOrdinaryName,
|
||||
Sema::ForRedeclaration);
|
||||
SemaRef.LookupQualifiedName(R, DC);
|
||||
SemaRef.LookupQualifiedName(Previous, DC);
|
||||
|
||||
PrevDecl = R.getAsSingleDecl(SemaRef.Context);
|
||||
|
||||
// In C++, the previous declaration we find might be a tag type
|
||||
// (class or enum). In this case, the new declaration will hide the
|
||||
// tag type. Note that this does does not apply if we're declaring a
|
||||
// typedef (C++ [dcl.typedef]p4).
|
||||
if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
|
||||
PrevDecl = 0;
|
||||
if (Previous.isSingleTagDecl())
|
||||
Previous.clear();
|
||||
}
|
||||
|
||||
SemaRef.CheckFunctionDeclaration(Function, PrevDecl, false, Redeclaration,
|
||||
SemaRef.CheckFunctionDeclaration(Function, Previous, false, Redeclaration,
|
||||
/*FIXME:*/OverloadableAttrRequired);
|
||||
|
||||
// If the original function was part of a friend declaration,
|
||||
@ -709,6 +709,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
||||
= TemplateParams? cast<NamedDecl>(D->getDescribedFunctionTemplate()) : D;
|
||||
if (FromFriendD->getFriendObjectKind()) {
|
||||
NamedDecl *ToFriendD = 0;
|
||||
NamedDecl *PrevDecl;
|
||||
if (TemplateParams) {
|
||||
ToFriendD = cast<NamedDecl>(FunctionTemplate);
|
||||
PrevDecl = FunctionTemplate->getPreviousDeclaration();
|
||||
@ -843,32 +844,31 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
|
||||
if (InitMethodInstantiation(Method, D))
|
||||
Method->setInvalidDecl();
|
||||
|
||||
NamedDecl *PrevDecl = 0;
|
||||
LookupResult Previous(SemaRef, Name, SourceLocation(),
|
||||
Sema::LookupOrdinaryName, Sema::ForRedeclaration);
|
||||
|
||||
if (!FunctionTemplate || TemplateParams) {
|
||||
LookupResult R(SemaRef, Name, SourceLocation(),
|
||||
Sema::LookupOrdinaryName,
|
||||
Sema::ForRedeclaration);
|
||||
SemaRef.LookupQualifiedName(R, Owner);
|
||||
PrevDecl = R.getAsSingleDecl(SemaRef.Context);
|
||||
SemaRef.LookupQualifiedName(Previous, Owner);
|
||||
|
||||
// In C++, the previous declaration we find might be a tag type
|
||||
// (class or enum). In this case, the new declaration will hide the
|
||||
// tag type. Note that this does does not apply if we're declaring a
|
||||
// typedef (C++ [dcl.typedef]p4).
|
||||
if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
|
||||
PrevDecl = 0;
|
||||
if (Previous.isSingleTagDecl())
|
||||
Previous.clear();
|
||||
}
|
||||
|
||||
bool Redeclaration = false;
|
||||
bool OverloadableAttrRequired = false;
|
||||
SemaRef.CheckFunctionDeclaration(Method, PrevDecl, false, Redeclaration,
|
||||
SemaRef.CheckFunctionDeclaration(Method, Previous, false, Redeclaration,
|
||||
/*FIXME:*/OverloadableAttrRequired);
|
||||
|
||||
if (!FunctionTemplate && (!Method->isInvalidDecl() || !PrevDecl) &&
|
||||
if (!FunctionTemplate && (!Method->isInvalidDecl() || Previous.empty()) &&
|
||||
!Method->getFriendObjectKind())
|
||||
Owner->addDecl(Method);
|
||||
|
||||
SemaRef.AddOverriddenMethods(Record, Method);
|
||||
|
||||
return Method;
|
||||
}
|
||||
|
||||
|
@ -3037,18 +3037,21 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
|
||||
template<typename Derived>
|
||||
Sema::OwningStmtResult
|
||||
TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
|
||||
// The case value expressions are not potentially evaluated.
|
||||
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||
OwningExprResult LHS(SemaRef), RHS(SemaRef);
|
||||
{
|
||||
// The case value expressions are not potentially evaluated.
|
||||
EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
|
||||
|
||||
// Transform the left-hand case value.
|
||||
OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
|
||||
if (LHS.isInvalid())
|
||||
return SemaRef.StmtError();
|
||||
// Transform the left-hand case value.
|
||||
LHS = getDerived().TransformExpr(S->getLHS());
|
||||
if (LHS.isInvalid())
|
||||
return SemaRef.StmtError();
|
||||
|
||||
// Transform the right-hand case value (for the GNU case-range extension).
|
||||
OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
|
||||
if (RHS.isInvalid())
|
||||
return SemaRef.StmtError();
|
||||
// Transform the right-hand case value (for the GNU case-range extension).
|
||||
RHS = getDerived().TransformExpr(S->getRHS());
|
||||
if (RHS.isInvalid())
|
||||
return SemaRef.StmtError();
|
||||
}
|
||||
|
||||
// Build the case statement.
|
||||
// Case statements are always rebuilt so that they will attached to their
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=basic -analyzer-store=basic
|
||||
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -verify %s -analyzer-constraints=range -analyzer-store=basic
|
||||
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-purge-dead=false -verify %s
|
||||
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -analyzer-no-purge-dead -verify %s
|
||||
// RUN: clang-cc -triple i386-apple-darwin10 -analyze -analyzer-experimental-internal-checks -std=gnu99 -checker-cfref -analyzer-store=region -analyzer-constraints=range -verify %s
|
||||
|
||||
typedef unsigned uintptr_t;
|
||||
|
@ -31,7 +31,7 @@ void test() {
|
||||
}
|
||||
|
||||
namespace Numbers {
|
||||
struct Number {
|
||||
struct Number { // expected-note 2 {{candidate}}
|
||||
explicit Number(double d) : d(d) {}
|
||||
double d;
|
||||
};
|
||||
@ -57,9 +57,9 @@ void test3() {
|
||||
|
||||
int i = Ints::zero;
|
||||
Numbers2::f(i);
|
||||
Numbers2::g(i); // expected-error {{incompatible type passing 'int'}}
|
||||
Numbers2::g(i); // expected-error {{no viable conversion from 'int' to 'struct Numbers::Number' is possible}}
|
||||
|
||||
float f = Floats::zero;
|
||||
Numbers2::f(f);
|
||||
Numbers2::g(f); // expected-error {{incompatible type passing 'float'}}
|
||||
Numbers2::g(f); // expected-error {{no viable conversion from 'float' to 'struct Numbers::Number' is possible}}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
template <unsigned N> class test {};
|
||||
|
||||
class foo {};
|
||||
class foo {}; // expected-note {{candidate}}
|
||||
test<0> foo(foo); // expected-note {{candidate}}
|
||||
|
||||
namespace Test0 {
|
||||
@ -38,7 +38,7 @@ namespace Test0 {
|
||||
test<2> _1 = (foo)(a);
|
||||
|
||||
class Test0::foo b;
|
||||
test<2> _2 = (foo)(b); // expected-error {{incompatible type passing}}
|
||||
test<2> _2 = (foo)(b); // expected-error {{no viable conversion from 'class Test0::foo' to 'class foo' is possible}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
test/CXX/special/class.dtor/p2.cpp
Normal file
7
test/CXX/special/class.dtor/p2.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
// PR5548
|
||||
struct A {~A();};
|
||||
void a(const A* x) {
|
||||
x->~A();
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// RUN: clang-cc -fmath-errno=1 -emit-llvm -o %t %s -triple i386-unknown-unknown
|
||||
// RUN: clang-cc -emit-llvm -o %t %s -triple i386-unknown-unknown
|
||||
// RUN: grep "declare " %t | count 6
|
||||
// RUN: grep "declare " %t | grep "@llvm." | count 1
|
||||
// RUN: clang-cc -fmath-errno=0 -emit-llvm -o %t %s -triple i386-unknown-unknown
|
||||
// RUN: clang-cc -fno-math-errno -emit-llvm -o %t %s -triple i386-unknown-unknown
|
||||
// RUN: grep "declare " %t | count 6
|
||||
// RUN: grep "declare " %t | grep -v "@llvm." | count 0
|
||||
|
||||
|
@ -6,4 +6,4 @@
|
||||
|
||||
// CHECK: "-analyze"
|
||||
// CHECK: "-target-feature" "+sse"
|
||||
// CHECK: "--fmath-errno=0"
|
||||
// CHECK: "-fno-math-errno"
|
||||
|
@ -5,7 +5,6 @@
|
||||
// RUN: grep '"--relocation-model" "static"' %t.log
|
||||
// RUN: grep '"--disable-fp-elim"' %t.log
|
||||
// RUN: grep '"--unwind-tables=0"' %t.log
|
||||
// RUN: grep '"--fmath-errno=1"' %t.log
|
||||
// RUN: grep '"-Os"' %t.log
|
||||
// RUN: grep '"-o" .*clang-translation.*' %t.log
|
||||
// RUN: grep '"--asm-verbose"' %t.log
|
||||
|
@ -1,10 +1,9 @@
|
||||
// RUN: clang -### -S -x c /dev/null -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings %s 2> %t
|
||||
// RUN: grep -F '"-fblocks"' %t
|
||||
// RUN: grep -F '"--fmath-errno=1"' %t
|
||||
// RUN: grep -F '"-fpascal-strings"' %t
|
||||
// RUN: clang -### -S -x c /dev/null -fblocks -fbuiltin -fmath-errno -fcommon -fpascal-strings -fno-blocks -fno-builtin -fno-math-errno -fno-common -fno-pascal-strings -fno-show-source-location -fshort-wchar %s 2> %t
|
||||
// RUN: grep -F '"-fbuiltin=0"' %t
|
||||
// RUN: grep -F '"-fno-builtin"' %t
|
||||
// RUN: grep -F '"-fno-common"' %t
|
||||
// RUN: grep -F '"--fmath-errno=0"' %t
|
||||
// RUN: grep -F '"-fno-math-errno"' %t
|
||||
// RUN: grep -F '"-fno-show-source-location"' %t
|
||||
// RUN: grep -F '"-fshort-wchar"' %t
|
||||
|
@ -32,20 +32,20 @@ void function(Foo * arg)
|
||||
// CHECK-scan: {start_line=13 start_col=24 end_line=16 end_col=1} FunctionDecl=function:13:6
|
||||
// CHECK-scan: {start_line=16 start_col=2 end_line=52 end_col=1} Invalid Cursor => NoDeclFound
|
||||
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:80:16: StructDecl=__va_list_tag:80:16 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:80:42: FieldDecl=gp_offset:80:42 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:63: FieldDecl=fp_offset:80:63 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:81: FieldDecl=overflow_arg_area:80:81 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:107: FieldDecl=reg_save_area:80:107 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:123: TypedefDecl=__va_list_tag:80:123 [Context=TestClassDecl.m]
|
||||
// CHECK-load: <invalid loc>:80:159: TypedefDecl=__builtin_va_list:80:159 [Context=TestClassDecl.m]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CHECK-load: TestClassDecl.m:10:12: ObjCInterfaceDecl=Foo:10:1 [Context=TestClassDecl.m]
|
||||
// CHECK-load: TestClassDecl.m:13:6: FunctionDefn=function [Context=TestClassDecl.m]
|
||||
// CHECK-load: TestClassDecl.m:13:21: ParmDecl=arg:13:21 [Context=function]
|
||||
|
@ -27,20 +27,20 @@ void function(Foo * arg)
|
||||
// CHECK-scan: {start_line=10 start_col=24 end_line=13 end_col=1} FunctionDecl=function:10:6
|
||||
// CHECK-scan: {start_line=13 start_col=2 end_line=46 end_col=1} Invalid Cursor => NoDeclFound
|
||||
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:80:16: StructDecl=__va_list_tag:80:16 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:80:42: FieldDecl=gp_offset:80:42 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:63: FieldDecl=fp_offset:80:63 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:81: FieldDecl=overflow_arg_area:80:81 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:107: FieldDecl=reg_save_area:80:107 [Context=__va_list_tag]
|
||||
// CHECK-load: <invalid loc>:80:123: TypedefDecl=__va_list_tag:80:123 [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: <invalid loc>:80:159: TypedefDecl=__builtin_va_list:80:159 [Context=TestClassForwardDecl.m]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// CHECK-load: TestClassForwardDecl.m:10:6: FunctionDefn=function [Context=TestClassForwardDecl.m]
|
||||
// CHECK-load: TestClassForwardDecl.m:10:21: ParmDecl=arg:10:21 [Context=function]
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
// RUN: clang-cc -triple x86_64-apple-darwin10 -fobjc-nonfragile-abi -fblocks -emit-pch -x objective-c %s -o %t.ast
|
||||
// RUN: c-index-test -test-load-tu %t.ast all | FileCheck %s
|
||||
|
||||
// CHECK: <invalid loc>:0:0: TypedefDecl=__int128_t:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:0:0: TypedefDecl=__uint128_t:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:0:0: StructDecl=objc_selector:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:0:0: TypedefDecl=SEL:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:0:0: ObjCInterfaceDecl=Protocol:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:0:0: TypedefDecl=id:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:0:0: TypedefDecl=Class:0:0 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:80:16: StructDecl=__va_list_tag:80:16 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:80:42: FieldDecl=gp_offset:80:42 [Context=__va_list_tag]
|
||||
// CHECK: <invalid loc>:80:63: FieldDecl=fp_offset:80:63 [Context=__va_list_tag]
|
||||
// CHECK: <invalid loc>:80:81: FieldDecl=overflow_arg_area:80:81 [Context=__va_list_tag]
|
||||
// CHECK: <invalid loc>:80:107: FieldDecl=reg_save_area:80:107 [Context=__va_list_tag]
|
||||
// CHECK: <invalid loc>:80:123: TypedefDecl=__va_list_tag:80:123 [Context=c-index-api-loadTU-test.m]
|
||||
// CHECK: <invalid loc>:80:159: TypedefDecl=__builtin_va_list:80:159 [Context=c-index-api-loadTU-test.m]
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@interface Foo
|
||||
{
|
||||
|
39
test/Index/complete-categories.m
Normal file
39
test/Index/complete-categories.m
Normal file
@ -0,0 +1,39 @@
|
||||
/* Note: the RUN lines are near the end of the file, since line/column
|
||||
matter for this test. */
|
||||
|
||||
@interface I1 @end
|
||||
@interface I2 @end
|
||||
@interface I3 : I2 @end
|
||||
|
||||
@interface I1(Cat1) @end
|
||||
@interface I1(Cat2) @end
|
||||
@interface I1(Cat3) @end
|
||||
|
||||
@interface I2 (Cat2) @end
|
||||
@interface I2 (Cat3) @end
|
||||
@interface I2 (Cat2) @end
|
||||
@interface I3 (Cat1) @end
|
||||
@interface I3 (Cat2) @end
|
||||
|
||||
@implementation I1(Cat2) @end
|
||||
@implementation I1(Cat3) @end
|
||||
@implementation I3(Cat2) @end
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:12:16 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat1}
|
||||
// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat2}
|
||||
// CHECK-CC1: ObjCCategoryDecl:{TypedText Cat3}
|
||||
// RUN: c-index-test -code-completion-at=%s:13:16 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: ObjCCategoryDecl:{TypedText Cat1}
|
||||
// CHECK-CC2-NEXT: ObjCCategoryDecl:{TypedText Cat3}
|
||||
// RUN: c-index-test -code-completion-at=%s:18:20 %s | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat1}
|
||||
// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat2}
|
||||
// CHECK-CC3: ObjCCategoryDecl:{TypedText Cat3}
|
||||
// RUN: c-index-test -code-completion-at=%s:19:20 %s | FileCheck -check-prefix=CHECK-CC4 %s
|
||||
// CHECK-CC4: ObjCCategoryDecl:{TypedText Cat1}
|
||||
// CHECK-CC4-NEXT: ObjCCategoryDecl:{TypedText Cat3}
|
||||
// RUN: c-index-test -code-completion-at=%s:20:20 %s | FileCheck -check-prefix=CHECK-CC5 %s
|
||||
// CHECK-CC5: ObjCCategoryDecl:{TypedText Cat1}
|
||||
// CHECK-CC5-NEXT: ObjCCategoryDecl:{TypedText Cat2}
|
||||
// CHECK-CC5-NEXT: ObjCCategoryDecl:{TypedText Cat3}
|
43
test/Index/complete-interfaces.m
Normal file
43
test/Index/complete-interfaces.m
Normal file
@ -0,0 +1,43 @@
|
||||
/* Note: the RUN lines are near the end of the file, since line/column
|
||||
matter for this test. */
|
||||
|
||||
@class Int1, Int2, Int3, Int4;
|
||||
|
||||
@interface Int3
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@interface Int2 : Int3
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation Int2
|
||||
@end
|
||||
|
||||
@implementation Int3
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:6:12 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int2}
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC1: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int2}
|
||||
// CHECK-CC2-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:11:19 %s | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
// CHECK-CC3: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC3-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:16:17 %s | FileCheck -check-prefix=CHECK-CC4 %s
|
||||
// CHECK-CC4: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int2}
|
||||
// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC4-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
||||
// RUN: c-index-test -code-completion-at=%s:19:17 %s | FileCheck -check-prefix=CHECK-CC5 %s
|
||||
// CHECK-CC5: ObjCInterfaceDecl:{TypedText Int1}
|
||||
// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int3}
|
||||
// CHECK-CC5-NEXT: ObjCInterfaceDecl:{TypedText Int4}
|
@ -82,6 +82,19 @@ void test_qual_id(id<FooTestProtocol,FooTestProtocol2> ptr) {
|
||||
[ptr protocolInstanceMethod:1];
|
||||
}
|
||||
|
||||
@interface Overload
|
||||
- (int)Method:(int)i;
|
||||
- (int)Method;
|
||||
- (int)Method:(float)f Arg1:(int)i1 Arg2:(int)i2;
|
||||
- (int)Method:(float)f Arg1:(int)i1 OtherArg:(id)obj;
|
||||
- (int)Method:(float)f SomeArg:(int)i1 OtherArg:(id)obj;
|
||||
- (int)OtherMethod:(float)f Arg1:(int)i1 Arg2:(int)i2;
|
||||
@end
|
||||
|
||||
void test_overload(Overload *ovl) {
|
||||
[ovl Method:1 Arg1:1 OtherArg:ovl];
|
||||
}
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:23:19 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: {TypedText categoryClassMethod}
|
||||
// CHECK-CC1: {TypedText classMethod1:}{Placeholder (id)a}{Text withKeyword:}{Placeholder (int)b}
|
||||
@ -104,4 +117,18 @@ void test_qual_id(id<FooTestProtocol,FooTestProtocol2> ptr) {
|
||||
// RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s
|
||||
// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText protocolInstanceMethod:}{Placeholder (int)value}
|
||||
// CHECK-CC6: ObjCInstanceMethodDecl:{TypedText secondProtocolInstanceMethod}
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:95:8 %s | FileCheck -check-prefix=CHECK-CC7 %s
|
||||
// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method}
|
||||
// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (int)i}
|
||||
// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2}
|
||||
// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
|
||||
// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText Method:}{Placeholder (float)f}{Text SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
|
||||
// CHECK-CC7: ObjCInstanceMethodDecl:{TypedText OtherMethod:}{Placeholder (float)f}{Text Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2}
|
||||
// RUN: c-index-test -code-completion-at=%s:95:17 %s | FileCheck -check-prefix=CHECK-CC8 %s
|
||||
// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText }
|
||||
// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text Arg2:}{Placeholder (int)i2}
|
||||
// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText Arg1:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
|
||||
// CHECK-CC8: ObjCInstanceMethodDecl:{Informative Method:}{TypedText SomeArg:}{Placeholder (int)i1}{Text OtherArg:}{Placeholder (id)obj}
|
||||
// RUN: c-index-test -code-completion-at=%s:95:24 %s | FileCheck -check-prefix=CHECK-CC9 %s
|
||||
// CHECK-CC9: ObjCInstanceMethodDecl:{Informative Method:}{Informative Arg1:}{TypedText Arg2:}{Placeholder (int)i2}
|
||||
// CHECK-CC9: ObjCInstanceMethodDecl:{Informative Method:}{Informative Arg1:}{TypedText OtherArg:}{Placeholder (id)obj}
|
||||
|
40
test/Index/complete-properties.m
Normal file
40
test/Index/complete-properties.m
Normal file
@ -0,0 +1,40 @@
|
||||
/* Note: the RUN lines are near the end of the file, since line/column
|
||||
matter for this test. */
|
||||
|
||||
@interface I1
|
||||
{
|
||||
id StoredProp3;
|
||||
int RandomIVar;
|
||||
}
|
||||
@property int Prop0;
|
||||
@property int Prop1;
|
||||
@property float Prop2;
|
||||
@end
|
||||
|
||||
@interface I2 : I1
|
||||
@property id Prop3;
|
||||
@property id Prop4;
|
||||
@end
|
||||
|
||||
@implementation I2
|
||||
@synthesize Prop2, Prop1, Prop3 = StoredProp3;
|
||||
@dynamic Prop4;
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:20:13 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop0}
|
||||
// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop1}
|
||||
// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop2}
|
||||
// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop3}
|
||||
// CHECK-CC1: ObjCPropertyDecl:{TypedText Prop4}
|
||||
// RUN: c-index-test -code-completion-at=%s:20:20 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: ObjCPropertyDecl:{TypedText Prop0}
|
||||
// CHECK-CC2: ObjCPropertyDecl:{TypedText Prop1}
|
||||
// CHECK-CC2-NEXT: ObjCPropertyDecl:{TypedText Prop3}
|
||||
// CHECK-CC2: ObjCPropertyDecl:{TypedText Prop4}
|
||||
// RUN: c-index-test -code-completion-at=%s:20:35 %s | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
// CHECK-CC3: ObjCIvarDecl:{TypedText RandomIVar}
|
||||
// CHECK-CC3: ObjCIvarDecl:{TypedText StoredProp3}
|
||||
// RUN: c-index-test -code-completion-at=%s:21:10 %s | FileCheck -check-prefix=CHECK-CC4 %s
|
||||
// CHECK-CC4: ObjCPropertyDecl:{TypedText Prop0}
|
||||
// CHECK-CC4-NEXT: ObjCPropertyDecl:{TypedText Prop4}
|
23
test/Index/complete-property-flags.m
Normal file
23
test/Index/complete-property-flags.m
Normal file
@ -0,0 +1,23 @@
|
||||
// Note: the run lines follow their respective tests, since line/column
|
||||
// matter in this test.
|
||||
|
||||
@interface Foo {
|
||||
void *isa;
|
||||
}
|
||||
@property(copy) Foo *myprop;
|
||||
@property(retain, nonatomic) id xx;
|
||||
// RUN: c-index-test -code-completion-at=%s:7:11 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: {TypedText assign}
|
||||
// CHECK-CC1-NEXT: {TypedText copy}
|
||||
// CHECK-CC1-NEXT: {TypedText getter}{Text = }{Placeholder method}
|
||||
// CHECK-CC1-NEXT: {TypedText nonatomic}
|
||||
// CHECK-CC1-NEXT: {TypedText readonly}
|
||||
// CHECK-CC1-NEXT: {TypedText readwrite}
|
||||
// CHECK-CC1-NEXT: {TypedText retain}
|
||||
// CHECK-CC1-NEXT: {TypedText setter}{Text = }{Placeholder method}
|
||||
// RUN: c-index-test -code-completion-at=%s:8:18 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: {TypedText getter}{Text = }{Placeholder method}
|
||||
// CHECK-CC2-NEXT: {TypedText nonatomic}
|
||||
// CHECK-CC2-NEXT: {TypedText readwrite}
|
||||
// CHECK-CC2-NEXT: {TypedText setter}{Text = }{Placeholder method}
|
||||
@end
|
41
test/Index/complete-property-getset.m
Normal file
41
test/Index/complete-property-getset.m
Normal file
@ -0,0 +1,41 @@
|
||||
// Note: the run lines follow their respective tests, since line/column
|
||||
// matter in this test.
|
||||
|
||||
@interface Super { }
|
||||
- (int)getter1;
|
||||
+ (int)getter2_not_instance;
|
||||
- (int)getter2_not:(int)x;
|
||||
- (int)getter3;
|
||||
- (void)setter1:(int)x;
|
||||
+ (void)setter2_not_inst:(int)x;
|
||||
+ (void)setter2_many_args:(int)x second:(int)y;
|
||||
- (void)setter3:(int)y;
|
||||
@property (getter = getter1, setter = setter1:) int blah;
|
||||
@end
|
||||
|
||||
@interface Sub : Super { }
|
||||
- (int)getter4;
|
||||
- (void)setter4:(int)x;
|
||||
@property (getter = getter4, setter = setter1:) int blarg;
|
||||
@end
|
||||
|
||||
// RUN: c-index-test -code-completion-at=%s:13:21 %s | FileCheck -check-prefix=CHECK-CC1 %s
|
||||
// CHECK-CC1: ObjCInstanceMethodDecl:{TypedText getter1}
|
||||
// CHECK-CC1-NOT: getter2
|
||||
// CHECK-CC1: ObjCInstanceMethodDecl:{TypedText getter3}
|
||||
// RUN: c-index-test -code-completion-at=%s:13:39 %s | FileCheck -check-prefix=CHECK-CC2 %s
|
||||
// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText getter2_not:}
|
||||
// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText setter1:}
|
||||
// CHECK-CC2-NOT: setter2
|
||||
// CHECK-CC2: ObjCInstanceMethodDecl:{TypedText setter3:}
|
||||
// RUN: c-index-test -code-completion-at=%s:19:21 %s | FileCheck -check-prefix=CHECK-CC3 %s
|
||||
// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText getter1}
|
||||
// CHECK-CC3-NOT: getter2
|
||||
// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText getter3}
|
||||
// CHECK-CC3: ObjCInstanceMethodDecl:{TypedText getter4}
|
||||
// RUN: c-index-test -code-completion-at=%s:19:39 %s | FileCheck -check-prefix=CHECK-CC4 %s
|
||||
// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText getter2_not:}{Informative (int)x}
|
||||
// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText setter1:}{Informative (int)x}
|
||||
// CHECK-CC4-NOT: setter2
|
||||
// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText setter3:}{Informative (int)y}
|
||||
// CHECK-CC4: ObjCInstanceMethodDecl:{TypedText setter4:}{Informative (int)x}
|
15
test/Parser/objc-synthesized-recover.m
Normal file
15
test/Parser/objc-synthesized-recover.m
Normal file
@ -0,0 +1,15 @@
|
||||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
@interface I1
|
||||
{
|
||||
int value;
|
||||
int value2;
|
||||
}
|
||||
@property int value;
|
||||
@property int value2;
|
||||
@end
|
||||
|
||||
@implementation I1
|
||||
@synthesize value, - value2; // expected-error{{expected a property name}}
|
||||
@synthesize value2;
|
||||
@end
|
@ -155,8 +155,9 @@
|
||||
// ARM:#define __INT64_TYPE__ long long int
|
||||
// ARM:#define __INT8_TYPE__ char
|
||||
// ARM:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// ARM:#define __INTMAX_TYPE__ long long int
|
||||
// ARM:#define __INTMAX_WIDTH__ 64
|
||||
// ARM:#define __INTPTR_TYPE__ long int
|
||||
// ARM:#define __INTPTR_WIDTH__ 32
|
||||
// ARM:#define __INT_MAX__ 2147483647
|
||||
// ARM:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// ARM:#define __LDBL_DIG__ 15
|
||||
@ -181,7 +182,6 @@
|
||||
// ARM:#define __SHRT_MAX__ 32767
|
||||
// ARM:#define __SIZE_TYPE__ unsigned int
|
||||
// ARM:#define __THUMB_INTERWORK__ 1
|
||||
// ARM:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// ARM:#define __USER_LABEL_PREFIX__ _
|
||||
// ARM:#define __VFP_FP__ 1
|
||||
// ARM:#define __WCHAR_MAX__ 2147483647
|
||||
@ -233,8 +233,9 @@
|
||||
// BFIN:#define __INT64_TYPE__ long long int
|
||||
// BFIN:#define __INT8_TYPE__ char
|
||||
// BFIN:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// BFIN:#define __INTMAX_TYPE__ long long int
|
||||
// BFIN:#define __INTMAX_WIDTH__ 64
|
||||
// BFIN:#define __INTPTR_TYPE__ long int
|
||||
// BFIN:#define __INTPTR_WIDTH__ 32
|
||||
// BFIN:#define __INT_MAX__ 2147483647
|
||||
// BFIN:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// BFIN:#define __LDBL_DIG__ 15
|
||||
@ -257,7 +258,6 @@
|
||||
// BFIN:#define __SCHAR_MAX__ 127
|
||||
// BFIN:#define __SHRT_MAX__ 32767
|
||||
// BFIN:#define __SIZE_TYPE__ long unsigned int
|
||||
// BFIN:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// BFIN:#define __USER_LABEL_PREFIX__ _
|
||||
// BFIN:#define __WCHAR_MAX__ 2147483647
|
||||
// BFIN:#define __WCHAR_TYPE__ int
|
||||
@ -304,8 +304,9 @@
|
||||
// I386:#define __INT64_TYPE__ long long int
|
||||
// I386:#define __INT8_TYPE__ char
|
||||
// I386:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// I386:#define __INTMAX_TYPE__ long long int
|
||||
// I386:#define __INTMAX_WIDTH__ 64
|
||||
// I386:#define __INTPTR_TYPE__ int
|
||||
// I386:#define __INTPTR_WIDTH__ 32
|
||||
// I386:#define __INT_MAX__ 2147483647
|
||||
// I386:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
|
||||
// I386:#define __LDBL_DIG__ 18
|
||||
@ -331,7 +332,6 @@
|
||||
// I386:#define __SCHAR_MAX__ 127
|
||||
// I386:#define __SHRT_MAX__ 32767
|
||||
// I386:#define __SIZE_TYPE__ unsigned int
|
||||
// I386:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// I386:#define __USER_LABEL_PREFIX__ _
|
||||
// I386:#define __WCHAR_MAX__ 2147483647
|
||||
// I386:#define __WCHAR_TYPE__ int
|
||||
@ -381,8 +381,9 @@
|
||||
// MSP430:#define __INT32_TYPE__ long int
|
||||
// MSP430:#define __INT8_TYPE__ char
|
||||
// MSP430:#define __INTMAX_MAX__ 2147483647L
|
||||
// MSP430:#define __INTMAX_TYPE__ long int
|
||||
// MSP430:#define __INTMAX_WIDTH__ 32
|
||||
// MSP430:#define __INTPTR_TYPE__ short
|
||||
// MSP430:#define __INTPTR_WIDTH__ 16
|
||||
// MSP430:#define __INT_MAX__ 32767
|
||||
// MSP430:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// MSP430:#define __LDBL_DIG__ 15
|
||||
@ -406,7 +407,6 @@
|
||||
// MSP430:#define __SCHAR_MAX__ 127
|
||||
// MSP430:#define __SHRT_MAX__ 32767
|
||||
// MSP430:#define __SIZE_TYPE__ unsigned int
|
||||
// MSP430:#define __UINTMAX_TYPE__ long unsigned int
|
||||
// MSP430:#define __USER_LABEL_PREFIX__ _
|
||||
// MSP430:#define __WCHAR_MAX__ 32767
|
||||
// MSP430:#define __WCHAR_TYPE__ int
|
||||
@ -451,8 +451,9 @@
|
||||
// PIC16:#define __INT32_TYPE__ long int
|
||||
// PIC16:#define __INT8_TYPE__ char
|
||||
// PIC16:#define __INTMAX_MAX__ 2147483647L
|
||||
// PIC16:#define __INTMAX_TYPE__ long int
|
||||
// PIC16:#define __INTMAX_WIDTH__ 32
|
||||
// PIC16:#define __INTPTR_TYPE__ short
|
||||
// PIC16:#define __INTPTR_WIDTH__ 16
|
||||
// PIC16:#define __INT_MAX__ 32767
|
||||
// PIC16:#define __LDBL_DENORM_MIN__ 1.40129846e-45F
|
||||
// PIC16:#define __LDBL_DIG__ 6
|
||||
@ -475,7 +476,6 @@
|
||||
// PIC16:#define __SCHAR_MAX__ 127
|
||||
// PIC16:#define __SHRT_MAX__ 32767
|
||||
// PIC16:#define __SIZE_TYPE__ unsigned int
|
||||
// PIC16:#define __UINTMAX_TYPE__ long unsigned int
|
||||
// PIC16:#define __USER_LABEL_PREFIX__ _
|
||||
// PIC16:#define __WCHAR_MAX__ 32767
|
||||
// PIC16:#define __WCHAR_TYPE__ int
|
||||
@ -533,8 +533,9 @@
|
||||
// PPC64:#define __INT64_TYPE__ long int
|
||||
// PPC64:#define __INT8_TYPE__ char
|
||||
// PPC64:#define __INTMAX_MAX__ 9223372036854775807L
|
||||
// PPC64:#define __INTMAX_TYPE__ long int
|
||||
// PPC64:#define __INTMAX_WIDTH__ 64
|
||||
// PPC64:#define __INTPTR_TYPE__ long int
|
||||
// PPC64:#define __INTPTR_WIDTH__ 64
|
||||
// PPC64:#define __INT_MAX__ 2147483647
|
||||
// PPC64:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// PPC64:#define __LDBL_DIG__ 15
|
||||
@ -562,7 +563,6 @@
|
||||
// PPC64:#define __SCHAR_MAX__ 127
|
||||
// PPC64:#define __SHRT_MAX__ 32767
|
||||
// PPC64:#define __SIZE_TYPE__ long unsigned int
|
||||
// PPC64:#define __UINTMAX_TYPE__ long unsigned int
|
||||
// PPC64:#define __USER_LABEL_PREFIX__ _
|
||||
// PPC64:#define __WCHAR_MAX__ 2147483647
|
||||
// PPC64:#define __WCHAR_TYPE__ int
|
||||
@ -612,8 +612,9 @@
|
||||
// PPC:#define __INT64_TYPE__ long long int
|
||||
// PPC:#define __INT8_TYPE__ char
|
||||
// PPC:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// PPC:#define __INTMAX_TYPE__ long long int
|
||||
// PPC:#define __INTMAX_WIDTH__ 64
|
||||
// PPC:#define __INTPTR_TYPE__ long int
|
||||
// PPC:#define __INTPTR_WIDTH__ 32
|
||||
// PPC:#define __INT_MAX__ 2147483647
|
||||
// PPC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// PPC:#define __LDBL_DIG__ 15
|
||||
@ -640,7 +641,6 @@
|
||||
// PPC:#define __SCHAR_MAX__ 127
|
||||
// PPC:#define __SHRT_MAX__ 32767
|
||||
// PPC:#define __SIZE_TYPE__ long unsigned int
|
||||
// PPC:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// PPC:#define __USER_LABEL_PREFIX__ _
|
||||
// PPC:#define __WCHAR_MAX__ 2147483647
|
||||
// PPC:#define __WCHAR_TYPE__ int
|
||||
@ -686,8 +686,9 @@
|
||||
// S390X:#define __INT64_TYPE__ long int
|
||||
// S390X:#define __INT8_TYPE__ char
|
||||
// S390X:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// S390X:#define __INTMAX_TYPE__ long long int
|
||||
// S390X:#define __INTMAX_WIDTH__ 64
|
||||
// S390X:#define __INTPTR_TYPE__ long int
|
||||
// S390X:#define __INTPTR_WIDTH__ 64
|
||||
// S390X:#define __INT_MAX__ 2147483647
|
||||
// S390X:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// S390X:#define __LDBL_DIG__ 15
|
||||
@ -710,7 +711,6 @@
|
||||
// S390X:#define __SCHAR_MAX__ 127
|
||||
// S390X:#define __SHRT_MAX__ 32767
|
||||
// S390X:#define __SIZE_TYPE__ long unsigned int
|
||||
// S390X:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// S390X:#define __USER_LABEL_PREFIX__ _
|
||||
// S390X:#define __WCHAR_MAX__ 2147483647
|
||||
// S390X:#define __WCHAR_TYPE__ int
|
||||
@ -756,8 +756,9 @@
|
||||
// SPARC:#define __INT64_TYPE__ long long int
|
||||
// SPARC:#define __INT8_TYPE__ char
|
||||
// SPARC:#define __INTMAX_MAX__ 9223372036854775807LL
|
||||
// SPARC:#define __INTMAX_TYPE__ long long int
|
||||
// SPARC:#define __INTMAX_WIDTH__ 64
|
||||
// SPARC:#define __INTPTR_TYPE__ long int
|
||||
// SPARC:#define __INTPTR_WIDTH__ 32
|
||||
// SPARC:#define __INT_MAX__ 2147483647
|
||||
// SPARC:#define __LDBL_DENORM_MIN__ 4.9406564584124654e-324
|
||||
// SPARC:#define __LDBL_DIG__ 15
|
||||
@ -781,7 +782,6 @@
|
||||
// SPARC:#define __SCHAR_MAX__ 127
|
||||
// SPARC:#define __SHRT_MAX__ 32767
|
||||
// SPARC:#define __SIZE_TYPE__ long unsigned int
|
||||
// SPARC:#define __UINTMAX_TYPE__ long long unsigned int
|
||||
// SPARC:#define __USER_LABEL_PREFIX__ _
|
||||
// SPARC:#define __VERSION__ "4.2.1 Compatible Clang Compiler"
|
||||
// SPARC:#define __WCHAR_MAX__ 2147483647
|
||||
@ -828,8 +828,9 @@
|
||||
// TCE:#define __INT32_TYPE__ int
|
||||
// TCE:#define __INT8_TYPE__ char
|
||||
// TCE:#define __INTMAX_MAX__ 2147483647L
|
||||
// TCE:#define __INTMAX_TYPE__ long int
|
||||
// TCE:#define __INTMAX_WIDTH__ 32
|
||||
// TCE:#define __INTPTR_TYPE__ int
|
||||
// TCE:#define __INTPTR_WIDTH__ 32
|
||||
// TCE:#define __INT_MAX__ 2147483647
|
||||
// TCE:#define __LDBL_DENORM_MIN__ 1.40129846e-45F
|
||||
// TCE:#define __LDBL_DIG__ 6
|
||||
@ -854,7 +855,6 @@
|
||||
// TCE:#define __SIZE_TYPE__ unsigned int
|
||||
// TCE:#define __TCE_V1__ 1
|
||||
// TCE:#define __TCE__ 1
|
||||
// TCE:#define __UINTMAX_TYPE__ long unsigned int
|
||||
// TCE:#define __USER_LABEL_PREFIX__ _
|
||||
// TCE:#define __WCHAR_MAX__ 2147483647
|
||||
// TCE:#define __WCHAR_TYPE__ int
|
||||
@ -902,8 +902,9 @@
|
||||
// X86_64:#define __INT64_TYPE__ long int
|
||||
// X86_64:#define __INT8_TYPE__ char
|
||||
// X86_64:#define __INTMAX_MAX__ 9223372036854775807L
|
||||
// X86_64:#define __INTMAX_TYPE__ long int
|
||||
// X86_64:#define __INTMAX_WIDTH__ 64
|
||||
// X86_64:#define __INTPTR_TYPE__ long int
|
||||
// X86_64:#define __INTPTR_WIDTH__ 64
|
||||
// X86_64:#define __INT_MAX__ 2147483647
|
||||
// X86_64:#define __LDBL_DENORM_MIN__ 3.64519953188247460253e-4951L
|
||||
// X86_64:#define __LDBL_DIG__ 18
|
||||
@ -935,7 +936,6 @@
|
||||
// X86_64:#define __SSE2__ 1
|
||||
// X86_64:#define __SSE_MATH__ 1
|
||||
// X86_64:#define __SSE__ 1
|
||||
// X86_64:#define __UINTMAX_TYPE__ long unsigned int
|
||||
// X86_64:#define __USER_LABEL_PREFIX__ _
|
||||
// X86_64:#define __WCHAR_MAX__ 2147483647
|
||||
// X86_64:#define __WCHAR_TYPE__ int
|
||||
|
@ -28,11 +28,11 @@
|
||||
// ARM:typedef int8_t int_fast8_t;
|
||||
// ARM:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// ARM:typedef long int intptr_t;
|
||||
// ARM:typedef unsigned long int uintptr_t;
|
||||
// ARM:typedef int32_t intptr_t;
|
||||
// ARM:typedef uint32_t uintptr_t;
|
||||
//
|
||||
// ARM:typedef long long int intmax_t;
|
||||
// ARM:typedef long long unsigned int uintmax_t;
|
||||
// ARM:typedef int64_t intmax_t;
|
||||
// ARM:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// ARM:INT8_MAX_ 127
|
||||
// ARM:INT8_MIN_ (-127 -1)
|
||||
@ -83,7 +83,7 @@
|
||||
//
|
||||
// ARM:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// ARM:INTMAX_MAX_ 9223372036854775807LL
|
||||
// ARM:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
|
||||
// ARM:UINTMAX_MAX_ 18446744073709551615ULL
|
||||
//
|
||||
// ARM:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// ARM:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -136,11 +136,11 @@
|
||||
// BFIN:typedef int8_t int_fast8_t;
|
||||
// BFIN:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// BFIN:typedef long int intptr_t;
|
||||
// BFIN:typedef unsigned long int uintptr_t;
|
||||
// BFIN:typedef int32_t intptr_t;
|
||||
// BFIN:typedef uint32_t uintptr_t;
|
||||
//
|
||||
// BFIN:typedef long long int intmax_t;
|
||||
// BFIN:typedef long long unsigned int uintmax_t;
|
||||
// BFIN:typedef int64_t intmax_t;
|
||||
// BFIN:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// BFIN:INT8_MAX_ 127
|
||||
// BFIN:INT8_MIN_ (-127 -1)
|
||||
@ -191,7 +191,7 @@
|
||||
//
|
||||
// BFIN:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// BFIN:INTMAX_MAX_ 9223372036854775807LL
|
||||
// BFIN:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
|
||||
// BFIN:UINTMAX_MAX_ 18446744073709551615ULL
|
||||
//
|
||||
// BFIN:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// BFIN:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -244,11 +244,11 @@
|
||||
// I386:typedef int8_t int_fast8_t;
|
||||
// I386:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// I386:typedef int intptr_t;
|
||||
// I386:typedef unsigned int uintptr_t;
|
||||
// I386:typedef int32_t intptr_t;
|
||||
// I386:typedef uint32_t uintptr_t;
|
||||
//
|
||||
// I386:typedef long long int intmax_t;
|
||||
// I386:typedef long long unsigned int uintmax_t;
|
||||
// I386:typedef int64_t intmax_t;
|
||||
// I386:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// I386:INT8_MAX_ 127
|
||||
// I386:INT8_MIN_ (-127 -1)
|
||||
@ -299,7 +299,7 @@
|
||||
//
|
||||
// I386:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// I386:INTMAX_MAX_ 9223372036854775807LL
|
||||
// I386:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
|
||||
// I386:UINTMAX_MAX_ 18446744073709551615ULL
|
||||
//
|
||||
// I386:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// I386:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -344,11 +344,11 @@
|
||||
// MSP430:typedef int8_t int_fast8_t;
|
||||
// MSP430:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// MSP430:typedef short intptr_t;
|
||||
// MSP430:typedef unsigned short uintptr_t;
|
||||
// MSP430:typedef int16_t intptr_t;
|
||||
// MSP430:typedef uint16_t uintptr_t;
|
||||
//
|
||||
// MSP430:typedef long int intmax_t;
|
||||
// MSP430:typedef long unsigned int uintmax_t;
|
||||
// MSP430:typedef int32_t intmax_t;
|
||||
// MSP430:typedef uint32_t uintmax_t;
|
||||
//
|
||||
// MSP430:INT8_MAX_ 127
|
||||
// MSP430:INT8_MIN_ (-127 -1)
|
||||
@ -399,7 +399,7 @@
|
||||
//
|
||||
// MSP430:INTMAX_MIN_ (-2147483647L -1)
|
||||
// MSP430:INTMAX_MAX_ 2147483647L
|
||||
// MSP430:UINTMAX_MAX_ (2147483647L*2ULL +1ULL)
|
||||
// MSP430:UINTMAX_MAX_ 4294967295UL
|
||||
//
|
||||
// MSP430:SIG_ATOMIC_MIN_ (-2147483647L -1)
|
||||
// MSP430:SIG_ATOMIC_MAX_ 2147483647L
|
||||
@ -418,8 +418,8 @@
|
||||
// MSP430:INT64_C_(0) INT64_C(0)
|
||||
// MSP430:UINT64_C_(0) UINT64_C(0)
|
||||
//
|
||||
// MSP430:INTMAX_C_(0) 0LL
|
||||
// MSP430:UINTMAX_C_(0) 0ULL
|
||||
// MSP430:INTMAX_C_(0) 0L
|
||||
// MSP430:UINTMAX_C_(0) 0UL
|
||||
//
|
||||
// RUN: clang-cc -E -ffreestanding -triple=pic16-none-none %s | FileCheck -check-prefix PIC16 %s
|
||||
//
|
||||
@ -444,11 +444,11 @@
|
||||
// PIC16:typedef int8_t int_fast8_t;
|
||||
// PIC16:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// PIC16:typedef short intptr_t;
|
||||
// PIC16:typedef unsigned short uintptr_t;
|
||||
// PIC16:typedef int16_t intptr_t;
|
||||
// PIC16:typedef uint16_t uintptr_t;
|
||||
//
|
||||
// PIC16:typedef long int intmax_t;
|
||||
// PIC16:typedef long unsigned int uintmax_t;
|
||||
// PIC16:typedef int32_t intmax_t;
|
||||
// PIC16:typedef uint32_t uintmax_t;
|
||||
//
|
||||
// PIC16:INT8_MAX_ 127
|
||||
// PIC16:INT8_MIN_ (-127 -1)
|
||||
@ -499,7 +499,7 @@
|
||||
//
|
||||
// PIC16:INTMAX_MIN_ (-2147483647L -1)
|
||||
// PIC16:INTMAX_MAX_ 2147483647L
|
||||
// PIC16:UINTMAX_MAX_ (2147483647L*2ULL +1ULL)
|
||||
// PIC16:UINTMAX_MAX_ 4294967295UL
|
||||
//
|
||||
// PIC16:SIG_ATOMIC_MIN_ (-2147483647L -1)
|
||||
// PIC16:SIG_ATOMIC_MAX_ 2147483647L
|
||||
@ -518,8 +518,8 @@
|
||||
// PIC16:INT64_C_(0) INT64_C(0)
|
||||
// PIC16:UINT64_C_(0) UINT64_C(0)
|
||||
//
|
||||
// PIC16:INTMAX_C_(0) 0LL
|
||||
// PIC16:UINTMAX_C_(0) 0ULL
|
||||
// PIC16:INTMAX_C_(0) 0L
|
||||
// PIC16:UINTMAX_C_(0) 0UL
|
||||
//
|
||||
// RUN: clang-cc -E -ffreestanding -triple=powerpc64-none-none %s | FileCheck -check-prefix PPC64 %s
|
||||
//
|
||||
@ -551,11 +551,11 @@
|
||||
// PPC64:typedef int8_t int_fast8_t;
|
||||
// PPC64:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// PPC64:typedef long int intptr_t;
|
||||
// PPC64:typedef unsigned long int uintptr_t;
|
||||
// PPC64:typedef int64_t intptr_t;
|
||||
// PPC64:typedef uint64_t uintptr_t;
|
||||
//
|
||||
// PPC64:typedef long int intmax_t;
|
||||
// PPC64:typedef long unsigned int uintmax_t;
|
||||
// PPC64:typedef int64_t intmax_t;
|
||||
// PPC64:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// PPC64:INT8_MAX_ 127
|
||||
// PPC64:INT8_MIN_ (-127 -1)
|
||||
@ -606,7 +606,7 @@
|
||||
//
|
||||
// PPC64:INTMAX_MIN_ (-9223372036854775807L -1)
|
||||
// PPC64:INTMAX_MAX_ 9223372036854775807L
|
||||
// PPC64:UINTMAX_MAX_ (9223372036854775807L*2ULL +1ULL)
|
||||
// PPC64:UINTMAX_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// PPC64:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// PPC64:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -625,8 +625,8 @@
|
||||
// PPC64:INT64_C_(0) 0L
|
||||
// PPC64:UINT64_C_(0) 0UL
|
||||
//
|
||||
// PPC64:INTMAX_C_(0) 0LL
|
||||
// PPC64:UINTMAX_C_(0) 0ULL
|
||||
// PPC64:INTMAX_C_(0) 0L
|
||||
// PPC64:UINTMAX_C_(0) 0UL
|
||||
//
|
||||
// RUN: clang-cc -E -ffreestanding -triple=powerpc-none-none %s | FileCheck -check-prefix PPC %s
|
||||
//
|
||||
@ -659,11 +659,11 @@
|
||||
// PPC:typedef int8_t int_fast8_t;
|
||||
// PPC:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// PPC:typedef long int intptr_t;
|
||||
// PPC:typedef unsigned long int uintptr_t;
|
||||
// PPC:typedef int32_t intptr_t;
|
||||
// PPC:typedef uint32_t uintptr_t;
|
||||
//
|
||||
// PPC:typedef long long int intmax_t;
|
||||
// PPC:typedef long long unsigned int uintmax_t;
|
||||
// PPC:typedef int64_t intmax_t;
|
||||
// PPC:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// PPC:INT8_MAX_ 127
|
||||
// PPC:INT8_MIN_ (-127 -1)
|
||||
@ -714,7 +714,7 @@
|
||||
//
|
||||
// PPC:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// PPC:INTMAX_MAX_ 9223372036854775807LL
|
||||
// PPC:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
|
||||
// PPC:UINTMAX_MAX_ 18446744073709551615ULL
|
||||
//
|
||||
// PPC:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// PPC:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -766,11 +766,11 @@
|
||||
// S390X:typedef int8_t int_fast8_t;
|
||||
// S390X:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// S390X:typedef long int intptr_t;
|
||||
// S390X:typedef unsigned long int uintptr_t;
|
||||
// S390X:typedef int64_t intptr_t;
|
||||
// S390X:typedef uint64_t uintptr_t;
|
||||
//
|
||||
// S390X:typedef long long int intmax_t;
|
||||
// S390X:typedef long long unsigned int uintmax_t;
|
||||
// S390X:typedef int64_t intmax_t;
|
||||
// S390X:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// S390X:INT8_MAX_ 127
|
||||
// S390X:INT8_MIN_ (-127 -1)
|
||||
@ -819,9 +819,9 @@
|
||||
// S390X:PTRDIFF_MAX_ 9223372036854775807L
|
||||
// S390X:SIZE_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// S390X:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// S390X:INTMAX_MAX_ 9223372036854775807LL
|
||||
// S390X:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
|
||||
// S390X:INTMAX_MIN_ (-9223372036854775807L -1)
|
||||
// S390X:INTMAX_MAX_ 9223372036854775807L
|
||||
// S390X:UINTMAX_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// S390X:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// S390X:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -840,8 +840,8 @@
|
||||
// S390X:INT64_C_(0) 0L
|
||||
// S390X:UINT64_C_(0) 0UL
|
||||
//
|
||||
// S390X:INTMAX_C_(0) 0LL
|
||||
// S390X:UINTMAX_C_(0) 0ULL
|
||||
// S390X:INTMAX_C_(0) 0L
|
||||
// S390X:UINTMAX_C_(0) 0UL
|
||||
//
|
||||
// RUN: clang-cc -E -ffreestanding -triple=sparc-none-none %s | FileCheck -check-prefix SPARC %s
|
||||
//
|
||||
@ -873,11 +873,11 @@
|
||||
// SPARC:typedef int8_t int_fast8_t;
|
||||
// SPARC:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// SPARC:typedef long int intptr_t;
|
||||
// SPARC:typedef unsigned long int uintptr_t;
|
||||
// SPARC:typedef int32_t intptr_t;
|
||||
// SPARC:typedef uint32_t uintptr_t;
|
||||
//
|
||||
// SPARC:typedef long long int intmax_t;
|
||||
// SPARC:typedef long long unsigned int uintmax_t;
|
||||
// SPARC:typedef int64_t intmax_t;
|
||||
// SPARC:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// SPARC:INT8_MAX_ 127
|
||||
// SPARC:INT8_MIN_ (-127 -1)
|
||||
@ -928,7 +928,7 @@
|
||||
//
|
||||
// SPARC:INTMAX_MIN_ (-9223372036854775807LL -1)
|
||||
// SPARC:INTMAX_MAX_ 9223372036854775807LL
|
||||
// SPARC:UINTMAX_MAX_ (9223372036854775807LL*2ULL +1ULL)
|
||||
// SPARC:UINTMAX_MAX_ 18446744073709551615ULL
|
||||
//
|
||||
// SPARC:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// SPARC:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -973,11 +973,11 @@
|
||||
// TCE:typedef int8_t int_fast8_t;
|
||||
// TCE:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// TCE:typedef int intptr_t;
|
||||
// TCE:typedef unsigned int uintptr_t;
|
||||
// TCE:typedef int32_t intptr_t;
|
||||
// TCE:typedef uint32_t uintptr_t;
|
||||
//
|
||||
// TCE:typedef long int intmax_t;
|
||||
// TCE:typedef long unsigned int uintmax_t;
|
||||
// TCE:typedef int32_t intmax_t;
|
||||
// TCE:typedef uint32_t uintmax_t;
|
||||
//
|
||||
// TCE:INT8_MAX_ 127
|
||||
// TCE:INT8_MIN_ (-127 -1)
|
||||
@ -1026,9 +1026,9 @@
|
||||
// TCE:PTRDIFF_MAX_ 2147483647
|
||||
// TCE:SIZE_MAX_ 4294967295U
|
||||
//
|
||||
// TCE:INTMAX_MIN_ (-2147483647L -1)
|
||||
// TCE:INTMAX_MAX_ 2147483647L
|
||||
// TCE:UINTMAX_MAX_ (2147483647L*2ULL +1ULL)
|
||||
// TCE:INTMAX_MIN_ (-2147483647 -1)
|
||||
// TCE:INTMAX_MAX_ 2147483647
|
||||
// TCE:UINTMAX_MAX_ 4294967295U
|
||||
//
|
||||
// TCE:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// TCE:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -1047,8 +1047,8 @@
|
||||
// TCE:INT64_C_(0) INT64_C(0)
|
||||
// TCE:UINT64_C_(0) UINT64_C(0)
|
||||
//
|
||||
// TCE:INTMAX_C_(0) 0LL
|
||||
// TCE:UINTMAX_C_(0) 0ULL
|
||||
// TCE:INTMAX_C_(0) 0
|
||||
// TCE:UINTMAX_C_(0) 0U
|
||||
//
|
||||
// RUN: clang-cc -E -ffreestanding -triple=x86_64-none-none %s | FileCheck -check-prefix X86_64 %s
|
||||
//
|
||||
@ -1081,11 +1081,11 @@
|
||||
// X86_64:typedef int8_t int_fast8_t;
|
||||
// X86_64:typedef uint8_t uint_fast8_t;
|
||||
//
|
||||
// X86_64:typedef long int intptr_t;
|
||||
// X86_64:typedef unsigned long int uintptr_t;
|
||||
// X86_64:typedef int64_t intptr_t;
|
||||
// X86_64:typedef uint64_t uintptr_t;
|
||||
//
|
||||
// X86_64:typedef long int intmax_t;
|
||||
// X86_64:typedef long unsigned int uintmax_t;
|
||||
// X86_64:typedef int64_t intmax_t;
|
||||
// X86_64:typedef uint64_t uintmax_t;
|
||||
//
|
||||
// X86_64:INT8_MAX_ 127
|
||||
// X86_64:INT8_MIN_ (-127 -1)
|
||||
@ -1136,7 +1136,7 @@
|
||||
//
|
||||
// X86_64:INTMAX_MIN_ (-9223372036854775807L -1)
|
||||
// X86_64:INTMAX_MAX_ 9223372036854775807L
|
||||
// X86_64:UINTMAX_MAX_ (9223372036854775807L*2ULL +1ULL)
|
||||
// X86_64:UINTMAX_MAX_ 18446744073709551615UL
|
||||
//
|
||||
// X86_64:SIG_ATOMIC_MIN_ (-2147483647 -1)
|
||||
// X86_64:SIG_ATOMIC_MAX_ 2147483647
|
||||
@ -1155,8 +1155,8 @@
|
||||
// X86_64:INT64_C_(0) 0L
|
||||
// X86_64:UINT64_C_(0) 0UL
|
||||
//
|
||||
// X86_64:INTMAX_C_(0) 0LL
|
||||
// X86_64:UINTMAX_C_(0) 0ULL
|
||||
// X86_64:INTMAX_C_(0) 0L
|
||||
// X86_64:UINTMAX_C_(0) 0UL
|
||||
//
|
||||
|
||||
#include <stdint.h>
|
||||
|
@ -1,4 +1,4 @@
|
||||
// RUN: clang-cc -fsyntax-only -verify -fmath-errno=0 %s
|
||||
// RUN: clang-cc -fsyntax-only -verify -fno-math-errno %s
|
||||
|
||||
int foo(int X, int Y);
|
||||
|
||||
|
@ -138,3 +138,20 @@ namespace PR5222 {
|
||||
|
||||
C c;
|
||||
}
|
||||
|
||||
// PR5550 - instantiating template didn't track overridden methods
|
||||
namespace PR5550 {
|
||||
struct A {
|
||||
virtual void a() = 0;
|
||||
virtual void b() = 0;
|
||||
};
|
||||
template<typename T> struct B : public A {
|
||||
virtual void b();
|
||||
virtual void c() = 0;
|
||||
};
|
||||
struct C : public B<int> {
|
||||
virtual void a();
|
||||
virtual void c();
|
||||
};
|
||||
C x;
|
||||
}
|
||||
|
21
test/SemaCXX/cxx-member-pointer-op.cpp
Normal file
21
test/SemaCXX/cxx-member-pointer-op.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
// RUN: clang-cc -fsyntax-only -pedantic -verify %s
|
||||
|
||||
struct C {
|
||||
static int (C::* a);
|
||||
};
|
||||
|
||||
typedef void (C::*pmfc)();
|
||||
|
||||
void g(pmfc) {
|
||||
C *c;
|
||||
c->*pmfc(); // expected-error {{invalid use of pointer to member type after ->*}}
|
||||
C c1;
|
||||
c1.*pmfc(); // expected-error {{invalid use of pointer to member type after .*}}
|
||||
c->*(pmfc()); // expected-error {{invalid use of pointer to member type after ->*}}
|
||||
c1.*((pmfc())); // expected-error {{invalid use of pointer to member type after .*}}
|
||||
}
|
||||
|
||||
int a(C* x) {
|
||||
return x->*C::a;
|
||||
}
|
||||
|
@ -286,3 +286,41 @@ class RegAlloc {
|
||||
}
|
||||
int usepri[LastReg + 1];
|
||||
};
|
||||
|
||||
// PR5546: Don't generate incorrect and ambiguous overloads for multi-level
|
||||
// arrays.
|
||||
namespace pr5546
|
||||
{
|
||||
enum { X };
|
||||
extern const char *const sMoveCommands[][2][2];
|
||||
const char* a() { return sMoveCommands[X][0][0]; }
|
||||
const char* b() { return (*(sMoveCommands+X))[0][0]; }
|
||||
}
|
||||
|
||||
// PR5512 and its discussion
|
||||
namespace pr5512 {
|
||||
struct Y {
|
||||
operator short();
|
||||
operator float();
|
||||
};
|
||||
void g_test(Y y) {
|
||||
short s = 0;
|
||||
// DR507, this should be ambiguous, but we special-case assignment
|
||||
s = y;
|
||||
// Note: DR507, this is ambiguous as specified
|
||||
//s += y;
|
||||
}
|
||||
|
||||
struct S {};
|
||||
void operator +=(int&, S);
|
||||
void f(S s) {
|
||||
int i = 0;
|
||||
i += s;
|
||||
}
|
||||
|
||||
struct A {operator int();};
|
||||
int a;
|
||||
void b(A x) {
|
||||
a += x;
|
||||
}
|
||||
}
|
||||
|
@ -88,3 +88,9 @@ void memptrs()
|
||||
(void)reinterpret_cast<void (structure::*)()>(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)()' is not allowed}}
|
||||
(void)reinterpret_cast<int structure::*>(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}}
|
||||
}
|
||||
|
||||
// PR5545
|
||||
class A;
|
||||
class B;
|
||||
void (A::*a)();
|
||||
void (B::*b)() = reinterpret_cast<void (B::*)()>(a);
|
||||
|
@ -65,9 +65,9 @@ int&& should_not_warn(int&& i) { // But GCC 4.4 does
|
||||
// Test the return dance. This also tests IsReturnCopyElidable.
|
||||
struct MoveOnly {
|
||||
MoveOnly();
|
||||
MoveOnly(const MoveOnly&) = delete;
|
||||
MoveOnly(MoveOnly&&);
|
||||
MoveOnly(int&&);
|
||||
MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}}
|
||||
MoveOnly(MoveOnly&&); // expected-note {{candidate function}}
|
||||
MoveOnly(int&&); // expected-note {{candidate function}}
|
||||
};
|
||||
|
||||
MoveOnly returning() {
|
||||
@ -87,5 +87,5 @@ MoveOnly returningNonEligible() {
|
||||
else if (0) // Copy from reference can't be elided
|
||||
return r; // expected-error {{incompatible type returning}}
|
||||
else // Construction from different type can't be elided
|
||||
return i; // expected-error {{incompatible type returning}}
|
||||
return i; // expected-error {{no viable conversion from 'int' to 'struct MoveOnly'}}
|
||||
}
|
||||
|
@ -45,22 +45,18 @@ namespace A {
|
||||
using namespace E; // expected-error{{reference to 'E' is ambiguous}}
|
||||
}
|
||||
|
||||
struct K2 {}; // expected-note{{candidate found by name lookup is 'A::K2'}}
|
||||
struct K2 {}; // expected-note 2{{candidate found by name lookup is 'A::K2'}}
|
||||
}
|
||||
|
||||
struct K2 {}; // expected-note{{candidate found by name lookup is 'K2'}}
|
||||
struct K2 {}; // expected-note 2{{candidate found by name lookup is 'K2'}}
|
||||
|
||||
using namespace A;
|
||||
|
||||
void K1::foo() {} // okay
|
||||
|
||||
// FIXME: Do we want err_ovl_no_viable_function_in_init here?
|
||||
struct K2 k2; // expected-error{{reference to 'K2' is ambiguous}} \
|
||||
expected-error{{incomplete type}}
|
||||
|
||||
// FIXME: This case is incorrectly diagnosed!
|
||||
//K2 k3;
|
||||
struct K2 *k2; // expected-error{{reference to 'K2' is ambiguous}}
|
||||
|
||||
K2 *k3; // expected-error{{reference to 'K2' is ambiguous}}
|
||||
|
||||
class X { // expected-note{{candidate found by name lookup is 'X'}}
|
||||
// FIXME: produce a suitable error message for this
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user