Update clang to r89337.

This commit is contained in:
Roman Divacky 2009-11-19 09:00:00 +00:00
parent b3d5a323a5
commit f5bd02d290
110 changed files with 3690 additions and 2729 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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);
};
}

View File

@ -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

View File

@ -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);
};
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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">;

View File

@ -1 +1,2 @@
add_subdirectory(Basic)
add_subdirectory(Driver)

View File

@ -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

View 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

View 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)">;

View 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)

View 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, $@) $<

View 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; }

View 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

View 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

View File

@ -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;

View File

@ -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)

View File

@ -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();
}
}

View 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]>;

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,4 +1,4 @@
LEVEL = ../../../..
DIRS := Basic
DIRS := Basic Driver
include $(LEVEL)/Makefile.common

View File

@ -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) {
}
//@}
};

View File

@ -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();

View File

@ -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 {

View File

@ -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,

View File

@ -611,4 +611,3 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) {
DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder);
}
}

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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);
};
}

View File

@ -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))

View File

@ -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
View 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();
}

View File

@ -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)

View File

@ -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"

View File

@ -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;
}

View 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();
}

View File

@ -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";
}
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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"));

View File

@ -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 =

View File

@ -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];
}

View File

@ -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)

View File

@ -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);

View File

@ -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(), '/');

View File

@ -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 */

View File

@ -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

View File

@ -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))

View File

@ -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;
}
}
}

View File

@ -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())

View File

@ -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()) {

View File

@ -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

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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}}
}

View File

@ -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}}
}
}
}

View File

@ -0,0 +1,7 @@
// RUN: clang-cc -fsyntax-only -verify %s
// PR5548
struct A {~A();};
void a(const A* x) {
x->~A();
}

View File

@ -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

View File

@ -6,4 +6,4 @@
// CHECK: "-analyze"
// CHECK: "-target-feature" "+sse"
// CHECK: "--fmath-errno=0"
// CHECK: "-fno-math-errno"

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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]

View File

@ -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
{

View 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}

View 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}

View File

@ -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}

View 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}

View 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

View 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}

View 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

View File

@ -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

View File

@ -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>

View File

@ -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);

View File

@ -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;
}

View 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;
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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'}}
}

View File

@ -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